
* ImageService had a stream reset before writting out to array. Added logging statment for updating series metadata. Removed ConcurencyCheck due to bad update issue for CollectionTag. * Added a new screen which lets you quickly see all your bookmarks for a given user. * Built user bookmark page in user settings. Moved user settings to it's own lazy loaded module. Removed unneded debouncing from downloader and just used throttleTime instead. * Removed a not-yet implemented tab from series modal * Fixed a bug in clear bookmarks and adjusted icons within anchors to have proper styling
179 lines
5.7 KiB
TypeScript
179 lines
5.7 KiB
TypeScript
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
|
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
|
import { forkJoin, Subject } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { UtilityService } from 'src/app/shared/_services/utility.service';
|
|
import { TypeaheadSettings } from 'src/app/typeahead/typeahead-settings';
|
|
import { Chapter } from 'src/app/_models/chapter';
|
|
import { CollectionTag } from 'src/app/_models/collection-tag';
|
|
import { Series } from 'src/app/_models/series';
|
|
import { SeriesMetadata } from 'src/app/_models/series-metadata';
|
|
import { CollectionTagService } from 'src/app/_services/collection-tag.service';
|
|
import { ImageService } from 'src/app/_services/image.service';
|
|
import { LibraryService } from 'src/app/_services/library.service';
|
|
import { SeriesService } from 'src/app/_services/series.service';
|
|
import { UploadService } from 'src/app/_services/upload.service';
|
|
|
|
@Component({
|
|
selector: 'app-edit-series-modal',
|
|
templateUrl: './edit-series-modal.component.html',
|
|
styleUrls: ['./edit-series-modal.component.scss']
|
|
})
|
|
export class EditSeriesModalComponent implements OnInit, OnDestroy {
|
|
|
|
@Input() series!: Series;
|
|
seriesVolumes: any[] = [];
|
|
isLoadingVolumes = false;
|
|
|
|
isCollapsed = true;
|
|
volumeCollapsed: any = {};
|
|
tabs = ['General', 'Cover Image', 'Info'];
|
|
active = this.tabs[0];
|
|
editSeriesForm!: FormGroup;
|
|
libraryName: string | undefined = undefined;
|
|
private readonly onDestroy = new Subject<void>();
|
|
|
|
settings: TypeaheadSettings<CollectionTag> = new TypeaheadSettings();
|
|
tags: CollectionTag[] = [];
|
|
metadata!: SeriesMetadata;
|
|
imageUrls: Array<string> = [];
|
|
/**
|
|
* Selected Cover for uploading
|
|
*/
|
|
selectedCover: string = '';
|
|
|
|
constructor(public modal: NgbActiveModal,
|
|
private seriesService: SeriesService,
|
|
public utilityService: UtilityService,
|
|
private fb: FormBuilder,
|
|
public imageService: ImageService,
|
|
private libraryService: LibraryService,
|
|
private collectionService: CollectionTagService,
|
|
private uploadService: UploadService) { }
|
|
|
|
ngOnInit(): void {
|
|
this.imageUrls.push(this.imageService.getSeriesCoverImage(this.series.id));
|
|
|
|
this.libraryService.getLibraryNames().pipe(takeUntil(this.onDestroy)).subscribe(names => {
|
|
this.libraryName = names[this.series.libraryId];
|
|
});
|
|
|
|
this.setupTypeaheadSettings();
|
|
|
|
|
|
|
|
this.editSeriesForm = this.fb.group({
|
|
id: new FormControl(this.series.id, []),
|
|
summary: new FormControl(this.series.summary, []),
|
|
name: new FormControl(this.series.name, []),
|
|
localizedName: new FormControl(this.series.localizedName, []),
|
|
sortName: new FormControl(this.series.sortName, []),
|
|
rating: new FormControl(this.series.userRating, []),
|
|
|
|
genres: new FormControl('', []),
|
|
author: new FormControl('', []),
|
|
artist: new FormControl('', []),
|
|
|
|
coverImageIndex: new FormControl(0, []),
|
|
coverImageLocked: new FormControl(this.series.coverImageLocked, [])
|
|
});
|
|
|
|
this.seriesService.getMetadata(this.series.id).subscribe(metadata => {
|
|
if (metadata) {
|
|
this.metadata = metadata;
|
|
this.settings.savedData = metadata.tags;
|
|
}
|
|
});
|
|
|
|
this.isLoadingVolumes = true;
|
|
this.seriesService.getVolumes(this.series.id).subscribe(volumes => {
|
|
this.seriesVolumes = volumes;
|
|
this.isLoadingVolumes = false;
|
|
|
|
volumes.forEach(v => {
|
|
this.volumeCollapsed[v.name] = true;
|
|
});
|
|
this.seriesVolumes.forEach(vol => {
|
|
vol.volumeFiles = vol.chapters?.sort(this.utilityService.sortChapters).map((c: Chapter) => c.files.map((f: any) => {
|
|
f.chapter = c.number;
|
|
return f;
|
|
})).flat();
|
|
});
|
|
});
|
|
}
|
|
|
|
ngOnDestroy() {
|
|
this.onDestroy.next();
|
|
this.onDestroy.complete();
|
|
}
|
|
|
|
setupTypeaheadSettings() {
|
|
this.settings.minCharacters = 0;
|
|
this.settings.multiple = true;
|
|
this.settings.id = 'collections';
|
|
this.settings.unique = true;
|
|
this.settings.addIfNonExisting = true;
|
|
this.settings.fetchFn = (filter: string) => this.fetchCollectionTags(filter);
|
|
this.settings.addTransformFn = ((title: string) => {
|
|
return {id: 0, title: title, promoted: false, coverImage: '', summary: '', coverImageLocked: false };
|
|
});
|
|
this.settings.compareFn = (options: CollectionTag[], filter: string) => {
|
|
const f = filter.toLowerCase();
|
|
return options.filter(m => m.title.toLowerCase() === f);
|
|
}
|
|
}
|
|
|
|
close() {
|
|
this.modal.close({success: false, series: undefined});
|
|
}
|
|
|
|
fetchCollectionTags(filter: string = '') {
|
|
return this.collectionService.search(filter);
|
|
}
|
|
|
|
formatChapterNumber(chapter: Chapter) {
|
|
if (chapter.number === '0') {
|
|
return '1';
|
|
}
|
|
return chapter.number;
|
|
}
|
|
|
|
save() {
|
|
const model = this.editSeriesForm.value;
|
|
const selectedIndex = this.editSeriesForm.get('coverImageIndex')?.value || 0;
|
|
const apis = [
|
|
this.seriesService.updateSeries(model),
|
|
this.seriesService.updateMetadata(this.metadata, this.tags)
|
|
];
|
|
|
|
if (selectedIndex > 0) {
|
|
apis.push(this.uploadService.updateSeriesCoverImage(model.id, this.selectedCover));
|
|
}
|
|
|
|
forkJoin(apis).subscribe(results => {
|
|
this.modal.close({success: true, series: model, coverImageUpdate: selectedIndex > 0});
|
|
});
|
|
}
|
|
|
|
updateCollections(tags: CollectionTag[]) {
|
|
this.tags = tags;
|
|
}
|
|
|
|
updateSelectedIndex(index: number) {
|
|
this.editSeriesForm.patchValue({
|
|
coverImageIndex: index
|
|
});
|
|
}
|
|
|
|
updateSelectedImage(url: string) {
|
|
this.selectedCover = url;
|
|
}
|
|
|
|
handleReset() {
|
|
this.editSeriesForm.patchValue({
|
|
coverImageLocked: false
|
|
});
|
|
}
|
|
|
|
}
|