UX Overhaul Part 1 (#3047)
Co-authored-by: Joseph Milazzo <joseph.v.milazzo@gmail.com>
This commit is contained in:
parent
5934d516f3
commit
ff79710ac6
324 changed files with 11589 additions and 4598 deletions
|
|
@ -0,0 +1,290 @@
|
|||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
|
||||
import {translate, TranslocoDirective} from "@ngneat/transloco";
|
||||
import {
|
||||
bookLayoutModes,
|
||||
bookWritingStyles,
|
||||
layoutModes,
|
||||
pageLayoutModes,
|
||||
pageSplitOptions,
|
||||
pdfScrollModes,
|
||||
pdfSpreadModes,
|
||||
pdfThemes,
|
||||
Preferences,
|
||||
readingDirections,
|
||||
readingModes,
|
||||
scalingOptions
|
||||
} from "../../_models/preferences/preferences";
|
||||
import {AccountService} from "../../_services/account.service";
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
import {BookService} from "../../book-reader/_services/book.service";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
import {Router} from "@angular/router";
|
||||
import {LocalizationService} from "../../_services/localization.service";
|
||||
import {bookColorThemes} from "../../book-reader/_components/reader-settings/reader-settings.component";
|
||||
import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
|
||||
import {User} from "../../_models/user";
|
||||
import {Language} from "../../_models/metadata/language";
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {debounceTime, distinctUntilChanged, filter, forkJoin, switchMap, tap} from "rxjs";
|
||||
import {take} from "rxjs/operators";
|
||||
import {BookPageLayoutMode} from "../../_models/readers/book-page-layout-mode";
|
||||
import {PdfTheme} from "../../_models/preferences/pdf-theme";
|
||||
import {PdfScrollMode} from "../../_models/preferences/pdf-scroll-mode";
|
||||
import {PdfSpreadMode} from "../../_models/preferences/pdf-spread-mode";
|
||||
import {
|
||||
NgbAccordionBody, NgbAccordionButton,
|
||||
NgbAccordionCollapse,
|
||||
NgbAccordionDirective, NgbAccordionHeader,
|
||||
NgbAccordionItem, NgbTooltip
|
||||
} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {NgForOf, NgIf, NgStyle, NgTemplateOutlet, TitleCasePipe} from "@angular/common";
|
||||
import {ColorPickerModule} from "ngx-color-picker";
|
||||
import {SettingTitleComponent} from "../../settings/_components/setting-title/setting-title.component";
|
||||
import {SettingItemComponent} from "../../settings/_components/setting-item/setting-item.component";
|
||||
import {PageLayoutModePipe} from "../../_pipes/page-layout-mode.pipe";
|
||||
import {SettingSwitchComponent} from "../../settings/_components/setting-switch/setting-switch.component";
|
||||
import {ReadingDirectionPipe} from "../../_pipes/reading-direction.pipe";
|
||||
import {ScalingOptionPipe} from "../../_pipes/scaling-option.pipe";
|
||||
import {PageSplitOptionPipe} from "../../_pipes/page-split-option.pipe";
|
||||
import {ReaderModePipe} from "../../_pipes/reading-mode.pipe";
|
||||
import {LayoutModePipe} from "../../_pipes/layout-mode.pipe";
|
||||
import {WritingStylePipe} from "../../_pipes/writing-style.pipe";
|
||||
import {BookPageLayoutModePipe} from "../../_pipes/book-page-layout-mode.pipe";
|
||||
import {PdfSpreadTypePipe} from "../../pdf-reader/_pipe/pdf-spread-mode.pipe";
|
||||
import {PdfSpreadModePipe} from "../../_pipes/pdf-spread-mode.pipe";
|
||||
import {PdfThemePipe} from "../../_pipes/pdf-theme.pipe";
|
||||
import {PdfScrollModeTypePipe} from "../../pdf-reader/_pipe/pdf-scroll-mode.pipe";
|
||||
import {PdfScrollModePipe} from "../../_pipes/pdf-scroll-mode.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-manga-user-preferences',
|
||||
standalone: true,
|
||||
imports: [
|
||||
TranslocoDirective,
|
||||
NgbAccordionDirective,
|
||||
ReactiveFormsModule,
|
||||
NgbAccordionItem,
|
||||
NgbAccordionCollapse,
|
||||
NgbAccordionBody,
|
||||
NgbAccordionHeader,
|
||||
NgbAccordionButton,
|
||||
NgIf,
|
||||
NgbTooltip,
|
||||
NgTemplateOutlet,
|
||||
TitleCasePipe,
|
||||
ColorPickerModule,
|
||||
NgForOf,
|
||||
SettingTitleComponent,
|
||||
SettingItemComponent,
|
||||
PageLayoutModePipe,
|
||||
SettingSwitchComponent,
|
||||
ReadingDirectionPipe,
|
||||
ScalingOptionPipe,
|
||||
PageSplitOptionPipe,
|
||||
ReaderModePipe,
|
||||
LayoutModePipe,
|
||||
NgStyle,
|
||||
WritingStylePipe,
|
||||
BookPageLayoutModePipe,
|
||||
PdfSpreadTypePipe,
|
||||
PdfSpreadTypePipe,
|
||||
PdfSpreadModePipe,
|
||||
PdfThemePipe,
|
||||
PdfScrollModeTypePipe,
|
||||
PdfScrollModePipe
|
||||
],
|
||||
templateUrl: './manage-user-preferences.component.html',
|
||||
styleUrl: './manage-user-preferences.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ManageUserPreferencesComponent implements OnInit {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly accountService = inject(AccountService);
|
||||
private readonly bookService = inject(BookService);
|
||||
private readonly titleService = inject(Title);
|
||||
private readonly router = inject(Router);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly localizationService = inject(LocalizationService);
|
||||
|
||||
protected readonly readingDirections = readingDirections;
|
||||
protected readonly scalingOptions = scalingOptions;
|
||||
protected readonly pageSplitOptions = pageSplitOptions;
|
||||
protected readonly readerModes = readingModes;
|
||||
protected readonly layoutModes = layoutModes;
|
||||
protected readonly bookWritingStyles = bookWritingStyles;
|
||||
protected readonly pageLayoutModes = pageLayoutModes;
|
||||
protected readonly bookLayoutModes = bookLayoutModes;
|
||||
protected readonly pdfSpreadModes = pdfSpreadModes;
|
||||
protected readonly pdfThemes = pdfThemes;
|
||||
protected readonly pdfScrollModes = pdfScrollModes;
|
||||
|
||||
bookColorThemesTranslated = bookColorThemes.map(o => {
|
||||
const d = {...o};
|
||||
d.name = translate('theme.' + d.translationKey);
|
||||
return d;
|
||||
});
|
||||
|
||||
|
||||
fontFamilies: Array<string> = [];
|
||||
locales: Array<Language> = [{title: 'English', isoCode: 'en'}];
|
||||
|
||||
settingsForm: FormGroup = new FormGroup({});
|
||||
user: User | undefined = undefined;
|
||||
|
||||
get Locale() {
|
||||
return this.locales.filter(l => l.isoCode === this.settingsForm.get('locale')!.value)[0].title;
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
this.fontFamilies = this.bookService.getFontFamilies().map(f => f.title);
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
this.localizationService.getLocales().subscribe(res => {
|
||||
this.locales = res;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.titleService.setTitle('Kavita - User Preferences');
|
||||
|
||||
forkJoin({
|
||||
user: this.accountService.currentUser$.pipe(take(1)),
|
||||
pref: this.accountService.getPreferences()
|
||||
}).subscribe(results => {
|
||||
if (results.user === undefined) {
|
||||
this.router.navigateByUrl('/login');
|
||||
return;
|
||||
}
|
||||
|
||||
this.user = results.user;
|
||||
this.user.preferences = results.pref;
|
||||
|
||||
if (this.fontFamilies.indexOf(this.user.preferences.bookReaderFontFamily) < 0) {
|
||||
this.user.preferences.bookReaderFontFamily = 'default';
|
||||
}
|
||||
|
||||
this.settingsForm.addControl('readingDirection', new FormControl(this.user.preferences.readingDirection, []));
|
||||
this.settingsForm.addControl('scalingOption', new FormControl(this.user.preferences.scalingOption, []));
|
||||
this.settingsForm.addControl('pageSplitOption', new FormControl(this.user.preferences.pageSplitOption, []));
|
||||
this.settingsForm.addControl('autoCloseMenu', new FormControl(this.user.preferences.autoCloseMenu, []));
|
||||
this.settingsForm.addControl('showScreenHints', new FormControl(this.user.preferences.showScreenHints, []));
|
||||
this.settingsForm.addControl('readerMode', new FormControl(this.user.preferences.readerMode, []));
|
||||
this.settingsForm.addControl('layoutMode', new FormControl(this.user.preferences.layoutMode, []));
|
||||
this.settingsForm.addControl('emulateBook', new FormControl(this.user.preferences.emulateBook, []));
|
||||
this.settingsForm.addControl('swipeToPaginate', new FormControl(this.user.preferences.swipeToPaginate, []));
|
||||
this.settingsForm.addControl('backgroundColor', new FormControl(this.user.preferences.backgroundColor, []));
|
||||
|
||||
this.settingsForm.addControl('bookReaderFontFamily', new FormControl(this.user.preferences.bookReaderFontFamily, []));
|
||||
this.settingsForm.addControl('bookReaderFontSize', new FormControl(this.user.preferences.bookReaderFontSize, []));
|
||||
this.settingsForm.addControl('bookReaderLineSpacing', new FormControl(this.user.preferences.bookReaderLineSpacing, []));
|
||||
this.settingsForm.addControl('bookReaderMargin', new FormControl(this.user.preferences.bookReaderMargin, []));
|
||||
this.settingsForm.addControl('bookReaderReadingDirection', new FormControl(this.user.preferences.bookReaderReadingDirection, []));
|
||||
this.settingsForm.addControl('bookReaderWritingStyle', new FormControl(this.user.preferences.bookReaderWritingStyle, []))
|
||||
this.settingsForm.addControl('bookReaderTapToPaginate', new FormControl(this.user.preferences.bookReaderTapToPaginate, []));
|
||||
this.settingsForm.addControl('bookReaderLayoutMode', new FormControl(this.user.preferences.bookReaderLayoutMode || BookPageLayoutMode.Default, []));
|
||||
this.settingsForm.addControl('bookReaderThemeName', new FormControl(this.user?.preferences.bookReaderThemeName || bookColorThemes[0].name, []));
|
||||
this.settingsForm.addControl('bookReaderImmersiveMode', new FormControl(this.user?.preferences.bookReaderImmersiveMode, []));
|
||||
|
||||
this.settingsForm.addControl('pdfTheme', new FormControl(this.user?.preferences.pdfTheme || PdfTheme.Dark, []));
|
||||
this.settingsForm.addControl('pdfScrollMode', new FormControl(this.user?.preferences.pdfScrollMode || PdfScrollMode.Vertical, []));
|
||||
this.settingsForm.addControl('pdfSpreadMode', new FormControl(this.user?.preferences.pdfSpreadMode || PdfSpreadMode.None, []));
|
||||
|
||||
this.settingsForm.addControl('theme', new FormControl(this.user.preferences.theme, []));
|
||||
this.settingsForm.addControl('globalPageLayoutMode', new FormControl(this.user.preferences.globalPageLayoutMode, []));
|
||||
this.settingsForm.addControl('blurUnreadSummaries', new FormControl(this.user.preferences.blurUnreadSummaries, []));
|
||||
this.settingsForm.addControl('promptForDownloadSize', new FormControl(this.user.preferences.promptForDownloadSize, []));
|
||||
this.settingsForm.addControl('noTransitions', new FormControl(this.user.preferences.noTransitions, []));
|
||||
this.settingsForm.addControl('collapseSeriesRelationships', new FormControl(this.user.preferences.collapseSeriesRelationships, []));
|
||||
this.settingsForm.addControl('shareReviews', new FormControl(this.user.preferences.shareReviews, []));
|
||||
this.settingsForm.addControl('locale', new FormControl(this.user.preferences.locale || 'en', []));
|
||||
|
||||
if (this.locales.length === 1) {
|
||||
this.settingsForm.get('locale')?.disable();
|
||||
}
|
||||
|
||||
this.settingsForm.valueChanges.pipe(
|
||||
distinctUntilChanged(),
|
||||
debounceTime(100),
|
||||
filter(_ => this.settingsForm.valid),
|
||||
takeUntilDestroyed(this.destroyRef),
|
||||
switchMap(_ => {
|
||||
const data = this.packSettings();
|
||||
return this.accountService.updatePreferences(data);
|
||||
}),
|
||||
tap(updatedPrefs => {
|
||||
if (this.user) {
|
||||
this.user.preferences = updatedPrefs;
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
})
|
||||
).subscribe();
|
||||
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
|
||||
this.settingsForm.get('bookReaderImmersiveMode')?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(mode => {
|
||||
if (mode) {
|
||||
this.settingsForm.get('bookReaderTapToPaginate')?.setValue(true);
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
});
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
packSettings(): Preferences {
|
||||
const modelSettings = this.settingsForm.value;
|
||||
return {
|
||||
readingDirection: parseInt(modelSettings.readingDirection, 10),
|
||||
scalingOption: parseInt(modelSettings.scalingOption, 10),
|
||||
pageSplitOption: parseInt(modelSettings.pageSplitOption, 10),
|
||||
autoCloseMenu: modelSettings.autoCloseMenu,
|
||||
readerMode: parseInt(modelSettings.readerMode, 10),
|
||||
layoutMode: parseInt(modelSettings.layoutMode, 10),
|
||||
showScreenHints: modelSettings.showScreenHints,
|
||||
backgroundColor: modelSettings.backgroundColor || '#000',
|
||||
bookReaderFontFamily: modelSettings.bookReaderFontFamily,
|
||||
bookReaderLineSpacing: modelSettings.bookReaderLineSpacing,
|
||||
bookReaderFontSize: modelSettings.bookReaderFontSize,
|
||||
bookReaderMargin: modelSettings.bookReaderMargin,
|
||||
bookReaderTapToPaginate: modelSettings.bookReaderTapToPaginate,
|
||||
bookReaderReadingDirection: parseInt(modelSettings.bookReaderReadingDirection, 10),
|
||||
bookReaderWritingStyle: parseInt(modelSettings.bookReaderWritingStyle, 10),
|
||||
bookReaderLayoutMode: parseInt(modelSettings.bookReaderLayoutMode, 10),
|
||||
bookReaderThemeName: modelSettings.bookReaderThemeName,
|
||||
theme: modelSettings.theme,
|
||||
bookReaderImmersiveMode: modelSettings.bookReaderImmersiveMode,
|
||||
globalPageLayoutMode: parseInt(modelSettings.globalPageLayoutMode, 10),
|
||||
blurUnreadSummaries: modelSettings.blurUnreadSummaries,
|
||||
promptForDownloadSize: modelSettings.promptForDownloadSize,
|
||||
noTransitions: modelSettings.noTransitions,
|
||||
emulateBook: modelSettings.emulateBook,
|
||||
swipeToPaginate: modelSettings.swipeToPaginate,
|
||||
collapseSeriesRelationships: modelSettings.collapseSeriesRelationships,
|
||||
shareReviews: modelSettings.shareReviews,
|
||||
locale: modelSettings.locale,
|
||||
pdfTheme: parseInt(modelSettings.pdfTheme, 10),
|
||||
pdfScrollMode: parseInt(modelSettings.pdfScrollMode, 10),
|
||||
pdfSpreadMode: parseInt(modelSettings.pdfSpreadMode, 10),
|
||||
};
|
||||
}
|
||||
|
||||
handleBackgroundColorChange(color: string) {
|
||||
this.settingsForm.markAsDirty();
|
||||
this.settingsForm.markAsTouched();
|
||||
if (this.user?.preferences) {
|
||||
this.user.preferences.backgroundColor = color;
|
||||
}
|
||||
|
||||
this.settingsForm.get('backgroundColor')?.setValue(color);
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
translatePrefOptions(o: {text: string, value: any}) {
|
||||
const d = {...o};
|
||||
d.text = translate('preferences.' + o.text);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue