
* Adding some code for Robbie * See more on series detail metadata area is now at the bottom on the section * Cleaned up subtitle headings to use a single class for offset with actionables * Added some markup for the new design, waiting for Robbie to finish it off * styling age-rating badge * Started hooking up basic analyze file service and hooks in the UI. Basic code to implement the count is implemented and in benchmarks. * Hooked up analyze ui to backend * Refactored Series Detail metadata area to use a new icon/title design * Cleaned up the new design * Pushing for robbie to do css * Massive performance improvement to scan series where we only need to scan folders reported that have series in them, rather than the whole library. * Removed theme page as we no longer need it. Added WordCount to DTOs so the UI can show them. Added new pipe to format numbers in compact mode. * Hooked up actual reading time based on user's words per hour * Refactor some magic numbers to consts * Hooked in progress reporting for series word count * Hooked up analyze files * Re-implemented time to read on comics * Removed the word Last Read * Show proper language name instead of iso tag on series detail page. Added some error handling on word count code. * Reworked error handling * Fixed some security vulnerabilities in npm. * Handle a case where there are no text nodes and instead of returning an empty list, htmlagilitypack returns null. * Tweaked the styles a bit on the icon-and-title * Code cleanup Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
102 lines
No EOL
3.6 KiB
TypeScript
102 lines
No EOL
3.6 KiB
TypeScript
import { Component, OnDestroy, OnInit } from '@angular/core';
|
|
import { NavigationEnd, Router } from '@angular/router';
|
|
import { Observable, Subject } from 'rxjs';
|
|
import { filter, map, take, takeUntil, takeWhile } from 'rxjs/operators';
|
|
import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';
|
|
import { Breakpoint, UtilityService } from '../../shared/_services/utility.service';
|
|
import { Library } from '../../_models/library';
|
|
import { User } from '../../_models/user';
|
|
import { AccountService } from '../../_services/account.service';
|
|
import { Action, ActionFactoryService, ActionItem } from '../../_services/action-factory.service';
|
|
import { ActionService } from '../../_services/action.service';
|
|
import { LibraryService } from '../../_services/library.service';
|
|
import { NavService } from '../../_services/nav.service';
|
|
|
|
@Component({
|
|
selector: 'app-side-nav',
|
|
templateUrl: './side-nav.component.html',
|
|
styleUrls: ['./side-nav.component.scss']
|
|
})
|
|
export class SideNavComponent implements OnInit, OnDestroy {
|
|
|
|
user: User | undefined;
|
|
libraries: Library[] = [];
|
|
isAdmin = false;
|
|
actions: ActionItem<Library>[] = [];
|
|
|
|
filterQuery: string = '';
|
|
filterLibrary = (library: Library) => {
|
|
return library.name.toLowerCase().indexOf((this.filterQuery || '').toLowerCase()) >= 0;
|
|
}
|
|
|
|
private onDestroy: Subject<void> = new Subject();
|
|
|
|
|
|
constructor(public accountService: AccountService, private libraryService: LibraryService,
|
|
public utilityService: UtilityService, private messageHub: MessageHubService,
|
|
private actionFactoryService: ActionFactoryService, private actionService: ActionService, public navService: NavService, private router: Router) { }
|
|
|
|
ngOnInit(): void {
|
|
this.accountService.currentUser$.pipe(take(1)).subscribe(user => {
|
|
this.user = user;
|
|
|
|
if (this.user) {
|
|
this.isAdmin = this.accountService.hasAdminRole(this.user);
|
|
}
|
|
this.libraryService.getLibrariesForMember().pipe(take(1)).subscribe((libraries: Library[]) => {
|
|
this.libraries = libraries;
|
|
});
|
|
this.actions = this.actionFactoryService.getLibraryActions(this.handleAction.bind(this));
|
|
});
|
|
|
|
this.messageHub.messages$.pipe(takeUntil(this.onDestroy), filter(event => event.event === EVENTS.LibraryModified)).subscribe(event => {
|
|
this.libraryService.getLibrariesForMember().pipe(take(1)).subscribe((libraries: Library[]) => {
|
|
this.libraries = libraries;
|
|
});
|
|
});
|
|
|
|
this.router.events
|
|
.pipe(filter(event => event instanceof NavigationEnd),
|
|
takeUntil(this.onDestroy),
|
|
map(evt => evt as NavigationEnd))
|
|
.subscribe((evt: NavigationEnd) => {
|
|
if (this.utilityService.getActiveBreakpoint() < Breakpoint.Tablet) {
|
|
// collapse side nav
|
|
this.navService.sideNavCollapsed$.pipe(take(1)).subscribe(collapsed => {
|
|
if (!collapsed) {
|
|
this.navService.toggleSideNav();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.onDestroy.next();
|
|
this.onDestroy.complete();
|
|
}
|
|
|
|
handleAction(action: Action, library: Library) {
|
|
switch (action) {
|
|
case(Action.ScanLibrary):
|
|
this.actionService.scanLibrary(library);
|
|
break;
|
|
case(Action.RefreshMetadata):
|
|
this.actionService.refreshMetadata(library);
|
|
break;
|
|
case (Action.AnalyzeFiles):
|
|
this.actionService.analyzeFiles(library);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
performAction(action: ActionItem<Library>, library: Library) {
|
|
if (typeof action.callback === 'function') {
|
|
action.callback(action.action, library);
|
|
}
|
|
}
|
|
|
|
} |