A boatload of Bugs (#3704)

Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com>
This commit is contained in:
Joe Milazzo 2025-04-05 15:52:01 -05:00 committed by GitHub
parent ea9b7ad0d1
commit 37734554ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
102 changed files with 2051 additions and 1115 deletions

View file

@ -1,70 +1,71 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef,
inject,
OnInit
} from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
import {NavigationEnd, Router} from '@angular/router';
import {NgbTooltip} from '@ng-bootstrap/ng-bootstrap';
import {distinctUntilChanged, filter, map, take, tap} from 'rxjs/operators';
import { ImageService } from 'src/app/_services/image.service';
import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';
import { Breakpoint, UtilityService } from '../../../shared/_services/utility.service';
import { Library, LibraryType } from '../../../_models/library/library';
import { AccountService } from '../../../_services/account.service';
import { Action, ActionFactoryService, ActionItem } from '../../../_services/action-factory.service';
import { ActionService } from '../../../_services/action.service';
import { NavService } from '../../../_services/nav.service';
import {ImageService} from 'src/app/_services/image.service';
import {EVENTS, MessageHubService} from 'src/app/_services/message-hub.service';
import {Breakpoint, UtilityService} from '../../../shared/_services/utility.service';
import {Library, LibraryType} from '../../../_models/library/library';
import {AccountService} from '../../../_services/account.service';
import {Action, ActionFactoryService, ActionItem} from '../../../_services/action-factory.service';
import {ActionService} from '../../../_services/action.service';
import {NavService} from '../../../_services/nav.service';
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {BehaviorSubject, merge, Observable, of, ReplaySubject, startWith, switchMap} from "rxjs";
import {AsyncPipe, NgClass} from "@angular/common";
import {SideNavItemComponent} from "../side-nav-item/side-nav-item.component";
import {FilterPipe} from "../../../_pipes/filter.pipe";
import {FormsModule} from "@angular/forms";
import {TranslocoDirective} from "@jsverse/transloco";
import {translate, TranslocoDirective} from "@jsverse/transloco";
import {CardActionablesComponent} from "../../../_single-module/card-actionables/card-actionables.component";
import {SideNavStream} from "../../../_models/sidenav/sidenav-stream";
import {SideNavStreamType} from "../../../_models/sidenav/sidenav-stream-type.enum";
import {WikiLink} from "../../../_models/wiki";
import {SettingsTabId} from "../../preference-nav/preference-nav.component";
import {LicenseService} from "../../../_services/license.service";
import {CdkDrag, CdkDragDrop, CdkDropList} from "@angular/cdk/drag-drop";
import {ToastrService} from "ngx-toastr";
@Component({
selector: 'app-side-nav',
imports: [SideNavItemComponent, CardActionablesComponent, FilterPipe, FormsModule, TranslocoDirective, NgbTooltip, NgClass, AsyncPipe],
templateUrl: './side-nav.component.html',
styleUrls: ['./side-nav.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
selector: 'app-side-nav',
imports: [SideNavItemComponent, CardActionablesComponent, FilterPipe, FormsModule, TranslocoDirective, NgbTooltip,
NgClass, AsyncPipe, CdkDropList, CdkDrag],
templateUrl: './side-nav.component.html',
styleUrls: ['./side-nav.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SideNavComponent implements OnInit {
private readonly router = inject(Router);
protected readonly utilityService = inject(UtilityService);
private readonly messageHub = inject(MessageHubService);
private readonly actionService = inject(ActionService);
public readonly navService = inject(NavService);
private readonly cdRef = inject(ChangeDetectorRef);
private readonly imageService = inject(ImageService);
public readonly accountService = inject(AccountService);
public readonly licenseService = inject(LicenseService);
private readonly destroyRef = inject(DestroyRef);
private readonly actionFactoryService = inject(ActionFactoryService);
protected readonly WikiLink = WikiLink;
protected readonly ItemLimit = 10;
protected readonly SideNavStreamType = SideNavStreamType;
protected readonly SettingsTabId = SettingsTabId;
protected readonly Breakpoint = Breakpoint;
private readonly router = inject(Router);
protected readonly utilityService = inject(UtilityService);
private readonly messageHub = inject(MessageHubService);
private readonly actionService = inject(ActionService);
protected readonly navService = inject(NavService);
private readonly cdRef = inject(ChangeDetectorRef);
private readonly imageService = inject(ImageService);
protected readonly accountService = inject(AccountService);
protected readonly licenseService = inject(LicenseService);
private readonly destroyRef = inject(DestroyRef);
private readonly actionFactoryService = inject(ActionFactoryService);
private readonly toastr = inject(ToastrService)
cachedData: SideNavStream[] | null = null;
actions: ActionItem<Library>[] = this.actionFactoryService.getLibraryActions(this.handleAction.bind(this));
homeActions: ActionItem<void>[] = this.actionFactoryService.getSideNavHomeActions(this.handleHomeAction.bind(this));
filterQuery: string = '';
filterLibrary = (stream: SideNavStream) => {
return stream.name.toLowerCase().indexOf((this.filterQuery || '').toLowerCase()) >= 0;
}
showAll: boolean = false;
editMode: boolean = false;
totalSize = 0;
isReadOnly = false;
@ -88,7 +89,7 @@ export class SideNavComponent implements OnInit {
})
);
navStreams$ = merge(
navStreams$: Observable<SideNavStream[]> = merge(
this.showAll$.pipe(
startWith(false),
distinctUntilChanged(),
@ -178,12 +179,28 @@ export class SideNavComponent implements OnInit {
}
}
async handleHomeAction(action: ActionItem<void>) {
switch (action.action) {
case Action.Edit:
this.showMore(true);
break;
default:
break;
}
}
performAction(action: ActionItem<Library>, library: Library) {
if (typeof action.callback === 'function') {
action.callback(action, library);
}
}
performHomeAction(action: ActionItem<void>) {
if (typeof action.callback === 'function') {
action.callback(action)
}
}
getLibraryTypeIcon(format: LibraryType) {
switch (format) {
case LibraryType.Book:
@ -208,15 +225,31 @@ export class SideNavComponent implements OnInit {
this.navService.toggleSideNav();
}
showMore() {
showMore(edit: boolean = false) {
this.showAllSubject.next(true);
this.editMode = edit;
this.cdRef.markForCheck();
}
showLess() {
this.filterQuery = '';
this.cdRef.markForCheck();
this.showAllSubject.next(false);
this.editMode = false;
this.cdRef.markForCheck();
}
protected readonly Breakpoint = Breakpoint;
async reorderDrop($event: CdkDragDrop<any, any, SideNavStream>) {
const stream = $event.item.data;
// Offset the home, back, and customize button
this.navService.updateSideNavStreamPosition(stream.name, stream.id, stream.order, $event.currentIndex - 3).subscribe({
next: () => {
this.showAllSubject.next(this.showAll);
this.cdRef.markForCheck();
},
error: err => {
console.error(err);
this.toastr.error(translate('errors.generic'));
}
});
}
}