From 370b412d4b06bc005594f333fe55ca1ac157a133 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 11:38:14 -0500 Subject: [PATCH 01/26] Fixed a bug where library type wasn't wired up and all chapter cards used the chapter word instead of issue --- UI/Web/src/app/cards/chapter-card/chapter-card.component.html | 2 +- UI/Web/src/app/cards/entity-title/entity-title.component.html | 1 + openapi.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/UI/Web/src/app/cards/chapter-card/chapter-card.component.html b/UI/Web/src/app/cards/chapter-card/chapter-card.component.html index c39ce980c..9268309e3 100644 --- a/UI/Web/src/app/cards/chapter-card/chapter-card.component.html +++ b/UI/Web/src/app/cards/chapter-card/chapter-card.component.html @@ -80,7 +80,7 @@ @if (chapter.isSpecial) { {{chapter.title || chapter.range}} } @else { - + } diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.html b/UI/Web/src/app/cards/entity-title/entity-title.component.html index e0fc0471d..1477e0858 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.html +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.html @@ -18,6 +18,7 @@ @case (LibraryType.ComicVine) { @if (titleName !== '' && prioritizeTitleName) { @if (isChapter && includeChapter) { + Hi {{t('issue-num') + ' ' + number + ' - ' }} } diff --git a/openapi.json b/openapi.json index e0fceb7b4..124ac091b 100644 --- a/openapi.json +++ b/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Kavita", - "description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.2.12", + "description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.3.1", "license": { "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" From a42ab404d4375e4bc3c0e5b847b43788034cd0ba Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 14:39:46 -0500 Subject: [PATCH 02/26] Instead of showing Special on chapter cards that belong to a volume with no chapter marker, show a dash instead. --- .../app/cards/entity-title/entity-title.component.html | 9 ++++++--- .../app/cards/entity-title/entity-title.component.ts | 10 +++++++++- UI/Web/src/assets/langs/en.json | 5 +++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.html b/UI/Web/src/app/cards/entity-title/entity-title.component.html index 1477e0858..28bb9924f 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.html +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.html @@ -18,7 +18,6 @@ @case (LibraryType.ComicVine) { @if (titleName !== '' && prioritizeTitleName) { @if (isChapter && includeChapter) { - Hi {{t('issue-num') + ' ' + number + ' - ' }} } @@ -49,16 +48,20 @@ @case (LibraryType.Book) { @if (titleName !== '' && prioritizeTitleName) { {{titleName}} + } @else if (number === LooseLeafOrSpecial) { + {{null | defaultValue}} } @else { - {{volumeTitle}} + {{t('book-num', {num: volumeTitle})}} } } @case (LibraryType.LightNovel) { @if (titleName !== '' && prioritizeTitleName) { {{titleName}} + } @else if (number === LooseLeafOrSpecial) { + {{null | defaultValue}} } @else { - {{volumeTitle}} + {{t('book-num', {num: (isChapter ? number : volumeTitle)})}} } } diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.ts b/UI/Web/src/app/cards/entity-title/entity-title.component.ts index 1b62fe08d..af91b1d17 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.ts +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.ts @@ -4,6 +4,7 @@ import { Chapter, LooseLeafOrDefaultNumber } from 'src/app/_models/chapter'; import { LibraryType } from 'src/app/_models/library/library'; import { Volume } from 'src/app/_models/volume'; import {TranslocoModule} from "@jsverse/transloco"; +import {DefaultValuePipe} from "../../_pipes/default-value.pipe"; /** * This is primarily used for list item @@ -12,7 +13,8 @@ import {TranslocoModule} from "@jsverse/transloco"; selector: 'app-entity-title', standalone: true, imports: [ - TranslocoModule + TranslocoModule, + DefaultValuePipe ], templateUrl: './entity-title.component.html', styleUrls: ['./entity-title.component.scss'], @@ -59,6 +61,12 @@ export class EntityTitleComponent implements OnInit { this.volumeTitle = c.volumeTitle || ''; this.titleName = c.titleName || ''; this.number = c.range; + + // If loose leaf/special + if (this.number === this.LooseLeafOrSpecial) { + + } + } else { const v = this.utilityService.asVolume(this.entity); this.volumeTitle = v.name || ''; diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json index 0019f436d..a633ad632 100644 --- a/UI/Web/src/assets/langs/en.json +++ b/UI/Web/src/assets/langs/en.json @@ -1109,8 +1109,9 @@ "entity-title": { "special": "Special", - "issue-num": "Issue #", - "chapter": "Chapter" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { From 54180c735556884253a8fadd1c8bdcaf65aa3b30 Mon Sep 17 00:00:00 2001 From: Robbie Davis Date: Wed, 18 Sep 2024 16:00:13 -0400 Subject: [PATCH 03/26] more fixes for card title --- UI/Web/src/_card-item-common.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/Web/src/_card-item-common.scss b/UI/Web/src/_card-item-common.scss index 29924c495..c2ee2378d 100644 --- a/UI/Web/src/_card-item-common.scss +++ b/UI/Web/src/_card-item-common.scss @@ -168,7 +168,7 @@ $image-width: 160px; font-size: 0.8rem; margin: 0; text-align: center; - max-width: 110px; + max-width: 94px; a { overflow: hidden; From 5ec93f00d4eb7667d9eca24302ae44e55bab728c Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 15:08:09 -0500 Subject: [PATCH 04/26] Fixed a locale string for edit icon --- UI/Web/src/assets/langs/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json index a633ad632..98053913c 100644 --- a/UI/Web/src/assets/langs/en.json +++ b/UI/Web/src/assets/langs/en.json @@ -788,7 +788,7 @@ "incognito": "Incognito", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "Edit Series Information", + "edit-series-alt": "Edit Information", "reviews-tab": "{{tabs.reviews-tab}}", "storyline-tab": "{{tabs.storyline-tab}}", "books-tab": "{{tabs.books-tab}}", From bb087cbb658fc24e95f2e7253257e2d22498a61a Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 15:22:45 -0500 Subject: [PATCH 05/26] Fixed Cover Artists still showing instead of Artist in search --- UI/Web/src/assets/langs/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json index 98053913c..0e93c6db4 100644 --- a/UI/Web/src/assets/langs/en.json +++ b/UI/Web/src/assets/langs/en.json @@ -527,7 +527,7 @@ "artist": "Artist", "character": "Character", "colorist": "Colorist", - "cover-artist": "Cover Artist", + "cover-artist": "Artist", "editor": "Editor", "inker": "Inker", "letterer": "Letterer", From fe39ee40e718bead91456d3335d276d0a1e068a1 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 15:32:25 -0500 Subject: [PATCH 06/26] Changed how the warning about having real settings before test work --- .../manage-email-settings.component.html | 6 +----- .../manage-email-settings.component.ts | 6 +++--- UI/Web/src/assets/langs/en.json | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.html b/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.html index 33482af62..bef6f63c2 100644 --- a/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.html +++ b/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.html @@ -2,11 +2,7 @@

{{t('description')}}

-

{{t('setting-description')}}

- - @if (settingsForm.dirty) { -
{{t('test-warning')}}
- } +

{{t('setting-description')}} {{t('test-warning')}}

@if (settingsForm.get('hostName'); as formControl) { diff --git a/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.ts b/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.ts index f3b872c36..5c05e2d5e 100644 --- a/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.ts +++ b/UI/Web/src/app/admin/manage-email-settings/manage-email-settings.component.ts @@ -1,14 +1,14 @@ import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core'; import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; import {ToastrService} from 'ngx-toastr'; -import {debounceTime, distinctUntilChanged, filter, switchMap, take, tap} from 'rxjs'; +import {debounceTime, distinctUntilChanged, filter, map, switchMap, take, tap} from 'rxjs'; import {SettingsService} from '../settings.service'; import {ServerSettings} from '../_models/server-settings'; import { NgbAlert, NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; -import {NgIf, NgTemplateOutlet, TitleCasePipe} from '@angular/common'; +import {AsyncPipe, NgIf, NgTemplateOutlet, TitleCasePipe} from '@angular/common'; import {translate, TranslocoModule} from "@jsverse/transloco"; import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe"; import {ManageMediaIssuesComponent} from "../manage-media-issues/manage-media-issues.component"; @@ -25,7 +25,7 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgIf, ReactiveFormsModule, NgbTooltip, NgTemplateOutlet, TranslocoModule, SafeHtmlPipe, - ManageMediaIssuesComponent, TitleCasePipe, NgbAlert, SettingItemComponent, SettingSwitchComponent, DefaultValuePipe, BytesPipe] + ManageMediaIssuesComponent, TitleCasePipe, NgbAlert, SettingItemComponent, SettingSwitchComponent, DefaultValuePipe, BytesPipe, AsyncPipe] }) export class ManageEmailSettingsComponent implements OnInit { diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json index 0e93c6db4..20b4f43ed 100644 --- a/UI/Web/src/assets/langs/en.json +++ b/UI/Web/src/assets/langs/en.json @@ -1133,7 +1133,7 @@ "manage-email-settings": { "description": "In order to use some functions of Kavita like Send To Device an email provider must be setup. Other features like Forgot Password require admin intervention without Email setup.", "setting-description": "You must fill out both Host Name and SMTP settings to use email-based functionality within Kavita.", - "test-warning": "You must save before using Test button.", + "test-warning": "You must have valid settings before hitting Test.", "send-to-warning": "If you want Send to Device to work you must setup your email settings", "email-url-label": "Email Service URL", "email-url-tooltip": "Use fully qualified URL of the email service. Do not include ending slash.", From 33af893b0aa5f299d957b254a63880dc09e32d63 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 15:37:26 -0500 Subject: [PATCH 07/26] More localization cache busting techniques --- UI/Web/src/app/app.component.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/UI/Web/src/app/app.component.ts b/UI/Web/src/app/app.component.ts index aac0cb8e1..c74c9f0fc 100644 --- a/UI/Web/src/app/app.component.ts +++ b/UI/Web/src/app/app.component.ts @@ -22,7 +22,7 @@ import {ServerService} from "./_services/server.service"; import {OutOfDateModalComponent} from "./announcements/_components/out-of-date-modal/out-of-date-modal.component"; import {PreferenceNavComponent} from "./sidenav/preference-nav/preference-nav.component"; import {Breakpoint, UtilityService} from "./shared/_services/utility.service"; -import {translate} from "@jsverse/transloco"; +import {TranslocoService} from "@jsverse/transloco"; @Component({ selector: 'app-root', @@ -47,6 +47,7 @@ export class AppComponent implements OnInit { private readonly router = inject(Router); private readonly themeService = inject(ThemeService); private readonly document = inject(DOCUMENT); + private readonly translocoService = inject(TranslocoService); protected readonly Breakpoint = Breakpoint; @@ -126,6 +127,9 @@ export class AppComponent implements OnInit { // Bust locale cache localStorage.removeItem('@transloco/translations/timestamp'); localStorage.removeItem('@transloco/translations'); + (this.translocoService as any).cache.delete(localStorage.getItem('kavita-locale') || 'en'); + (this.translocoService as any).cache.clear(); + localStorage.setItem('kavita--version', version); location.reload(); } localStorage.setItem('kavita--version', version); From 7d91b2ff8b6e533b7fb66150d31debc7a0564c7d Mon Sep 17 00:00:00 2001 From: Robbie Davis Date: Wed, 18 Sep 2024 16:37:48 -0400 Subject: [PATCH 08/26] adding custom card action padding --- UI/Web/src/_card-item-common.scss | 2 +- .../card-actionables/card-actionables.component.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/UI/Web/src/_card-item-common.scss b/UI/Web/src/_card-item-common.scss index c2ee2378d..f187660fd 100644 --- a/UI/Web/src/_card-item-common.scss +++ b/UI/Web/src/_card-item-common.scss @@ -168,7 +168,7 @@ $image-width: 160px; font-size: 0.8rem; margin: 0; text-align: center; - max-width: 94px; + max-width: 98px; a { overflow: hidden; diff --git a/UI/Web/src/app/_single-module/card-actionables/card-actionables.component.scss b/UI/Web/src/app/_single-module/card-actionables/card-actionables.component.scss index 34ff10fe6..6f1d105e0 100644 --- a/UI/Web/src/app/_single-module/card-actionables/card-actionables.component.scss +++ b/UI/Web/src/app/_single-module/card-actionables/card-actionables.component.scss @@ -27,6 +27,10 @@ padding: var(--bs-dropdown-item-padding-y) 0; } +.btn { + padding: 5px; +} + // Robbie added this but it broke most of the uses //.dropdown-toggle { // padding-top: 0; From 08c0c191def8403b315e03cfbe04c46ffd32f9d8 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 16:09:52 -0500 Subject: [PATCH 09/26] Fixed a bug where manage tasks screen wasn't saving --- .../manage-tasks-settings.component.ts | 107 ++++++++---------- 1 file changed, 45 insertions(+), 62 deletions(-) diff --git a/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts b/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts index 02603d510..d66a2d2c2 100644 --- a/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts +++ b/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts @@ -107,7 +107,7 @@ export class ManageTasksSettingsComponent implements OnInit { }, { name: 'sync-themes-task', - description: 'sync-themes-desc', + description: 'sync-themes-task-desc', api: this.serverService.syncThemes(), successMessage: 'sync-themes-success' }, @@ -143,81 +143,35 @@ export class ManageTasksSettingsComponent implements OnInit { this.logLevels = result.levels; this.serverSettings = result.settings; + // Create base controls for taskScan, taskBackup, taskCleanup this.settingsForm.addControl('taskScan', new FormControl(this.serverSettings.taskScan, [Validators.required])); this.settingsForm.addControl('taskBackup', new FormControl(this.serverSettings.taskBackup, [Validators.required])); this.settingsForm.addControl('taskCleanup', new FormControl(this.serverSettings.taskCleanup, [Validators.required])); - if (!this.taskFrequencies.includes(this.serverSettings.taskScan)) { - this.settingsForm.get('taskScan')?.setValue(this.customOption); - this.settingsForm.addControl('taskScanCustom', new FormControl(this.serverSettings.taskScan, [Validators.required])); - } else { - this.settingsForm.addControl('taskScanCustom', new FormControl('', [Validators.required])); - } - - if (!this.taskFrequencies.includes(this.serverSettings.taskBackup)) { - this.settingsForm.get('taskBackup')?.setValue(this.customOption); - this.settingsForm.addControl('taskBackupCustom', new FormControl(this.serverSettings.taskBackup, [Validators.required])); - } else { - this.settingsForm.addControl('taskBackupCustom', new FormControl('', [Validators.required])); - } - if (!this.taskFrequenciesForCleanup.includes(this.serverSettings.taskCleanup)) { - this.settingsForm.get('taskCleanup')?.setValue(this.customOption); - this.settingsForm.addControl('taskCleanupCustom', new FormControl(this.serverSettings.taskCleanup, [Validators.required])); - } else { - this.settingsForm.addControl('taskCleanupCustom', new FormControl('', [Validators.required])); - } + this.updateCustomFields('taskScan', 'taskScanCustom', this.taskFrequencies, this.serverSettings.taskScan); + this.updateCustomFields('taskBackup', 'taskBackupCustom', this.taskFrequencies, this.serverSettings.taskBackup); + this.updateCustomFields('taskCleanup', 'taskCleanupCustom', this.taskFrequenciesForCleanup, this.serverSettings.taskCleanup); - this.settingsForm.get('taskScanCustom')?.valueChanges.pipe( - debounceTime(100), - switchMap(val => this.settingsService.isValidCronExpression(val)), - tap(isValid => { - if (isValid) { - this.settingsForm.get('taskScanCustom')?.setErrors(null); - } else { - this.settingsForm.get('taskScanCustom')?.setErrors({invalidCron: true}) - } - this.cdRef.markForCheck(); - }), - takeUntilDestroyed(this.destroyRef) - ).subscribe(); - - this.settingsForm.get('taskBackupCustom')?.valueChanges.pipe( - debounceTime(100), - switchMap(val => this.settingsService.isValidCronExpression(val)), - tap(isValid => { - if (isValid) { - this.settingsForm.get('taskBackupCustom')?.setErrors(null); - } else { - this.settingsForm.get('taskBackupCustom')?.setErrors({invalidCron: true}) - } - this.cdRef.markForCheck(); - }), - takeUntilDestroyed(this.destroyRef) - ).subscribe(); - - this.settingsForm.get('taskCleanupCustom')?.valueChanges.pipe( - debounceTime(100), - switchMap(val => this.settingsService.isValidCronExpression(val)), - tap(isValid => { - if (isValid) { - this.settingsForm.get('taskCleanupCustom')?.setErrors(null); - } else { - this.settingsForm.get('taskCleanupCustom')?.setErrors({invalidCron: true}) - } - this.cdRef.markForCheck(); - }), - takeUntilDestroyed(this.destroyRef) - ).subscribe(); + // Call the validation method for each custom control + this.validateCronExpression('taskScanCustom'); + this.validateCronExpression('taskBackupCustom'); + this.validateCronExpression('taskCleanupCustom'); // Automatically save settings as we edit them this.settingsForm.valueChanges.pipe( distinctUntilChanged(), debounceTime(100), - filter(_ => this.settingsForm.valid), + filter(_ => { + // This has a unique situation, so we can't just check if valid. We need to check the custom fields + + return this.settingsForm.valid; + }), + takeUntilDestroyed(this.destroyRef), switchMap(_ => { const data = this.packData(); + console.log('data: ', data) return this.settingsService.updateServerSettings(data); }), tap(settings => { @@ -235,6 +189,35 @@ export class ManageTasksSettingsComponent implements OnInit { this.cdRef.markForCheck(); } + // Custom logic to dynamically handle custom fields and validators + updateCustomFields(controlName: string, customControlName: string, frequencyList: string[], currentSetting: string) { + if (!frequencyList.includes(currentSetting)) { + // If the setting is not in the predefined list, it's a custom value + this.settingsForm.get(controlName)?.setValue(this.customOption); + this.settingsForm.addControl(customControlName, new FormControl(currentSetting, [Validators.required])); + } else { + // Otherwise, reset the custom control (no need for Validators.required here) + this.settingsForm.addControl(customControlName, new FormControl('')); + } + } + + // Validate the custom fields for cron expressions + validateCronExpression(controlName: string) { + this.settingsForm.get(controlName)?.valueChanges.pipe( + debounceTime(100), + switchMap(val => this.settingsService.isValidCronExpression(val)), + tap(isValid => { + if (isValid) { + this.settingsForm.get(controlName)?.setErrors(null); + } else { + this.settingsForm.get(controlName)?.setErrors({ invalidCron: true }); + } + this.cdRef.markForCheck(); + }), + takeUntilDestroyed(this.destroyRef) + ).subscribe(); + } + resetForm() { this.settingsForm.get('taskScan')?.setValue(this.serverSettings.taskScan, {onlySelf: true, emitEvent: false}); From ec68607566d8e9d23b148c11cb307a1a7b1a3219 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 16:10:43 -0500 Subject: [PATCH 10/26] Fixed a bug where manage tasks screen wasn't saving --- .../manage-tasks-settings.component.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts b/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts index d66a2d2c2..009a2840a 100644 --- a/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts +++ b/UI/Web/src/app/admin/manage-tasks-settings/manage-tasks-settings.component.ts @@ -162,16 +162,10 @@ export class ManageTasksSettingsComponent implements OnInit { this.settingsForm.valueChanges.pipe( distinctUntilChanged(), debounceTime(100), - filter(_ => { - // This has a unique situation, so we can't just check if valid. We need to check the custom fields - - return this.settingsForm.valid; - }), - + filter(_ => this.settingsForm.valid), takeUntilDestroyed(this.destroyRef), switchMap(_ => { const data = this.packData(); - console.log('data: ', data) return this.settingsService.updateServerSettings(data); }), tap(settings => { From 4beb2e74d53a7e0c9b763ee554f57f0fd522da5c Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 16:20:51 -0500 Subject: [PATCH 11/26] Don't serialize reading list items over opds when we can avoid it --- API/Controllers/OPDSController.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/API/Controllers/OPDSController.cs b/API/Controllers/OPDSController.cs index b025be4a4..3466b5587 100644 --- a/API/Controllers/OPDSController.cs +++ b/API/Controllers/OPDSController.cs @@ -549,12 +549,15 @@ public async Task GetReadingLists(string apiKey, [FromQuery] int Id = readingListDto.Id.ToString(), Title = readingListDto.Title, Summary = readingListDto.Summary, - Links = new List() - { - CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, $"{prefix}{apiKey}/reading-list/{readingListDto.Id}"), - CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}"), - CreateLink(FeedLinkRelation.Thumbnail, FeedLinkType.Image, $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}") - } + Links = + [ + CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, + $"{prefix}{apiKey}/reading-list/{readingListDto.Id}"), + CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, + $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}"), + CreateLink(FeedLinkRelation.Thumbnail, FeedLinkType.Image, + $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}") + ] }); } @@ -573,7 +576,7 @@ private static UserParams GetUserParams(int pageNumber) [HttpGet("{apiKey}/reading-list/{readingListId}")] [Produces("application/xml")] - public async Task GetReadingListItems(int readingListId, string apiKey) + public async Task GetReadingListItems(int readingListId, string apiKey, [FromQuery] int pageNumber = 0) { var userId = await GetUser(apiKey); if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds) @@ -592,7 +595,7 @@ public async Task GetReadingListItems(int readingListId, string a var feed = CreateFeed(readingList.Title + " " + await _localizationService.Translate(userId, "reading-list"), $"{apiKey}/reading-list/{readingListId}", apiKey, prefix); SetFeedId(feed, $"reading-list-{readingListId}"); - var items = (await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId)).ToList(); + var items = await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId); foreach (var item in items) { var chapterDto = await _unitOfWork.ChapterRepository.GetChapterDtoAsync(item.ChapterId); From 9bde8e3a5444fe663e835169ace21133188340a2 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Wed, 18 Sep 2024 20:06:47 -0500 Subject: [PATCH 12/26] Changed edit setting item so that when selection text within the input, the setting item won't close on release outside the input area. --- .../_components/setting-item/setting-item.component.ts | 4 +++- openapi.json | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/UI/Web/src/app/settings/_components/setting-item/setting-item.component.ts b/UI/Web/src/app/settings/_components/setting-item/setting-item.component.ts index 7a50d98e6..36b84ab31 100644 --- a/UI/Web/src/app/settings/_components/setting-item/setting-item.component.ts +++ b/UI/Web/src/app/settings/_components/setting-item/setting-item.component.ts @@ -69,7 +69,9 @@ export class SettingItemComponent { if (!this.toggleOnViewClick) return false; const mouseEvent = event as MouseEvent; - return !elementRef.nativeElement.contains(mouseEvent.target) + const selection = window.getSelection(); + const hasSelection = selection !== null && selection.toString().trim() === ''; + return !elementRef.nativeElement.contains(mouseEvent.target) && hasSelection; }), tap(() => { this.isEditMode = false; diff --git a/openapi.json b/openapi.json index 124ac091b..9c696a09b 100644 --- a/openapi.json +++ b/openapi.json @@ -4383,6 +4383,15 @@ "schema": { "type": "string" } + }, + { + "name": "pageNumber", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } } ], "responses": { From 717bc6bf52917546bfe959925dc5ec62138c796b Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Thu, 19 Sep 2024 07:17:05 -0500 Subject: [PATCH 13/26] Fixed missing validators being updated for 256 character passwords --- API/DTOs/Account/ConfirmEmailDto.cs | 2 +- API/DTOs/Account/ConfirmPasswordResetDto.cs | 2 +- API/DTOs/Account/ResetPasswordDto.cs | 2 +- API/DTOs/RegisterDto.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/API/DTOs/Account/ConfirmEmailDto.cs b/API/DTOs/Account/ConfirmEmailDto.cs index fb9a7c470..2f5849e74 100644 --- a/API/DTOs/Account/ConfirmEmailDto.cs +++ b/API/DTOs/Account/ConfirmEmailDto.cs @@ -9,7 +9,7 @@ public class ConfirmEmailDto [Required] public string Token { get; set; } = default!; [Required] - [StringLength(32, MinimumLength = 6)] + [StringLength(256, MinimumLength = 6)] public string Password { get; set; } = default!; [Required] public string Username { get; set; } = default!; diff --git a/API/DTOs/Account/ConfirmPasswordResetDto.cs b/API/DTOs/Account/ConfirmPasswordResetDto.cs index 862a18986..16dd86f9a 100644 --- a/API/DTOs/Account/ConfirmPasswordResetDto.cs +++ b/API/DTOs/Account/ConfirmPasswordResetDto.cs @@ -9,6 +9,6 @@ public class ConfirmPasswordResetDto [Required] public string Token { get; set; } = default!; [Required] - [StringLength(32, MinimumLength = 6)] + [StringLength(256, MinimumLength = 6)] public string Password { get; set; } = default!; } diff --git a/API/DTOs/Account/ResetPasswordDto.cs b/API/DTOs/Account/ResetPasswordDto.cs index fc7147f62..51a195131 100644 --- a/API/DTOs/Account/ResetPasswordDto.cs +++ b/API/DTOs/Account/ResetPasswordDto.cs @@ -13,7 +13,7 @@ public class ResetPasswordDto /// The new password /// [Required] - [StringLength(32, MinimumLength = 6)] + [StringLength(256, MinimumLength = 6)] public string Password { get; init; } = default!; /// /// The old, existing password. If an admin is performing the change, this is not required. Otherwise, it is. diff --git a/API/DTOs/RegisterDto.cs b/API/DTOs/RegisterDto.cs index b6132046f..d0118e385 100644 --- a/API/DTOs/RegisterDto.cs +++ b/API/DTOs/RegisterDto.cs @@ -11,6 +11,6 @@ public class RegisterDto /// public string Email { get; init; } = default!; [Required] - [StringLength(32, MinimumLength = 6)] + [StringLength(256, MinimumLength = 6)] public string Password { get; set; } = default!; } From 179a033116dc046d2e5163b8e87fcba58bc2e027 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 20 Sep 2024 00:57:04 +0200 Subject: [PATCH 14/26] [skip ci] Weblate Changes (#3188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Havokdan Co-authored-by: daydreamrabbit Co-authored-by: 無情天 --- UI/Web/src/assets/langs/ko.json | 8 ++++---- UI/Web/src/assets/langs/pt_BR.json | 28 ++++++++++++++-------------- UI/Web/src/assets/langs/zh_Hans.json | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/UI/Web/src/assets/langs/ko.json b/UI/Web/src/assets/langs/ko.json index e18cc357a..25c29a19c 100644 --- a/UI/Web/src/assets/langs/ko.json +++ b/UI/Web/src/assets/langs/ko.json @@ -693,11 +693,11 @@ "annual": "연간" }, "publication-status-pipe": { - "ended": "종료", - "ongoing": "진행중", - "hiatus": "중단", + "ended": "누락", + "ongoing": "연재중", + "hiatus": "휴재", "completed": "완결", - "cancelled": "취소" + "cancelled": "연재중단" }, "person-role-pipe": { "character": "캐릭터", diff --git a/UI/Web/src/assets/langs/pt_BR.json b/UI/Web/src/assets/langs/pt_BR.json index 4393dc731..25bb42a4f 100644 --- a/UI/Web/src/assets/langs/pt_BR.json +++ b/UI/Web/src/assets/langs/pt_BR.json @@ -1171,8 +1171,8 @@ "series-tab": "{{tabs.series-tab}}", "name-label": "Nome", "name-validation": "Nome deve ser único", - "promote-label": "Promoção", - "promote-tooltip": "Promoção significa que a tag pode ser vista em todo o servidor, não apenas para usuários administrativos. Todas as séries que possuem essa tag ainda terão restrições de acesso do usuário.", + "promote-label": "Divulgar", + "promote-tooltip": "Divulgação significa que a etiqueta pode ser vista em todo o servidor, não apenas para usuários administrativos. Todas as séries que possuem essa etiqueta ainda terão restrições de acesso do usuário.", "summary-label": "Sumário", "deselect-all": "{{common.deselect-all}}", "select-all": "{{common.select-all}}", @@ -1319,8 +1319,8 @@ "month-label": "Mês", "ending-title": "Terminando", "starting-title": "Começando", - "promote-label": "Promover", - "promote-tooltip": "Promoção significa que a coleção pode ser vista em todo o servidor, não apenas para você. Todas as séries desta coleção ainda terão restrições de acesso do usuário." + "promote-label": "Divulgar", + "promote-tooltip": "Divulgação significa que a coleção pode ser vista em todo o servidor, não apenas para você. Todas as séries desta coleção ainda terão restrições de acesso do usuário." }, "import-cbl-modal": { "close": "{{common.close}}", @@ -1705,8 +1705,8 @@ "confirm-download-size-ios": "O iOS tem problemas para baixar arquivos maiores que 200 MB; esse download pode não ser concluído.", "confirm-delete-collections": "Tem certeza de que deseja excluir várias coleções?", "collection-not-owned": "Você não possui esta coleção", - "collections-promoted": "Coleções promovidas", - "collections-unpromoted": "Coleções não promovidas", + "collections-promoted": "Coleções divulgadas", + "collections-unpromoted": "Coleções não divulgadas", "collections-deleted": "Coleções excluídas", "pdf-book-mode-screen-size": "Tela muito pequena para o modo Livro", "stack-imported": "Pilha Importada", @@ -1714,11 +1714,11 @@ "mal-token-required": "O token MAL é obrigatório, definido nas Configurações do Usuário", "reading-lists-deleted": "Listas de leitura excluídas", "confirm-delete-reading-lists": "Tem certeza de que deseja excluir as listas de leitura? Isto não pode ser desfeito.", - "reading-lists-unpromoted": "Listas de leitura não promovidas", - "reading-lists-promoted": "Listas de leitura promovidas", - "reading-list-promoted": "Lista de Leitura promovida", + "reading-lists-unpromoted": "Listas de leitura não divulgadas", + "reading-lists-promoted": "Listas de leitura divulgadas", + "reading-list-promoted": "Lista de Leitura divulgadas", "confirm-reset-server-settings": "Isso redefinirá suas configurações para os valores da primeira instalação. Tem certeza de que deseja continuar?", - "reading-list-unpromoted": "Lista de Leitura não promovida", + "reading-list-unpromoted": "Lista de Leitura não divulgadas", "generate-colorscape-queued": "Gerar colorscape na fila para {{name}}", "chapter-deleted": "Capítulo excluído", "confirm-delete-chapter": "Tem certeza de que deseja excluir este capítulo? Não modificará arquivos no disco.", @@ -1754,8 +1754,8 @@ "mark-invisible": "Marcar como Invisível", "mark-visible": "Marcar como Visível", "import-mal-stack": "Importar Pilha do Mal", - "unpromote": "Não Promover", - "promote": "Promover", + "unpromote": "Não Divulgar", + "promote": "Divulgar", "generate-colorscape": "Gerar ColorScape", "new-collection": "Nova Coleção", "multiple-selections": "Múltiplas Seleções", @@ -1765,7 +1765,7 @@ "mark-as-read-tooltip": "Marcar o progresso como totalmente lido", "scan-library-tooltip": "Escanear a biblioteca em busca de alterações. Use o escaneamento forçado para forçar a verificação de todas as pastas", "analyze-files-tooltip": "Analisar Arquivos quanto ao tipo e tamanho da extensão", - "unpromote-tooltip": "Restringir a visibilidade apenas à sua conta", + "unpromote-tooltip": "Restringi a visibilidade apenas à sua conta", "generate-colorscape-tooltip": "Gerar colorscapes e quaisquer capas ausentes", "edit-tooltip": "Editar configurações ou detalhes", "remove-from-on-deck-tooltip": "Remover séries da exibição no Na Estante", @@ -1854,7 +1854,7 @@ "loading": "Carregando…", "username": "Nome do usuário", "password": "Senha", - "promoted": "Promovido", + "promoted": "Divulgado", "select-all": "Selecionar Tudo", "deselect-all": "Deselecionar Todos", "series-count": "{{num}} Séries", diff --git a/UI/Web/src/assets/langs/zh_Hans.json b/UI/Web/src/assets/langs/zh_Hans.json index 640087a44..77cfe51f2 100644 --- a/UI/Web/src/assets/langs/zh_Hans.json +++ b/UI/Web/src/assets/langs/zh_Hans.json @@ -1645,7 +1645,7 @@ "email-service-reset": "电子邮件服务已重置", "email-service-reachable": "Kavita电子邮件服务连接成功", "email-service-unresponsive": "电子邮件服务的网址没有响应。", - "refresh-covers-queued": "已为{{name}}排队刷新封面", + "refresh-covers-queued": "刷新 {{name}} 队列中的封面", "library-file-analysis-queued": "已为{{name}}排队进行资料库文件分析", "entity-read": "{{name}}已标记为已读", "entity-unread": "{{name}}已标记为未读", From 96ef7b0b1c5a409092f8b5b32373a1388718cf0b Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Thu, 19 Sep 2024 18:01:05 -0500 Subject: [PATCH 15/26] Locale fix --- UI/Web/src/assets/langs/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json index 20b4f43ed..365876a82 100644 --- a/UI/Web/src/assets/langs/en.json +++ b/UI/Web/src/assets/langs/en.json @@ -527,7 +527,7 @@ "artist": "Artist", "character": "Character", "colorist": "Colorist", - "cover-artist": "Artist", + "cover-artist": "{{artist}}", "editor": "Editor", "inker": "Inker", "letterer": "Letterer", @@ -2189,7 +2189,7 @@ "characters": "{{metadata-fields.characters-title}}", "collection-tags": "Collection Tags", "colorist": "Colorist", - "cover-artist": "Cover Artist", + "cover-artist": "{{person-role-pipe.cover-artist}}", "editor": "Editor", "formats": "Formats", "genres": "{{metadata-fields.genres-title}}", From 49c62aefc1a9ea11b3c600de575732c768d764cb Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Thu, 19 Sep 2024 18:16:18 -0500 Subject: [PATCH 16/26] Manually patch locale --- openapi.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openapi.json b/openapi.json index 9c696a09b..f399ef73e 100644 --- a/openapi.json +++ b/openapi.json @@ -16093,7 +16093,7 @@ "type": "string" }, "password": { - "maxLength": 32, + "maxLength": 256, "minLength": 6, "type": "string" }, @@ -16153,7 +16153,7 @@ "type": "string" }, "password": { - "maxLength": 32, + "maxLength": 256, "minLength": 6, "type": "string" } @@ -19143,7 +19143,7 @@ "nullable": true }, "password": { - "maxLength": 32, + "maxLength": 256, "minLength": 6, "type": "string" } @@ -19282,7 +19282,7 @@ "description": "The Username of the User" }, "password": { - "maxLength": 32, + "maxLength": 256, "minLength": 6, "type": "string", "description": "The new password" From 4868f0b282abec53efffd5c1781ea8dee5f3a840 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 06:45:57 -0500 Subject: [PATCH 17/26] Fixed alignment on details tab so that Genres/Tags lines up with Writers. --- API/config/appsettings.Development.json | 2 +- .../app/_single-module/details-tab/details-tab.component.html | 4 ++-- UI/Web/src/assets/langs/pl.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/config/appsettings.Development.json b/API/config/appsettings.Development.json index 83a13e7ce..f4ac136f8 100644 --- a/API/config/appsettings.Development.json +++ b/API/config/appsettings.Development.json @@ -2,7 +2,7 @@ "TokenKey": "super secret unguessable key that is longer because we require it", "Port": 5000, "IpAddresses": "0.0.0.0,::", - "BaseUrl": "/test/", + "BaseUrl": "/test2/", "Cache": 75, "AllowIFraming": false } \ No newline at end of file diff --git a/UI/Web/src/app/_single-module/details-tab/details-tab.component.html b/UI/Web/src/app/_single-module/details-tab/details-tab.component.html index 5f96f206c..33165d3ed 100644 --- a/UI/Web/src/app/_single-module/details-tab/details-tab.component.html +++ b/UI/Web/src/app/_single-module/details-tab/details-tab.component.html @@ -1,6 +1,6 @@
-
+

{{t('genres-title')}}

@@ -9,7 +9,7 @@

{{t('genres-title')}}

-
+

{{t('tags-title')}}

diff --git a/UI/Web/src/assets/langs/pl.json b/UI/Web/src/assets/langs/pl.json index b7337952c..a172b9d3d 100644 --- a/UI/Web/src/assets/langs/pl.json +++ b/UI/Web/src/assets/langs/pl.json @@ -622,7 +622,7 @@ }, "series-detail": { "continue": "Kontynuuj", - "edit-series-alt": "Edytuj informacje o serii", + "edit-series-alt": "Edytuj informacje", "storyline-tab": "{{tabs.storyline-tab}}", "recommendations-tab": "{{tabs.recommendations-tab}}", "send-to": "Plik wysłany e-mailem do {{deviceName}}", @@ -1199,7 +1199,7 @@ "size-limit-tooltip": "Ile bajtów może obsłużyć serwer poczty e-mail dla załączników", "gmail-label": "Gmail", "outlook-label": "Outlook", - "test-warning": "Musisz zapisać przed użyciem przycisku Test.", + "test-warning": "Przed naciśnięciem przycisku Test wprowadź prawidłowe ustawienia.", "setting-description": "Aby korzystać z funkcji poczty e-mail w Kavita, należy wypełnić zarówno ustawienia nazwy hosta, jak i SMTP." }, "manage-media-settings": { From 899fe27c156e6beeb58fca499be4ddfdcbecd9c7 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 07:38:06 -0500 Subject: [PATCH 18/26] Manually patched localization files so that we can release hotfix with translations. --- API/Services/CacheService.cs | 1 + UI/Web/src/assets/langs/de.json | 13 +++++++------ UI/Web/src/assets/langs/es.json | 13 +++++++------ UI/Web/src/assets/langs/fr.json | 15 ++++++++------- UI/Web/src/assets/langs/ga.json | 11 ++++++----- UI/Web/src/assets/langs/ko.json | 13 +++++++------ UI/Web/src/assets/langs/pl.json | 5 +++-- UI/Web/src/assets/langs/pt.json | 13 +++++++------ UI/Web/src/assets/langs/pt_BR.json | 13 +++++++------ UI/Web/src/assets/langs/zh_Hans.json | 13 +++++++------ 10 files changed, 60 insertions(+), 50 deletions(-) diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs index c6e539348..4f5dadfe0 100644 --- a/API/Services/CacheService.cs +++ b/API/Services/CacheService.cs @@ -119,6 +119,7 @@ public IEnumerable GetCachedFileDimensions(string cachePath) } _logger.LogDebug("File Dimensions call for {Length} images took {Time}ms", dimensions.Count, sw.ElapsedMilliseconds); + return dimensions; } diff --git a/UI/Web/src/assets/langs/de.json b/UI/Web/src/assets/langs/de.json index 163536972..59317b78c 100644 --- a/UI/Web/src/assets/langs/de.json +++ b/UI/Web/src/assets/langs/de.json @@ -625,7 +625,7 @@ "continue-incognito": "Unsichtbar fortsetzen", "incognito": "Unsichtbar", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", - "edit-series-alt": "Bearbeite die Serieninformationen", + "edit-series-alt": "Informationen bearbeiten", "user-reviews-local": "Lokale Bewertungen", "user-reviews-plus": "Externe Bewertungen", "cover-artists-title": "{{metadata-fields.cover-artists-title}}", @@ -832,8 +832,9 @@ }, "entity-title": { "special": "Spezial", - "issue-num": "Ausgabe #", - "chapter": "Kapitel" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "Extern öffnen" @@ -867,7 +868,7 @@ "email-settings-title": "E-Mail-Einstellungen", "outlook-label": "Outlook", "setting-description": "Sie müssen sowohl den Hostnamen als auch die SMTP-Einstellungen ausfüllen, um die E-Mail-basierten Funktionen von Kavita nutzen zu können.", - "test-warning": "Sie müssen speichern, bevor Sie die Schaltfläche Test verwenden.", + "test-warning": "Sie müssen über gültige Einstellungen verfügen, bevor Sie auf „Testen“ klicken.", "size-limit-tooltip": "Wie viele Bytes kann der E-Mail-Server für Anhänge verarbeiten", "customized-templates-label": "Angepasste Templates" }, @@ -1135,7 +1136,7 @@ }, "filter-field-pipe": { "want-to-read": "Möchte ich lesen", - "cover-artist": "Cover Künstler", + "cover-artist": "{{person-role-pipe.cover-artist}}", "read-time": "Lesezeit", "location": "Standort", "file-path": "Datei-Pfad", @@ -1251,7 +1252,7 @@ "character": "Charakter", "editor": "Editor", "publisher": "Herausgeber", - "cover-artist": "Cover Künstler", + "cover-artist": "{{artist}}", "translator": "Übersetzer", "colorist": "Kolorist", "imprint": "Impressum", diff --git a/UI/Web/src/assets/langs/es.json b/UI/Web/src/assets/langs/es.json index e853743f8..de4e847a4 100644 --- a/UI/Web/src/assets/langs/es.json +++ b/UI/Web/src/assets/langs/es.json @@ -614,7 +614,7 @@ "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "incognito": "Incógnito", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "Editar informacion de la serie", + "edit-series-alt": "Editar información", "volumes-tab": "{{tabs.volumes-tab}}", "specials-tab": "{{tabs.specials-tab}}", "related-tab": "{{tabs.related-tab}}", @@ -895,7 +895,7 @@ "artist": "Artista", "writer": "Escritor", "character": "Personaje", - "cover-artist": "Artista de portada", + "cover-artist": "{{artist}}", "editor": "Editor", "other": "Otro", "publisher": "Editorial", @@ -1469,8 +1469,9 @@ }, "entity-title": { "special": "Especial", - "chapter": "Capítulo", - "issue-num": "Número #" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "Abrir externamente" @@ -1506,7 +1507,7 @@ "outlook-label": "Outlook", "gmail-label": "Gmail", "setting-description": "Para poder utilizar las funciones de correo electrónico de Kavita, debes rellenar los campos nombre del host y SMTP.", - "test-warning": "Debes guardar antes de utilizar el botón Probar." + "test-warning": "Debe tener configuraciones válidas antes de presionar Probar." }, "cover-image-size": { "xlarge": "Extragrande (1265x1795)", @@ -1658,7 +1659,7 @@ "genres": "{{metadata-fields.genres-title}}", "release-year": "{{sort-field-pipe.release-year}}", "writers": "{{metadata-fields.writers-title}}", - "cover-artist": "Artista de la portada", + "cover-artist": "{{person-role-pipe.cover-artist}}", "read-progress": "Progreso de la lectura", "editor": "Editor", "read-time": "Tiempo de lectura", diff --git a/UI/Web/src/assets/langs/fr.json b/UI/Web/src/assets/langs/fr.json index e690078c6..18ee6e46f 100644 --- a/UI/Web/src/assets/langs/fr.json +++ b/UI/Web/src/assets/langs/fr.json @@ -4,7 +4,7 @@ "username": "{{common.username}}", "password": "{{common.password}}", "password-validation": "{{validation.password-validation}}", - "forgot-password": "Mot de passe oublié ?", + "forgot-password": "Mot de passe oublié?", "submit": "Se connecter" }, "dashboard": { @@ -416,7 +416,7 @@ "other": "Autre", "penciller": "Crayonneur", "letterer": "Lettreur", - "cover-artist": "Artiste de la couverture", + "cover-artist": "{{artist}}", "character": "Personnage", "artist": "Artiste", "inker": "Encreur", @@ -668,7 +668,7 @@ "collection-tags": "Étiquettes de la collection", "characters": "{{metadata-fields.characters-title}}", "languages": "Langues", - "cover-artist": "Artiste de couverture", + "cover-artist": "{{person-role-pipe.cover-artist}}", "writers": "{{metadata-fields.writers-title}}", "release-year": "{{sort-field-pipe.release-year}}", "read-progress": "Progrès de lecture", @@ -987,7 +987,7 @@ "read-incognito": "Lire en mode privé", "specials-tab": "{{tabs.specials-tab}}", "recommendations-tab": "{{tabs.recommendations-tab}}", - "edit-series-alt": "Modifier les informations sur la série", + "edit-series-alt": "Modifier les informations", "layout-mode-option-list": "Liste", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", "no-pages": "{{toasts.no-pages}}", @@ -1317,7 +1317,7 @@ "gmail-label": "Gmail", "outlook-label": "Outlook", "setting-description": "Vous devez remplir les paramètres Nom d'hôte et SMTP pour utiliser les fonctionnalités de messagerie électronique dans Kavita.", - "test-warning": "Vous devez enregistrer avant d'utiliser le bouton Test." + "test-warning": "Vous devez avoir des paramètres valides avant de cliquer sur Test." }, "bulk-add-to-collection": { "collection-label": "Collection", @@ -1332,8 +1332,9 @@ }, "entity-title": { "special": "Spécial", - "chapter": "Chapitre", - "issue-num": "Numéro #" + "chapter": "{{common.chapter-num}}", + "issue-num": "{{common.issue-hash-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "manage-library": { "add-library": "Ajouter une bibliothèque", diff --git a/UI/Web/src/assets/langs/ga.json b/UI/Web/src/assets/langs/ga.json index b6758de54..aec1886b8 100644 --- a/UI/Web/src/assets/langs/ga.json +++ b/UI/Web/src/assets/langs/ga.json @@ -345,7 +345,7 @@ "read-options-alt": "Léigh roghanna", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "Cuir Eolas faoin tSraith in Eagar", + "edit-series-alt": "Cuir Eolas in Eagar", "storyline-tab": "{{tabs.storyline-tab}}", "books-tab": "{{tabs.books-tab}}", "volumes-tab": "{{tabs.volumes-tab}}", @@ -524,7 +524,7 @@ "gmail-label": "GmailName", "description": "Chun úsáid a bhaint as roinnt feidhmeanna de chuid Kavita cosúil le Send To Device ní mór soláthraí ríomhphoist a shocrú. Teastaíonn idirghabháil riaracháin ó ghnéithe eile cosúil le Forgot Password gan socrú Ríomhphost.", "setting-description": "Ní mór duit socruithe Ainm Óstach agus SMTP araon a líonadh chun feidhmiúlacht ríomhphost-bhunaithe a úsáid laistigh de Kavita.", - "test-warning": "Ní mór duit sábháil sula n-úsáideann tú cnaipe Tástála.", + "test-warning": "Ní mór socruithe bailí a bheith agat sula mbuaileann tú Tástáil.", "send-to-warning": "Más mian leat Seol chuig gléas a bheith ag obair ní mór duit do shocruithe ríomhphoist a shocrú", "email-url-label": "URL na Seirbhíse Ríomhphoist", "email-url-tooltip": "Úsáid URL láncháilithe na seirbhíse ríomhphoist. Ná cuir deireadh le slais.", @@ -1134,7 +1134,7 @@ "characters": "{{metadata-fields.characters-title}}", "collection-tags": "Clibeanna Bailiúcháin", "colorist": "Dathóir", - "cover-artist": "Ealaíontóir Clúdaigh", + "cover-artist": "{{person-role-pipe.cover-artist}}", "editor": "Eagarthóir", "formats": "Formáidí", "genres": "{{metadata-fields.genres-title}}", @@ -1849,8 +1849,9 @@ }, "entity-title": { "special": "Speisialta", - "issue-num": "Eisiúint #", - "chapter": "Caibidil 1009" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "Oscail Seachtrach" diff --git a/UI/Web/src/assets/langs/ko.json b/UI/Web/src/assets/langs/ko.json index 25c29a19c..abfce5344 100644 --- a/UI/Web/src/assets/langs/ko.json +++ b/UI/Web/src/assets/langs/ko.json @@ -705,7 +705,7 @@ "writer": "작가", "other": "그 외", "artist": "작가", - "cover-artist": "표지 작가", + "cover-artist": "{{artist}}", "editor": "편집자", "inker": "잉커", "letterer": "레터러", @@ -825,7 +825,7 @@ "series-detail": { "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "시리즈 정보 편집", + "edit-series-alt": "정보 편집", "no-pages": "{{toasts.no-pages}}", "no-chapters": "이 볼륨에는 챕터가 없습니다. 읽을 수 없습니다.", "cover-change": "브라우저에서 이미지를 새로 고치는 데 최대 1분이 걸릴 수 있습니다. 그때까지는 일부 페이지에 이전 이미지가 표시될 수 있습니다.", @@ -982,8 +982,9 @@ }, "entity-title": { "special": "스페셜", - "issue-num": "이슈 #", - "chapter": "챕터" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "manage-email-settings": { "reset": "{{common.reset}}", @@ -1016,7 +1017,7 @@ "username-tooltip": "호스트에 대해 인증하는 데 사용되는 사용자 이름", "host-tooltip": "이메일 서버의 발신/SMTP 주소", "setting-description": "Kavita 내에서 이메일 기반 기능을 사용하려면 호스트 이름과 SMTP 설정을 모두 입력해야 합니다.", - "test-warning": "테스트 버튼을 사용하기 전에 반드시 저장해야 합니다." + "test-warning": "테스트를 누르기 전에 설정이 유효해야 합니다." }, "manage-scrobble-errors": { "edit-item-alt": "편집 {{seriesName}}", @@ -1885,7 +1886,7 @@ "filter-field-pipe": { "collection-tags": "컬렉션 태그", "colorist": "컬러리스트", - "cover-artist": "커버 아티스트", + "cover-artist": "{{person-role-pipe.cover-artist}}", "editor": "편집자", "summary": "요약", "tags": "{{metadata-fields.tags-title}}", diff --git a/UI/Web/src/assets/langs/pl.json b/UI/Web/src/assets/langs/pl.json index a172b9d3d..d97997a16 100644 --- a/UI/Web/src/assets/langs/pl.json +++ b/UI/Web/src/assets/langs/pl.json @@ -1403,8 +1403,9 @@ }, "entity-title": { "special": "Special", - "chapter": "Rozdział", - "issue-num": "Wydanie #" + "chapter": "{{common.chapter-num}}", + "issue-num": "{{common.issue-hash-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "card-detail-layout": { "jumpkey-count": "{{count}} Serii", diff --git a/UI/Web/src/assets/langs/pt.json b/UI/Web/src/assets/langs/pt.json index 655cf93bb..b016906e4 100644 --- a/UI/Web/src/assets/langs/pt.json +++ b/UI/Web/src/assets/langs/pt.json @@ -462,7 +462,7 @@ "artist": "Artista", "character": "Personagem", "colorist": "Colorista", - "cover-artist": "Artista de Capa", + "cover-artist": "{{artist}}", "editor": "Editor", "inker": "Arte-Finalista", "letterer": "Letrista", @@ -682,7 +682,7 @@ "incognito": "Incógnito", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "Editar Informação da Série", + "edit-series-alt": "Editar informações", "storyline-tab": "{{tabs.storyline-tab}}", "books-tab": "{{tabs.books-tab}}", "volumes-tab": "{{tabs.volumes-tab}}", @@ -917,8 +917,9 @@ }, "entity-title": { "special": "Especial", - "issue-num": "Número #", - "chapter": "Capítulo" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "Abrir Externo" @@ -953,7 +954,7 @@ "username-tooltip": "O nome de utilizador usado para autenticar no host", "outlook-label": "Outlook", "gmail-label": "Gmail", - "test-warning": "Tem de gravar antes de usar o botão Teste.", + "test-warning": "Deve ter definições válidas antes de clicar em Teste.", "setting-description": "Tem de preencher o nome do Host e as definições de SMTP para poder usar as funcionalidades do Kavita baseadas em email." }, "manage-library": { @@ -1890,7 +1891,7 @@ }, "filter-field-pipe": { "age-rating": "{{metadata-fields.age-rating-title}}", - "cover-artist": "Artista de Capa", + "cover-artist": "{{person-role-pipe.cover-artist}}", "formats": "Formatos", "genres": "{{metadata-fields.genres-title}}", "libraries": "Bibliotecas", diff --git a/UI/Web/src/assets/langs/pt_BR.json b/UI/Web/src/assets/langs/pt_BR.json index 25bb42a4f..f332ac3e1 100644 --- a/UI/Web/src/assets/langs/pt_BR.json +++ b/UI/Web/src/assets/langs/pt_BR.json @@ -462,7 +462,7 @@ "artist": "Artista", "character": "Personagem", "colorist": "Colorista", - "cover-artist": "Artista da Capa", + "cover-artist": "{{artist}}", "editor": "Editor", "inker": "Arte-finalista", "letterer": "Letrista", @@ -682,7 +682,7 @@ "incognito": "Incógnito", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "Editar Informações da Série", + "edit-series-alt": "Editar informações", "storyline-tab": "{{tabs.storyline-tab}}", "books-tab": "{{tabs.books-tab}}", "volumes-tab": "{{tabs.volumes-tab}}", @@ -917,8 +917,9 @@ }, "entity-title": { "special": "Especial", - "issue-num": "Número #", - "chapter": "Capítulo" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "Abrir Externamente" @@ -953,7 +954,7 @@ "username-tooltip": "O nome de usuário usado para autenticação no host", "gmail-label": "Gmail", "outlook-label": "Outlook", - "test-warning": "Você deve salvar antes de usar o botão Teste.", + "test-warning": "Você deve ter configurações válidas antes de clicar em Testar.", "setting-description": "Você deve preencher as configurações de nome do host e SMTP para usar a funcionalidade baseada em e-mail no Kavita." }, "manage-library": { @@ -1893,7 +1894,7 @@ "characters": "{{metadata-fields.characters-title}}", "collection-tags": "Coleção de Tags", "colorist": "Colorista", - "cover-artist": "Artista da Capa", + "cover-artist": "{{person-role-pipe.cover-artist}}", "editor": "Editor", "genres": "{{metadata-fields.genres-title}}", "inker": "Arte-finalista", diff --git a/UI/Web/src/assets/langs/zh_Hans.json b/UI/Web/src/assets/langs/zh_Hans.json index 77cfe51f2..9eed7f147 100644 --- a/UI/Web/src/assets/langs/zh_Hans.json +++ b/UI/Web/src/assets/langs/zh_Hans.json @@ -462,7 +462,7 @@ "artist": "设计师", "character": "角色", "colorist": "上色师", - "cover-artist": "封面设计", + "cover-artist": "{{artist}}", "editor": "编辑", "inker": "上墨师", "letterer": "嵌字师", @@ -682,7 +682,7 @@ "incognito": "隐身模式", "remove-from-want-to-read": "{{actionable.remove-from-want-to-read}}", "add-to-want-to-read": "{{actionable.add-to-want-to-read}}", - "edit-series-alt": "编辑系列信息", + "edit-series-alt": "編輯訊息", "storyline-tab": "{{tabs.storyline-tab}}", "books-tab": "{{tabs.books-tab}}", "volumes-tab": "{{tabs.volumes-tab}}", @@ -917,8 +917,9 @@ }, "entity-title": { "special": "特刊", - "issue-num": "期 #", - "chapter": "章节" + "issue-num": "{{common.issue-hash-num}}", + "chapter": "{{common.chapter-num}}", + "book-num": "{{common.book-num-shorthand}}" }, "external-series-card": { "open-external": "打开外部链接" @@ -954,7 +955,7 @@ "gmail-label": "Gmail", "outlook-label": "Outlook", "setting-description": "您必须填写主机名和 SMTP 设置才能使用 Kavita 中的基于电子邮件的功能。", - "test-warning": "使用测试按钮之前必须保存。" + "test-warning": "在點擊“測試”之前,您必須具有有效的設定。" }, "manage-library": { "title": "资料库", @@ -1892,7 +1893,7 @@ "characters": "{{metadata-fields.characters-title}}", "collection-tags": "收藏标签", "colorist": "上色师", - "cover-artist": "封面设计", + "cover-artist": "{{person-role-pipe.cover-artist}}", "editor": "编辑", "formats": "格式", "genres": "{{metadata-fields.genres-title}}", From ce2fd7bbda95477dc1c4d136ceb0728218f52fa1 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 07:41:08 -0500 Subject: [PATCH 19/26] Some more polish on details tab --- .../details-tab/details-tab.component.html | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/UI/Web/src/app/_single-module/details-tab/details-tab.component.html b/UI/Web/src/app/_single-module/details-tab/details-tab.component.html index 33165d3ed..5ce715b6f 100644 --- a/UI/Web/src/app/_single-module/details-tab/details-tab.component.html +++ b/UI/Web/src/app/_single-module/details-tab/details-tab.component.html @@ -2,20 +2,24 @@

{{t('genres-title')}}

- - - {{item.title}} - - +
+ + + {{item.title}} + + +

{{t('tags-title')}}

- - - {{item.title}} - - +
+ + + {{item.title}} + + +
@@ -29,7 +33,7 @@

{{t('tags-title')}}

- @if (genres.length > 0 || tags.length > 0) { + @if (genres.length > 0 || tags.length > 0 || webLinks.length > 0) { } From ff024a8e421aaf035dd372c613e0b897c8720b1d Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 08:17:02 -0500 Subject: [PATCH 20/26] Fixed an issue where Cover Image Size wasn't displaying on the UI --- API/config/appsettings.Development.json | 2 +- .../manage-media-settings/manage-media-settings.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/API/config/appsettings.Development.json b/API/config/appsettings.Development.json index f4ac136f8..0c6352d06 100644 --- a/API/config/appsettings.Development.json +++ b/API/config/appsettings.Development.json @@ -2,7 +2,7 @@ "TokenKey": "super secret unguessable key that is longer because we require it", "Port": 5000, "IpAddresses": "0.0.0.0,::", - "BaseUrl": "/test2/", + "BaseUrl": "/", "Cache": 75, "AllowIFraming": false } \ No newline at end of file diff --git a/UI/Web/src/app/admin/manage-media-settings/manage-media-settings.component.ts b/UI/Web/src/app/admin/manage-media-settings/manage-media-settings.component.ts index dc4df9825..6fe077012 100644 --- a/UI/Web/src/app/admin/manage-media-settings/manage-media-settings.component.ts +++ b/UI/Web/src/app/admin/manage-media-settings/manage-media-settings.component.ts @@ -21,7 +21,7 @@ import {allEncodeFormats} from '../_models/encode-format'; import {ManageMediaIssuesComponent} from '../manage-media-issues/manage-media-issues.component'; import {NgFor, NgIf, NgTemplateOutlet} from '@angular/common'; import {translate, TranslocoDirective, TranslocoService} from "@jsverse/transloco"; -import {allCoverImageSizes} from '../_models/cover-image-size'; +import {allCoverImageSizes, CoverImageSize} from '../_models/cover-image-size'; import {pageLayoutModes} from "../../_models/preferences/preferences"; import {PageLayoutModePipe} from "../../_pipes/page-layout-mode.pipe"; import {SettingItemComponent} from "../../settings/_components/setting-item/setting-item.component"; @@ -62,7 +62,7 @@ export class ManageMediaSettingsComponent implements OnInit { this.serverSettings = settings; this.settingsForm.addControl('encodeMediaAs', new FormControl(this.serverSettings.encodeMediaAs, [Validators.required])); this.settingsForm.addControl('bookmarksDirectory', new FormControl(this.serverSettings.bookmarksDirectory, [Validators.required])); - this.settingsForm.addControl('coverImageSize', new FormControl(this.serverSettings.coverImageSize, [Validators.required])); + this.settingsForm.addControl('coverImageSize', new FormControl(this.serverSettings.coverImageSize || CoverImageSize.Default, [Validators.required])); // Automatically save settings as we edit them this.settingsForm.valueChanges.pipe( From 7beeab2dd7cf5eaf4dee9237aedd7df4d5c6dcca Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 08:27:54 -0500 Subject: [PATCH 21/26] Fixed a bug when moving bookmark directory --- API/Controllers/SettingsController.cs | 3 ++- .../app/cards/entity-title/entity-title.component.html | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/API/Controllers/SettingsController.cs b/API/Controllers/SettingsController.cs index 5d0c207d1..e198f82a0 100644 --- a/API/Controllers/SettingsController.cs +++ b/API/Controllers/SettingsController.cs @@ -371,7 +371,8 @@ public async Task> UpdateSettings(ServerSettingDt return Ok(updateSettingsDto); } - private void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bookmarkDirectory) + // Public for Hangfire + public void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bookmarkDirectory) { _directoryService.ExistOrCreate(bookmarkDirectory); _directoryService.CopyDirectoryToDirectory(originalBookmarkDirectory, bookmarkDirectory); diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.html b/UI/Web/src/app/cards/entity-title/entity-title.component.html index 28bb9924f..1b232d902 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.html +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.html @@ -41,7 +41,15 @@ {{number !== LooseLeafOrSpecial ? (isChapter && includeVolume ? volumeTitle : '') : ''}} } - {{number !== LooseLeafOrSpecial ? (isChapter ? (t('chapter') + ' ') + number : volumeTitle) : t('special')}} + @if (number !== LooseLeafOrSpecial) { + @if (isChapter) { + {{t('chapter') + ' ' + number}} + } @else { + {{volumeTitle}} + } + } @else { + {{t('special')}} + } } } From dc935baaa8985b9e0969fad92ec6a295c4dd1548 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 08:45:39 -0500 Subject: [PATCH 22/26] Better handle special chapters not leaking encoding on chapter detail page --- API/Controllers/SettingsController.cs | 6 +++--- .../cards/entity-title/entity-title.component.html | 11 +++++++++-- .../app/cards/entity-title/entity-title.component.ts | 6 ------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/API/Controllers/SettingsController.cs b/API/Controllers/SettingsController.cs index e198f82a0..d884d05c8 100644 --- a/API/Controllers/SettingsController.cs +++ b/API/Controllers/SettingsController.cs @@ -345,7 +345,7 @@ public async Task> UpdateSettings(ServerSettingDt if (updateBookmarks) { - BackgroundJob.Enqueue(() => UpdateBookmarkDirectory(originalBookmarkDirectory, bookmarkDirectory)); + UpdateBookmarkDirectory(originalBookmarkDirectory, bookmarkDirectory); } if (updateSettingsDto.EnableFolderWatching) @@ -371,8 +371,8 @@ public async Task> UpdateSettings(ServerSettingDt return Ok(updateSettingsDto); } - // Public for Hangfire - public void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bookmarkDirectory) + + private void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bookmarkDirectory) { _directoryService.ExistOrCreate(bookmarkDirectory); _directoryService.CopyDirectoryToDirectory(originalBookmarkDirectory, bookmarkDirectory); diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.html b/UI/Web/src/app/cards/entity-title/entity-title.component.html index 1b232d902..7817d870c 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.html +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.html @@ -33,12 +33,19 @@ @case (LibraryType.Manga) { @if (titleName !== '' && prioritizeTitleName) { @if (isChapter && includeChapter) { - {{t('chapter') + ' ' + number + ' - ' }} + @if (number === LooseLeafOrSpecial) { + {{t('chapter') + ' - ' }} + } @else { + {{t('chapter') + ' ' + number + ' - ' }} + } + } {{titleName}} } @else { @if (includeVolume && volumeTitle !== '') { - {{number !== LooseLeafOrSpecial ? (isChapter && includeVolume ? volumeTitle : '') : ''}} + @if (number !== LooseLeafOrSpecial && isChapter && includeVolume) { + {{volumeTitle}} + } } @if (number !== LooseLeafOrSpecial) { diff --git a/UI/Web/src/app/cards/entity-title/entity-title.component.ts b/UI/Web/src/app/cards/entity-title/entity-title.component.ts index af91b1d17..eafdfdef4 100644 --- a/UI/Web/src/app/cards/entity-title/entity-title.component.ts +++ b/UI/Web/src/app/cards/entity-title/entity-title.component.ts @@ -22,7 +22,6 @@ import {DefaultValuePipe} from "../../_pipes/default-value.pipe"; }) export class EntityTitleComponent implements OnInit { - protected readonly LooseLeafOrSpecialNumber = LooseLeafOrDefaultNumber; protected readonly LooseLeafOrSpecial = LooseLeafOrDefaultNumber + ""; protected readonly LibraryType = LibraryType; @@ -62,11 +61,6 @@ export class EntityTitleComponent implements OnInit { this.titleName = c.titleName || ''; this.number = c.range; - // If loose leaf/special - if (this.number === this.LooseLeafOrSpecial) { - - } - } else { const v = this.utilityService.asVolume(this.entity); this.volumeTitle = v.name || ''; From 2db6a91c605e9b279d41a85d9b1b5c6882ead8d4 Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Fri, 20 Sep 2024 13:50:51 -0500 Subject: [PATCH 23/26] Fixed a bunch of issues around smart filters and base url reverse proxy setups. --- API/config/appsettings.Development.json | 2 +- .../src/app/chapter-detail/chapter-detail.component.ts | 8 +++++--- .../series-detail/series-detail.component.ts | 9 ++++++--- .../app/shared/_services/filter-utilities.service.ts | 10 +++++++--- .../dashboard-stream-list-item.component.html | 2 +- .../dashboard-stream-list-item.component.ts | 3 ++- .../manage-smart-filters.component.html | 2 +- .../manage-smart-filters.component.ts | 3 ++- .../sidenav-stream-list-item.component.html | 6 +++--- .../sidenav-stream-list-item.component.ts | 3 ++- .../src/app/volume-detail/volume-detail.component.ts | 8 +++++--- 11 files changed, 35 insertions(+), 21 deletions(-) diff --git a/API/config/appsettings.Development.json b/API/config/appsettings.Development.json index 0c6352d06..83a13e7ce 100644 --- a/API/config/appsettings.Development.json +++ b/API/config/appsettings.Development.json @@ -2,7 +2,7 @@ "TokenKey": "super secret unguessable key that is longer because we require it", "Port": 5000, "IpAddresses": "0.0.0.0,::", - "BaseUrl": "/", + "BaseUrl": "/test/", "Cache": 75, "AllowIFraming": false } \ No newline at end of file diff --git a/UI/Web/src/app/chapter-detail/chapter-detail.component.ts b/UI/Web/src/app/chapter-detail/chapter-detail.component.ts index ad64e2063..fd40ba436 100644 --- a/UI/Web/src/app/chapter-detail/chapter-detail.component.ts +++ b/UI/Web/src/app/chapter-detail/chapter-detail.component.ts @@ -9,7 +9,7 @@ import { } from '@angular/core'; import {BulkOperationsComponent} from "../cards/bulk-operations/bulk-operations.component"; import {TagBadgeComponent} from "../shared/tag-badge/tag-badge.component"; -import {AsyncPipe, DecimalPipe, DOCUMENT, NgStyle, NgClass, DatePipe} from "@angular/common"; +import {AsyncPipe, DecimalPipe, DOCUMENT, NgStyle, NgClass, DatePipe, Location} from "@angular/common"; import {CardActionablesComponent} from "../_single-module/card-actionables/card-actionables.component"; import {CarouselReelComponent} from "../carousel/_components/carousel-reel/carousel-reel.component"; import {ExternalSeriesCardComponent} from "../cards/external-series-card/external-series-card.component"; @@ -171,6 +171,7 @@ export class ChapterDetailComponent implements OnInit { private readonly messageHub = inject(MessageHubService); private readonly actionFactoryService = inject(ActionFactoryService); private readonly actionService = inject(ActionService); + private readonly location = inject(Location); protected readonly AgeRating = AgeRating; protected readonly TabID = TabID; @@ -331,8 +332,9 @@ export class ChapterDetailComponent implements OnInit { } updateUrl(activeTab: TabID) { - const newUrl = `${this.router.url.split('#')[0]}#${activeTab}`; - window.history.replaceState({}, '', newUrl); + const tokens = this.location.path().split('#'); + const newUrl = `${tokens[0]}#${activeTab}`; + this.location.replaceState(newUrl) } openPerson(field: FilterField, value: number) { diff --git a/UI/Web/src/app/series-detail/_components/series-detail/series-detail.component.ts b/UI/Web/src/app/series-detail/_components/series-detail/series-detail.component.ts index a7815f72a..125f7ba9d 100644 --- a/UI/Web/src/app/series-detail/_components/series-detail/series-detail.component.ts +++ b/UI/Web/src/app/series-detail/_components/series-detail/series-detail.component.ts @@ -1,7 +1,7 @@ import { AsyncPipe, DecimalPipe, - DOCUMENT, JsonPipe, + DOCUMENT, JsonPipe, Location, NgClass, NgOptimizedImage, NgStyle, @@ -211,6 +211,7 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked { protected readonly themeService = inject(ThemeService); private readonly filterUtilityService = inject(FilterUtilitiesService); private readonly scrobbleService = inject(ScrobblingService); + private readonly location = inject(Location); protected readonly LibraryType = LibraryType; protected readonly TabID = TabID; @@ -523,6 +524,8 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked { this.cdRef.markForCheck(); }); + + this.route.fragment.pipe(tap(frag => { if (frag !== null && this.activeTabId !== (frag as TabID)) { this.activeTabId = frag as TabID; @@ -561,9 +564,9 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked { } updateUrl(activeTab: TabID) { - var tokens = this.router.url.split('#'); + const tokens = this.location.path().split('#'); const newUrl = `${tokens[0]}#${activeTab}`; - window.history.replaceState({}, '', newUrl); + this.location.replaceState(newUrl) } handleSeriesActionCallback(action: ActionItem, series: Series) { diff --git a/UI/Web/src/app/shared/_services/filter-utilities.service.ts b/UI/Web/src/app/shared/_services/filter-utilities.service.ts index b266ec00c..1cb7c70c1 100644 --- a/UI/Web/src/app/shared/_services/filter-utilities.service.ts +++ b/UI/Web/src/app/shared/_services/filter-utilities.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {inject, Injectable} from '@angular/core'; import {ActivatedRouteSnapshot, Params, Router} from '@angular/router'; import {SortField, SortOptions} from 'src/app/_models/metadata/series-filter'; import {MetadataService} from "../../_services/metadata.service"; @@ -12,6 +12,7 @@ import {TextResonse} from "../../_types/text-response"; import {environment} from "../../../environments/environment"; import {map, tap} from "rxjs/operators"; import {of, switchMap} from "rxjs"; +import {Location} from "@angular/common"; @Injectable({ @@ -19,9 +20,12 @@ import {of, switchMap} from "rxjs"; }) export class FilterUtilitiesService { - private apiUrl = environment.apiUrl; + private readonly location = inject(Location); + private readonly router = inject(Router); + private readonly metadataService = inject(MetadataService); + private readonly http = inject(HttpClient); - constructor(private metadataService: MetadataService, private router: Router, private http: HttpClient) {} + private apiUrl = environment.apiUrl; encodeFilter(filter: SeriesFilterV2 | undefined) { return this.http.post(this.apiUrl + 'filter/encode', filter, TextResonse); diff --git a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.html b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.html index 9bf846f33..e19594d9d 100644 --- a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.html +++ b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.html @@ -22,7 +22,7 @@
@if (!item.isProvided) { }
diff --git a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts index 17c1f2704..1f21b4078 100644 --- a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts +++ b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts @@ -13,11 +13,12 @@ import {NgbProgressbar} from "@ng-bootstrap/ng-bootstrap"; import {TranslocoDirective} from "@jsverse/transloco"; import {DashboardStream} from "../../../_models/dashboard/dashboard-stream"; import {StreamNamePipe} from "../../../_pipes/stream-name.pipe"; +import {RouterLink} from "@angular/router"; @Component({ selector: 'app-dashboard-stream-list-item', standalone: true, - imports: [ImageComponent, MangaFormatIconPipe, MangaFormatPipe, NgbProgressbar, TranslocoDirective, StreamNamePipe, NgClass], + imports: [ImageComponent, MangaFormatIconPipe, MangaFormatPipe, NgbProgressbar, TranslocoDirective, StreamNamePipe, NgClass, RouterLink], templateUrl: './dashboard-stream-list-item.component.html', styleUrls: ['./dashboard-stream-list-item.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush diff --git a/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html b/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html index 05ea56b13..2d2f8f888 100644 --- a/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html +++ b/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html @@ -19,7 +19,7 @@ {{t('errored')}} } - {{f.name}} + {{f.name}}
@if (!item.isProvided) { }
diff --git a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts index 1f21b4078..8842c13a8 100644 --- a/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts +++ b/UI/Web/src/app/sidenav/_components/dashboard-stream-list-item/dashboard-stream-list-item.component.ts @@ -1,11 +1,11 @@ import { ChangeDetectionStrategy, Component, - EventEmitter, + EventEmitter, inject, Input, Output } from '@angular/core'; -import {CommonModule, NgClass} from '@angular/common'; +import {APP_BASE_HREF, CommonModule, NgClass} from '@angular/common'; import {ImageComponent} from "../../../shared/image/image.component"; import {MangaFormatIconPipe} from "../../../_pipes/manga-format-icon.pipe"; import {MangaFormatPipe} from "../../../_pipes/manga-format.pipe"; @@ -27,4 +27,5 @@ export class DashboardStreamListItemComponent { @Input({required: true}) item!: DashboardStream; @Input({required: true}) position: number = 0; @Output() hide: EventEmitter = new EventEmitter(); + protected readonly baseUrl = inject(APP_BASE_HREF); } diff --git a/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html b/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html index 2d2f8f888..5b02fea2f 100644 --- a/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html +++ b/UI/Web/src/app/sidenav/_components/manage-smart-filters/manage-smart-filters.component.html @@ -19,7 +19,7 @@ {{t('errored')}} } - {{f.name}} + {{f.name}}