Feature/enhancements and more (#1166)

* Moved libraryType into chapter info

* Fixed a bug where you could not reset cover on a series

* Patched in relevant changes from another polish branch

* Refactored invite user setup to shift the checking for accessibility to the backend and always show the link. This will help with users who have some unique setups in docker.

* Refactored invite user to always print the url to setup a new account.

* Single page renderer uses canvasImage rather than re-requesting and relying on cache

* Fixed a rendering issue where fit to split on single on a cover wouldn't force width scaling just for that image

* Fixed a rendering bug with split image functionality

* Added title to copy button

* Fixed a bug in GetContinuePoint when a chapter is added to an already read volume and a new chapter is added loose leaf. The loose leaf would be prioritized over the volume chapter.

Refactored 2 methods from controller into service and unit tested.

* Fixed a bug on opening a volume in series detail that had a chapter added to it after the volume (0 chapter) was read would cause a loose leaf chapter to be opened.

* Added mark as read/actionables on Files in volume detail modal. Fixed a bug where we were showing the wrong page count in a volume detail modal.

* Removed OnDeck page and replaced it with a pre-filtered All-Series. Hooked up the ability to pass read state to the filter via query params. Fixed some spacing on filter post bootstrap update.

* Fixed up some poor documentation on FilterDto.

* Some string equals enhancements to reduce extra allocations

* Fixed an issue when trying to download via a url, to remove query parameters to get the format

* Made an optimization to Normalize method to reduce memory pressure by 100MB over the course of a scan (16k files)

* Adjusted the styles on dashboard for first time setup and used a routerlink rather than href to avoid a fresh load.

* Use framgment on router link

* Hooked in the ability to search by release year (along with series optionally) and series will be returned back.

* Fixed a bug in the filter format code where it was sending the wrong type

* Only show clear all on typeahead when there are at least one selected item

* Cleaned up the styles of the styles of the typeahead

* Removed some dead code

* Implemented the ability to filter against a series name.

* Fixed filter top offset

* Ensure that when we add or remove libraries, the side nav of users gets updated.

* Tweaked the width on the mobile side nav

* Close side nav on clicking overlay on mobile viewport

* Don't show a pointer if the carousel section title is not actually selectable

* Removed the User profile on the side nav so home is always first. Tweaked styles to match

* Fixed up some poor documentation on FilterDto.

* Fixed a bug where Latest read date wasn't being set due to an early short circuit.

* When sending the chapter file, format the title of the FeedEntry more like Series Detail.

* Removed dead code
This commit is contained in:
Joseph Milazzo 2022-03-21 09:26:49 -05:00 committed by GitHub
parent 67d8d3d808
commit 4a93b5c715
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 663 additions and 451 deletions

View file

@ -27,7 +27,7 @@
<span>
<span *ngIf="chapterMetadata && chapterMetadata.releaseDate !== null">Release Date: {{chapterMetadata.releaseDate | date: 'shortDate' || '-'}}</span>
</span>
<span class="text-accent">{{chapter.pages}} pages</span>
<span class="text-accent">{{data.pages}} pages</span>
</div>
<div class="row g-0">
<div class="col-auto">
@ -106,24 +106,26 @@
<h4 *ngIf="!utilityService.isChapter(data)">{{utilityService.formatChapterName(libraryType) + 's'}}</h4>
<ul class="list-unstyled">
<li class="d-flex my-4" *ngFor="let chapter of chapters">
<a (click)="readChapter(chapter)" href="javascript:void(0);" title="Read {{libraryType !== LibraryType.Comic ? 'Chapter ' : 'Issue #'}} {{chapter.number}}">
<a (click)="readChapter(chapter)" href="javascript:void(0);" title="Read {{utilityService.formatChapterName(libraryType, true, false)}} {{formatChapterNumber(chapter)}}">
<app-image class="me-2" width="74px" [imageUrl]="chapter.coverImage"></app-image>
</a>
<div class="flex-grow-1">
<h5 class="mt-0 mb-1">
<span *ngIf="chapter.number !== '0'; else specialHeader">
<span >
<span>
<app-card-actionables (actionHandler)="performAction($event, chapter)" [actions]="chapterActions"
[labelBy]="utilityService.formatChapterName(libraryType, true, true) + formatChapterNumber(chapter)"></app-card-actionables>
{{utilityService.formatChapterName(libraryType, true, false) }} {{formatChapterNumber(chapter)}}
<ng-container *ngIf="chapter.number !== '0'; else specialHeader">
{{utilityService.formatChapterName(libraryType, true, false) }} {{formatChapterNumber(chapter)}}
</ng-container>
</span>
<span class="badge bg-primary rounded-pill">
<span class="badge bg-primary rounded-pill ms-1">
<span *ngIf="chapter.pagesRead > 0 && chapter.pagesRead < chapter.pages">{{chapter.pagesRead}} / {{chapter.pages}}</span>
<span *ngIf="chapter.pagesRead === 0">UNREAD</span>
<span *ngIf="chapter.pagesRead === chapter.pages">READ</span>
</span>
</span>
<ng-template #specialHeader>File(s)</ng-template>
<ng-template #specialHeader>Files</ng-template>
</h5>
<ul class="list-group">
<li *ngFor="let file of chapter.files" class="list-group-item no-hover">

View file

@ -89,7 +89,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
private seriesService: SeriesService,
public utilityService: UtilityService,
private fb: FormBuilder,
public imageService: ImageService,
public imageService: ImageService,
private libraryService: LibraryService,
private collectionService: CollectionTagService,
private uploadService: UploadService,
@ -98,8 +98,6 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.imageUrls.push(this.imageService.getSeriesCoverImage(this.series.id));
this.initSeries = Object.assign({}, this.series);
this.libraryService.getLibraryNames().pipe(takeUntil(this.onDestroy)).subscribe(names => {
this.libraryName = names[this.series.libraryId];
});
@ -107,7 +105,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
this.editSeriesForm = this.fb.group({
id: new FormControl(this.series.id, []),
summary: new FormControl('', []),
summary: new FormControl('', []),
name: new FormControl(this.series.name, []),
localizedName: new FormControl(this.series.localizedName, []),
sortName: new FormControl(this.series.sortName, []),
@ -125,7 +123,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
this.metadataService.getAllAgeRatings().subscribe(ratings => {
this.ageRatings = ratings;
});
this.metadataService.getAllPublicationStatus().subscribe(statuses => {
this.publicationStatuses = statuses;
});
@ -166,7 +164,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
this.metadata.ageRating = parseInt(val + '', 10);
this.metadata.ageRatingLocked = true;
});
this.editSeriesForm.get('publicationStatus')?.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(val => {
this.metadata.publicationStatus = parseInt(val + '', 10);
this.metadata.publicationStatusLocked = true;
@ -245,8 +243,8 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
return options.filter(m => this.utilityService.filter(m.title, filter));
}
this.tagsSettings.fetchFn = (filter: string) => this.metadataService.getAllTags()
.pipe(map(items => this.tagsSettings.compareFn(items, filter)));
.pipe(map(items => this.tagsSettings.compareFn(items, filter)));
this.tagsSettings.addTransformFn = ((title: string) => {
return {id: 0, title: title };
});
@ -269,7 +267,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
this.genreSettings.addIfNonExisting = true;
this.genreSettings.fetchFn = (filter: string) => {
return this.metadataService.getAllGenres()
.pipe(map(items => this.genreSettings.compareFn(items, filter)));
.pipe(map(items => this.genreSettings.compareFn(items, filter)));
};
this.genreSettings.compareFn = (options: Genre[], filter: string) => {
return options.filter(m => this.utilityService.filter(m.title, filter));
@ -336,7 +334,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
return forkJoin([
this.updateFromPreset('writer', this.metadata.writers, PersonRole.Writer),
this.updateFromPreset('character', this.metadata.characters, PersonRole.Character),
this.updateFromPreset('character', this.metadata.characters, PersonRole.Character),
this.updateFromPreset('colorist', this.metadata.colorists, PersonRole.Colorist),
this.updateFromPreset('cover-artist', this.metadata.coverArtists, PersonRole.CoverArtist),
this.updateFromPreset('editor', this.metadata.editors, PersonRole.Editor),
@ -350,7 +348,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
}));
}
fetchPeople(role: PersonRole, filter: string) {
fetchPeople(role: PersonRole, filter: string) {
return this.metadataService.getAllPeople().pipe(map(people => {
return people.filter(p => p.role == role && this.utilityService.filter(p.name, filter));
}));
@ -415,7 +413,7 @@ export class EditSeriesModalComponent implements OnInit, OnDestroy {
apis.push(this.seriesService.updateSeries(model));
}
if (selectedIndex > 0 && this.selectedCover !== '') {
apis.push(this.uploadService.updateSeriesCoverImage(model.id, this.selectedCover));
}