diff --git a/API/DTOs/Reader/BookmarkDto.cs b/API/DTOs/Reader/BookmarkDto.cs index b132eb958..a6b185683 100644 --- a/API/DTOs/Reader/BookmarkDto.cs +++ b/API/DTOs/Reader/BookmarkDto.cs @@ -13,4 +13,8 @@ public class BookmarkDto public int SeriesId { get; set; } [Required] public int ChapterId { get; set; } + /// + /// This is only used when getting all bookmarks. + /// + public SeriesDto? Series { get; set; } } diff --git a/API/Data/Repositories/UserRepository.cs b/API/Data/Repositories/UserRepository.cs index 3bf5757bb..67a72a7a9 100644 --- a/API/Data/Repositories/UserRepository.cs +++ b/API/Data/Repositories/UserRepository.cs @@ -383,13 +383,6 @@ public class UserRepository : IUserRepository .OrderBy(x => x.Created) .AsNoTracking(); - var filterStatement = filter.Statements.FirstOrDefault(f => f.Field == FilterField.SeriesName); - if (filterStatement == null || string.IsNullOrWhiteSpace(filterStatement.Value)) - return await query - .ProjectTo(_mapper.ConfigurationProvider) - .ToListAsync(); - - var queryString = filterStatement.Value.ToNormalized(); var filterSeriesQuery = query.Join(_context.Series, b => b.SeriesId, s => s.Id, (bookmark, series) => new BookmarkSeriesPair() { @@ -397,6 +390,17 @@ public class UserRepository : IUserRepository series = series }); + var filterStatement = filter.Statements.FirstOrDefault(f => f.Field == FilterField.SeriesName); + if (filterStatement == null || string.IsNullOrWhiteSpace(filterStatement.Value)) + { + return await ApplyLimit(filterSeriesQuery + .Sort(filter.SortOptions) + .AsSplitQuery(), filter.LimitTo) + .ProjectTo(_mapper.ConfigurationProvider) + .ToListAsync(); + } + + var queryString = filterStatement.Value.ToNormalized(); switch (filterStatement.Comparison) { case FilterComparison.Equal: @@ -429,6 +433,7 @@ public class UserRepository : IUserRepository || s.series.LocalizedName != queryString || s.series.SortName != queryString); break; + case FilterComparison.MustContains: case FilterComparison.NotContains: case FilterComparison.GreaterThan: case FilterComparison.GreaterThanEqual: @@ -443,8 +448,6 @@ public class UserRepository : IUserRepository break; } - - return await ApplyLimit(filterSeriesQuery .Sort(filter.SortOptions) .AsSplitQuery(), filter.LimitTo) @@ -458,6 +461,7 @@ public class UserRepository : IUserRepository return limit <= 0 ? query : query.Take(limit); } + /// /// Fetches the UserId by API Key. This does not include any extra information /// diff --git a/API/Helpers/AutoMapperProfiles.cs b/API/Helpers/AutoMapperProfiles.cs index c42a09eff..4c5a1b4f2 100644 --- a/API/Helpers/AutoMapperProfiles.cs +++ b/API/Helpers/AutoMapperProfiles.cs @@ -18,6 +18,7 @@ using API.Entities; using API.Entities.Enums; using API.Entities.Metadata; using API.Entities.Scrobble; +using API.Extensions.QueryExtensions.Filtering; using API.Helpers.Converters; using AutoMapper; using CollectionTag = API.Entities.CollectionTag; @@ -31,6 +32,13 @@ public class AutoMapperProfiles : Profile { public AutoMapperProfiles() { + CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.bookmark.Id)) + .ForMember(dest => dest.Page, opt => opt.MapFrom(src => src.bookmark.Page)) + .ForMember(dest => dest.VolumeId, opt => opt.MapFrom(src => src.bookmark.VolumeId)) + .ForMember(dest => dest.SeriesId, opt => opt.MapFrom(src => src.bookmark.SeriesId)) + .ForMember(dest => dest.ChapterId, opt => opt.MapFrom(src => src.bookmark.ChapterId)) + .ForMember(dest => dest.Series, opt => opt.MapFrom(src => src.series)); CreateMap(); CreateMap(); CreateMap(); diff --git a/API/I18N/cs.json b/API/I18N/cs.json index 2429c508b..79b614c25 100644 --- a/API/I18N/cs.json +++ b/API/I18N/cs.json @@ -158,5 +158,6 @@ "bad-copy-files-for-download": "Nelze zkopírovat soubory do dočasného stažení archivu adresáře.", "send-to-permission": "Nelze odeslat non-EPUB nebo PDF do zařízení, která nejsou podporována na Kindle", "reading-list-title-required": "Název seznamu čtení nemůže být prázdný", - "series-restricted-age-restriction": "Uživatel nemá povoleno sledovat tuto sérii z důvodu věkového omezení" + "series-restricted-age-restriction": "Uživatel nemá povoleno sledovat tuto sérii z důvodu věkového omezení", + "collection-deleted": "Sbírka smazána" } diff --git a/API/I18N/es.json b/API/I18N/es.json index 24a7a0179..658cb4db1 100644 --- a/API/I18N/es.json +++ b/API/I18N/es.json @@ -158,5 +158,6 @@ "browse-collections": "Navegar por colecciones", "reading-list-restricted": "La lista de lectura no existe o no tiene acceso", "browse-want-to-read": "Navegar en deseo leer", - "want-to-read": "Deseo leer" + "want-to-read": "Deseo leer", + "collection-deleted": "Colección eliminada" } diff --git a/API/I18N/it.json b/API/I18N/it.json index 0f6c90b04..e6022d83d 100644 --- a/API/I18N/it.json +++ b/API/I18N/it.json @@ -158,5 +158,6 @@ "browse-collections": "Sfoglia per Collezioni", "reading-list-restricted": "L'elenco di lettura non esiste o non hai accesso", "browse-want-to-read": "Sfoglia Vuoi leggere", - "want-to-read": "Vuoi leggere" + "want-to-read": "Vuoi leggere", + "collection-deleted": "Collezione cancellata" } diff --git a/API/I18N/ko.json b/API/I18N/ko.json index 73bca99d2..97e88bc16 100644 --- a/API/I18N/ko.json +++ b/API/I18N/ko.json @@ -158,5 +158,6 @@ "browse-libraries": "라이브러리에서 찾아보기", "unable-to-register-k+": "오류로 인해 라이선스를 등록할 수 없습니다. Kavita+ 지원 문의", "want-to-read": "읽고 싶어요", - "browse-want-to-read": "읽고 싶어요에서 찾아보기" + "browse-want-to-read": "읽고 싶어요에서 찾아보기", + "collection-deleted": "컬렉션이 삭제되었습니다" } diff --git a/API/I18N/zh_Hans.json b/API/I18N/zh_Hans.json index 9b9d69632..8dcdce257 100644 --- a/API/I18N/zh_Hans.json +++ b/API/I18N/zh_Hans.json @@ -156,5 +156,8 @@ "query-required": "您必须传递一个查询参数", "scrobble-bad-payload": "Scrobble服务提供商的数据无效", "bad-copy-files-for-download": "无法复制文件至临时下载目录", - "progress-must-exist": "用户进程必须存在" + "progress-must-exist": "用户进程必须存在", + "generic-scrobble-hold": "启用锁定时发生错误", + "reset-chapter-lock": "无法重置章节的封面锁", + "collection-deleted": "收藏已删除" } diff --git a/UI/Web/src/app/_models/readers/page-bookmark.ts b/UI/Web/src/app/_models/readers/page-bookmark.ts index e47ef0a06..68feee118 100644 --- a/UI/Web/src/app/_models/readers/page-bookmark.ts +++ b/UI/Web/src/app/_models/readers/page-bookmark.ts @@ -1,8 +1,10 @@ +import {Series} from "../series"; + export interface PageBookmark { id: number; page: number; seriesId: number; volumeId: number; chapterId: number; - fileName: string; -} \ No newline at end of file + series: Series; +} diff --git a/UI/Web/src/app/bookmark/_components/bookmarks/bookmarks.component.ts b/UI/Web/src/app/bookmark/_components/bookmarks/bookmarks.component.ts index a90a4a055..45fea7f64 100644 --- a/UI/Web/src/app/bookmark/_components/bookmarks/bookmarks.component.ts +++ b/UI/Web/src/app/bookmark/_components/bookmarks/bookmarks.component.ts @@ -32,7 +32,6 @@ import { CardDetailLayoutComponent } from '../../../cards/card-detail-layout/car import { BulkOperationsComponent } from '../../../cards/bulk-operations/bulk-operations.component'; import { SideNavCompanionBarComponent } from '../../../sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component'; import {translate, TranslocoDirective, TranslocoService} from "@ngneat/transloco"; -import {FilterField} from "../../../_models/metadata/v2/filter-field"; import {SeriesFilterV2} from "../../../_models/metadata/v2/series-filter-v2"; import {Title} from "@angular/platform-browser"; @@ -128,7 +127,8 @@ export class BookmarksComponent implements OnInit { switch (action.action) { case Action.DownloadBookmark: - this.downloadService.download('bookmark', this.bookmarks.filter(bmk => seriesIds.includes(bmk.seriesId)), (d) => { + this.downloadService.download('bookmark', this.bookmarks.filter(bmk => seriesIds.includes(bmk.seriesId)), + (d) => { if (!d) { this.bulkSelectionService.deselectAll(); } @@ -156,24 +156,18 @@ export class BookmarksComponent implements OnInit { this.readerService.getAllBookmarks(this.filter).pipe(take(1)).subscribe(bookmarks => { this.bookmarks = bookmarks; - this.seriesIds = {}; this.bookmarks.forEach(bmk => { - if (!this.seriesIds.hasOwnProperty(bmk.seriesId)) { - this.seriesIds[bmk.seriesId] = 1; - } else { - this.seriesIds[bmk.seriesId] += 1; - } this.downloadingSeries[bmk.seriesId] = false; this.clearingSeries[bmk.seriesId] = false; }); - const ids = Object.keys(this.seriesIds).map(k => parseInt(k, 10)); - this.seriesService.getAllSeriesByIds(ids).subscribe(series => { - this.jumpbarKeys = this.jumpbarService.getJumpKeys(series, (t: Series) => t.name); - this.series = series; - this.loadingBookmarks = false; - this.cdRef.markForCheck(); + const distinctSeriesMap = new Map(); + this.bookmarks.forEach(b => { + distinctSeriesMap.set(b.series.id, b.series); }); + this.series = Array.from(distinctSeriesMap.values()); + this.jumpbarKeys = this.jumpbarService.getJumpKeys(this.series, (t: Series) => t.name); + this.loadingBookmarks = false; this.cdRef.markForCheck(); }); } @@ -201,10 +195,6 @@ export class BookmarksComponent implements OnInit { }); } - getBookmarkPages(seriesId: number) { - return this.seriesIds[seriesId]; - } - downloadBookmarks(series: Series) { this.downloadingSeries[series.id] = true; this.cdRef.markForCheck(); diff --git a/UI/Web/src/assets/langs/cs.json b/UI/Web/src/assets/langs/cs.json index 5e136331e..6be25663f 100644 --- a/UI/Web/src/assets/langs/cs.json +++ b/UI/Web/src/assets/langs/cs.json @@ -121,169 +121,169 @@ "swipe-to-paginate-label": "Přejeďte prstem na stránkování", "book-reader-settings-title": "Čtečka knih", "tap-to-paginate-label": "Klepnutím můžete stránkovat", - "tap-to-paginate-tooltip": "", - "immersive-mode-label": "", - "immersive-mode-tooltip": "", - "reading-direction-book-label": "", - "reading-direction-book-tooltip": "", - "font-family-label": "", - "font-family-tooltip": "", - "writing-style-label": "", - "writing-style-tooltip": "", - "layout-mode-book-label": "", - "layout-mode-book-tooltip": "", - "color-theme-book-label": "", - "color-theme-book-tooltip": "", - "font-size-book-label": "", - "line-height-book-label": "", - "line-height-book-tooltip": "", - "margin-book-label": "", - "margin-book-tooltip": "", - "clients-opds-alert": "", - "clients-opds-description": "", - "clients-api-key-tooltip": "", - "clients-opds-url-tooltip": "", - "reset": "", - "save": "" + "tap-to-paginate-tooltip": "Pokud strany obrazovky čtečky knih umožňují klepnutím na ni přejít na předchozí/další stránku", + "immersive-mode-label": "Imerzní režim", + "immersive-mode-tooltip": "Tím se nabídka skryje za kliknutí na dokument čtečky a otočením klepnutím zapněte stránkování", + "reading-direction-book-label": "Směr čtení", + "reading-direction-book-tooltip": "Směrem ke kliknutí se přesunete na další stránku. Zprava doleva znamená, že kliknutím na levou stranu obrazovky přejdete na další stránku.", + "font-family-label": "Rodina písem", + "font-family-tooltip": "Rodina písem k načtení. Výchozí načte výchozí písmo knihy", + "writing-style-label": "Styl psaní", + "writing-style-tooltip": "Změní směr textu. Vodorovně je zleva doprava, svisle shora dolů.", + "layout-mode-book-label": "Režim rozvržení", + "layout-mode-book-tooltip": "Jak by měl být obsah rozvržen. Scroll je takový, jak ho kniha balí. 1 nebo 2 sloupce se přizpůsobí výšce zařízení a vejdou se 1 nebo 2 sloupce textu na stránku", + "color-theme-book-label": "Barevný motiv", + "color-theme-book-tooltip": "Jaký barevný motiv použít na obsah a nabídku čtečky knih", + "font-size-book-label": "Velikost písma", + "line-height-book-label": "Řádkování", + "line-height-book-tooltip": "Kolik mezer mezi řádky knihy", + "margin-book-label": "Okraj", + "margin-book-tooltip": "Kolik mezer na každé straně obrazovky. To bude přepsáno na 0 na mobilních zařízeních bez ohledu na toto nastavení.", + "clients-opds-alert": "OPDS není na tomto serveru povoleno. Toto nebude mít vliv na uživatele Tachiyomi.", + "clients-opds-description": "Všichni klienti třetích stran budou používat klíč API nebo níže uvedenou adresu URL připojení. Jsou to jako hesla, udržujte je v soukromí.", + "clients-api-key-tooltip": "Klíč API je jako heslo. Udržujte to v tajnosti, Udržujte to v bezpečí.", + "clients-opds-url-tooltip": "OPDS URL", + "reset": "{{common.reset}}", + "save": "{{common.save}}" }, "user-holds": { - "title": "", - "description": "" + "title": "Scrobble drží", + "description": "Toto je uživatelsky spravovaný seznam Sérií, který nebude scrobován na upstream poskytovatele. Sérii můžete kdykoli odstranit a další událost s možností scrobble (průběh čtení, hodnocení, stav chtít číst) spustí události." }, "theme-manager": { - "title": "", - "looking-for-theme": "", - "looking-for-theme-continued": "", - "scan": "", - "site-themes": "", - "set-default": "", - "apply": "", - "applied": "", - "updated-toastr": "", - "scan-queued": "" + "title": "Správce motivů", + "looking-for-theme": "Hledáte téma světla nebo e-ink? Máme několik vlastních motivů, které můžete použít u nás ", + "looking-for-theme-continued": "téma github.", + "scan": "Skenovat", + "site-themes": "Témata stránek", + "set-default": "Nastavit výchozí", + "apply": "{{common.apply}}", + "applied": "Aplikovaný", + "updated-toastr": "Výchozí nastavení webu bylo aktualizováno na {{name}}", + "scan-queued": "Kontrola motivu webu byla zařazena do fronty" }, "theme": { - "theme-dark": "", - "theme-black": "", - "theme-paper": "", - "theme-white": "" + "theme-dark": "Temný", + "theme-black": "Černá", + "theme-paper": "Papír", + "theme-white": "Bílý" }, "restriction-selector": { - "title": "", - "description": "", - "not-applicable-for-admins": "", - "age-rating-label": "", - "no-restriction": "", - "include-unknowns-label": "", - "include-unknowns-tooltip": "" + "title": "Věkové omezení", + "description": "Po výběru budou z výsledků odstraněny všechny série a seznamy čtení, které mají alespoň jednu položku větší než vybrané omezení.", + "not-applicable-for-admins": "Toto neplatí pro administrátory.", + "age-rating-label": "Věkové hodnocení", + "no-restriction": "Bez omezení", + "include-unknowns-label": "Zahrnout neznámé", + "include-unknowns-tooltip": "Pokud je pravda, budou Neznámé povoleny s věkovým omezením. To by mohlo vést k úniku neoznačených médií k uživatelům s věkovým omezením." }, "site-theme-provider-pipe": { - "system": "", - "user": "" + "system": "Systém", + "user": "Uživatel" }, "manage-devices": { - "title": "", - "description": "", - "devices-title": "", - "no-devices": "", - "platform-label": "", - "email-label": "", - "add": "", - "delete": "", - "edit": "" + "title": "Správce zařízení", + "description": "Tato část je určena k nastavení zařízení, která se nemohou připojit ke Kavitě prostřednictvím webového prohlížeče a místo toho mají e-mailovou adresu, která přijímá soubory.", + "devices-title": "Zařízení", + "no-devices": "Zatím nejsou nastavena žádná zařízení", + "platform-label": "Platforma: ", + "email-label": "Email: ", + "add": "{{common.add}}", + "delete": "{{common.delete}}", + "edit": "{{common.edit}}" }, "edit-device": { - "device-name-label": "", - "email-label": "", - "email-tooltip": "", - "device-platform-label": "", - "save": "", - "required-field": "", - "valid-email": "" + "device-name-label": "Název zařízení", + "email-label": "{{common.email}}", + "email-tooltip": "Tento e-mail bude použit k přijetí souboru prostřednictvím Odeslat", + "device-platform-label": "Platforma zařízení", + "save": "{{common.save}}", + "required-field": "{{validation.required-field}}", + "valid-email": "{{validation.valid-email}}" }, "change-password": { - "password-label": "", - "current-password-label": "", - "new-password-label": "", - "confirm-password-label": "", - "reset": "", - "edit": "", - "cancel": "", - "save": "", - "required-field": "", - "passwords-must-match": "", - "permission-error": "" + "password-label": "{{common.password}}", + "current-password-label": "Aktuální heslo", + "new-password-label": "Nové heslo", + "confirm-password-label": "Potvrďte heslo", + "reset": "{{common.reset}}", + "edit": "{{common.edit}}", + "cancel": "{{common.cancel}}", + "save": "{{common.save}}", + "required-field": "{{validation.required-field}}", + "passwords-must-match": "Heslo se musí shodovat", + "permission-error": "Nemáte oprávnění ke změně hesla. Obraťte se na správce serveru." }, "change-email": { - "email-label": "", - "current-password-label": "", - "email-not-confirmed": "", - "email-updated-title": "", - "email-updated-description": "", - "setup-user-account": "", - "invite-url-label": "", - "invite-url-tooltip": "", - "permission-error": "", - "required-field": "", - "reset": "", - "edit": "", - "cancel": "", - "save": "" + "email-label": "{{common.email}}", + "current-password-label": "Aktuální heslo", + "email-not-confirmed": "Tento e-mail není potvrzen", + "email-updated-title": "Email aktualizován", + "email-updated-description": "Pro potvrzení e-mailu pro váš účet můžete použít následující odkaz níže. Pokud je váš server externě přístupný, bude na e-mail odeslán e-mail a odkaz lze použít k potvrzení e-mailu.", + "setup-user-account": "Nastavení uživatelského účtu", + "invite-url-label": "Adresa URL pozvánky", + "invite-url-tooltip": "Zkopírujte toto a vložte na novou kartu", + "permission-error": "Nemáte oprávnění změnit svůj e-mail. Obraťte se na správce serveru.", + "required-field": "{{validation.required-field}}", + "reset": "{{common.reset}}", + "edit": "{{common.edit}}", + "cancel": "{{common.cancel}}", + "save": "{{common.save}}" }, "change-age-restriction": { - "age-restriction-label": "", - "unknowns": "", - "reset": "", - "edit": "", - "cancel": "", - "save": "" + "age-restriction-label": "Věkové omezení", + "unknowns": "Neznámí", + "reset": "{{common.reset}}", + "edit": "{{common.edit}}", + "cancel": "{{common.cancel}}", + "save": "{{common.save}}" }, "api-key": { - "copy": "", - "show": "", - "regen-warning": "", - "no-key": "", - "confirm-reset": "", - "key-reset": "" + "copy": "Kopírovat", + "show": "Ukázat", + "regen-warning": "Obnovení klíče API zruší platnost všech stávajících klientů.", + "no-key": "CHYBA – KLÍČ NENÍ NASTAVEN", + "confirm-reset": "Tím zrušíte platnost všech konfigurací OPDS, které jste nastavili. Jste si jistý, že chcete pokračovat?", + "key-reset": "Obnovení klíče API" }, "scrobbling-providers": { - "title": "", - "requires": "", - "token-expired": "", - "no-token-set": "", - "token-set": "", - "generate": "", - "instructions": "", - "token-input-label": "", - "edit": "", - "cancel": "", - "save": "" + "title": "Poskytovatelé scroblingu", + "requires": "Tato funkce vyžaduje aktivní licenci {{product}}", + "token-expired": "Platnost tokenu vypršela", + "no-token-set": "Žádná sada tokenů", + "token-set": "Sada tokenů", + "generate": "Generovat", + "instructions": "První uživatelé by měli kliknout na „{{scrobbling-providers.generate}}“ níže, aby Kavita+ mohla mluvit se {{service}}. Jakmile program autorizujete, zkopírujte a vložte token do níže uvedeného vstupu. Svůj token můžete kdykoli obnovit.", + "token-input-label": "Token {{service}} je zde", + "edit": "{{common.edit}}", + "cancel": "{{common.cancel}}", + "save": "{{common.save}}" }, "typeahead": { - "locked-field": "", - "close": "", - "loading": "", - "add-item": "", - "no-data": "", - "add-custom-item": "" + "locked-field": "Pole je uzamčeno", + "close": "{{common.close}}", + "loading": "{{common.loading}}", + "add-item": "Přidat {{item}}…", + "no-data": "Žádné údaje", + "add-custom-item": ", zadejte pro přidání vlastní položky" }, "generic-list-modal": { - "close": "", - "clear": "", - "filter": "", - "open-filtered-search": "" + "close": "{{common.close}}", + "clear": "Průhledná", + "filter": "Filtr", + "open-filtered-search": "Otevřít filtrované vyhledávání pro {{item}}" }, "user-stats-info-cards": { - "total-pages-read-label": "", - "total-pages-read-tooltip": "", - "total-words-read-label": "", - "total-words-read-tooltip": "", - "time-spent-reading-label": "", - "time-spent-reading-tooltip": "", - "chapters-read-label": "", - "chapters-read-tooltip": "", - "avg-reading-per-week-label": "", - "last-active-label": "", + "total-pages-read-label": "Celkový počet přečtených stránek", + "total-pages-read-tooltip": "{{user-stats-info-cards.total-pages-read-label}}: {{value}}", + "total-words-read-label": "Celkem přečtených slov", + "total-words-read-tooltip": "{{user-stats-info-cards.total-words-read-label}}: {{value}}", + "time-spent-reading-label": "Čas strávený čtením", + "time-spent-reading-tooltip": "{{user-stats-info-cards.time-spent-reading-label}}: {{value}}", + "chapters-read-label": "Přečtené kapitoly", + "chapters-read-tooltip": "{{user-stats-info-cards.chapters-read-label}}: {{value}}", + "avg-reading-per-week-label": "Průměrné čtení / týden", + "last-active-label": "Poslední aktivní", "chapters": "" }, "user-stats": { diff --git a/UI/Web/src/assets/langs/es.json b/UI/Web/src/assets/langs/es.json index 5731694d3..92c7cebb0 100644 --- a/UI/Web/src/assets/langs/es.json +++ b/UI/Web/src/assets/langs/es.json @@ -666,7 +666,7 @@ "tags-title": "Etiquetas", "collections-title": "{{side-nav.collections}}", "reading-lists-title": "{{side-nav.reading-lists}}", - "writers-title": "Escritor/Autor", + "writers-title": "Escritores", "characters-title": "Persoanjes", "see-less": "Ver menos", "see-more": "Ver más", diff --git a/UI/Web/src/assets/langs/it.json b/UI/Web/src/assets/langs/it.json index 16c18b09e..791a449b5 100644 --- a/UI/Web/src/assets/langs/it.json +++ b/UI/Web/src/assets/langs/it.json @@ -1752,6 +1752,7 @@ "does-not-contain": "Non contiene", "less-than-or-equal": "Minore o uguale", "is-in-last": "È ultimo", - "is-not-in-last": "Non è l'ultimo" + "is-not-in-last": "Non è l'ultimo", + "must-contains": "Deve Contenere" } } diff --git a/UI/Web/src/assets/langs/ko.json b/UI/Web/src/assets/langs/ko.json index 0a19d04f1..193d4338b 100644 --- a/UI/Web/src/assets/langs/ko.json +++ b/UI/Web/src/assets/langs/ko.json @@ -1721,7 +1721,9 @@ "writers": "작가", "languages": "언어", "libraries": "라이브러리", - "series-name": "시리즈 이름" + "series-name": "시리즈 이름", + "path": "경로", + "file-path": "파일 경로" }, "filter-comparison-pipe": { "is-not-in-last": "마지막에 없음", @@ -1738,7 +1740,8 @@ "ends-with": "로 끝남", "is-before": "이전", "is-after": "이후", - "is-in-last": "마지막에 있음" + "is-in-last": "마지막에 있음", + "must-contains": "반드시 포함" }, "metadata-builder": { "or": "다음 중 하나와 일치", diff --git a/UI/Web/src/assets/langs/nl.json b/UI/Web/src/assets/langs/nl.json index afce6b1f0..8295bda57 100644 --- a/UI/Web/src/assets/langs/nl.json +++ b/UI/Web/src/assets/langs/nl.json @@ -1270,46 +1270,46 @@ "next": "Volgende", "import-step": "Importeer CBL's", "validate-cbl-step": "Valideer CBL", - "dry-run-step": "", - "final-import-step": "" + "dry-run-step": "Test Run", + "final-import-step": "Laatste stap" }, "pdf-reader": { - "loading-message": "", - "incognito-mode": "", - "light-theme-alt": "", - "dark-theme-alt": "", - "close-reader-alt": "" + "loading-message": "Het laden van……PDF's kunnen langer duren dan verwacht", + "incognito-mode": "Incognito modus", + "light-theme-alt": "Licht thema", + "dark-theme-alt": "Donker thema", + "close-reader-alt": "Sluit Lezer" }, "manga-reader": { - "back": "", - "save-globally": "", - "incognito-alt": "", - "incognito-title": "", - "shortcuts-menu-alt": "", - "prev-page-tooltip": "", - "next-page-tooltip": "", - "prev-chapter-tooltip": "", - "next-chapter-tooltip": "", - "first-page-tooltip": "", - "last-page-tooltip": "", - "left-to-right-alt": "", - "right-to-left-alt": "", - "reading-direction-tooltip": "", - "reading-mode-tooltip": "", - "collapse": "", - "fullscreen": "", - "settings-tooltip": "", - "image-splitting-label": "", - "image-scaling-label": "", - "height": "", - "width": "", - "original": "", - "auto-close-menu-label": "", - "swipe-enabled-label": "", - "enable-comic-book-label": "", - "brightness-label": "", - "first-time-reading-manga": "", - "layout-mode-switched": "", + "back": "Terug", + "save-globally": "Globaal opslaan", + "incognito-alt": "De incognitomodus staat aan. Schakel om uit te schakelen.", + "incognito-title": "Incognito modus:", + "shortcuts-menu-alt": "Sneltoetsen Modaal", + "prev-page-tooltip": "Vorige bladzijde", + "next-page-tooltip": "Volgende bladzijde", + "prev-chapter-tooltip": "Vorig hoofdstuk/volume", + "next-chapter-tooltip": "Volgend hoofdstuk/volume", + "first-page-tooltip": "Eerste pagina", + "last-page-tooltip": "Laatste pagina", + "left-to-right-alt": "Links naar rechts", + "right-to-left-alt": "Rechts naar links", + "reading-direction-tooltip": "Leesrichting: ", + "reading-mode-tooltip": "Leesmodus", + "collapse": "Samenvouwen", + "fullscreen": "Volledig scherm", + "settings-tooltip": "Instellingen", + "image-splitting-label": "Beeldsplitsing", + "image-scaling-label": "Afbeelding schalen", + "height": "Hoogte", + "width": "Breedte", + "original": "Origineel", + "auto-close-menu-label": "{{user-preferences.auto-close-menu-label}}", + "swipe-enabled-label": "Swipen ingeschakeld", + "enable-comic-book-label": "Emuleer stripboek", + "brightness-label": "Helderheid", + "first-time-reading-manga": "Tik op elk gewenst moment op de afbeelding om het menu te openen. U kunt verschillende instellingen configureren of naar de pagina gaan door op de voortgangsbalk te klikken. Tik op de zijkanten van de afbeelding om naar de volgende/vorige pagina te gaan.", + "layout-mode-switched": "De lay-outmodus is overgeschakeld naar Enkel omdat er onvoldoende ruimte is om een dubbele lay-out weer te geven", "no-next-chapter": "", "no-prev-chapter": "", "user-preferences-updated": "" @@ -1630,5 +1630,11 @@ "theme-black": "Zwart", "theme-paper": "Papier", "theme-white": "Wit" + }, + "infinite-scroller": { + "continuous-reading-prev-chapter-alt": "Scroll omhoog om naar het vorige hoofdstuk te gaan", + "continuous-reading-prev-chapter": "Vorig hoofdstuk", + "continuous-reading-next-chapter-alt": "Scroll omhoog om naar het volgende hoofdstuk te gaan", + "continuous-reading-next-chapter": "Volgende hoofdstuk" } } diff --git a/UI/Web/src/assets/langs/zh_Hans.json b/UI/Web/src/assets/langs/zh_Hans.json index 46094236a..c280d249b 100644 --- a/UI/Web/src/assets/langs/zh_Hans.json +++ b/UI/Web/src/assets/langs/zh_Hans.json @@ -91,7 +91,7 @@ "success-toast": "用户首选项已更新", "global-settings-title": "全局设置", "page-layout-mode-label": "页面显示模式", - "page-layout-mode-tooltip": "在系列详细信息页面上将项目显示为卡片或列表视图。", + "page-layout-mode-tooltip": "在系列详细信息页面采用卡片或列表视图。", "locale-label": "本地语言", "locale-tooltip": "Kavita 当前语言", "blur-unread-summaries-label": "模糊未读摘要", @@ -103,7 +103,7 @@ "collapse-series-relationships-label": "折叠系列关系", "collapse-series-relationships-tooltip": "Kavitra 是否显示没有关系的系列或者是父/前传", "share-series-reviews-label": "分享系列评论", - "share-series-reviews-tooltip": "Kavita 是否对其他用户的系列评论显示你的评论", + "share-series-reviews-tooltip": "是否对其他用户显示你的评论", "image-reader-settings-title": "图像阅读器", "reading-direction-label": "阅读方向", "reading-direction-tooltip": "单击方向移动到下一页。从右到左意味着您单击屏幕左侧以移至下一页。", @@ -183,9 +183,9 @@ }, "manage-devices": { "title": "设备管理", - "description": "此部分是为您设置无法通过Web浏览器连接到Kavita的设备而设计的,而是具有接收文件的电子邮件地址。", + "description": "对于无法通过浏览器访问Kavita的设备,您可以设置一个电子邮件地址用来接收文件。", "devices-title": "设备", - "no-devices": "目前还没有设置任何设备", + "no-devices": "尚未设置任何设备", "platform-label": "平台: ", "email-label": "电子邮件: ", "add": "{{common.add}}", @@ -195,7 +195,7 @@ "edit-device": { "device-name-label": "设备名称", "email-label": "{{common.email}}", - "email-tooltip": "此电子邮件将用于通过“发送至”接收文件", + "email-tooltip": "此电子邮件地址用于接收通过“发送到”菜单发送的文件", "device-platform-label": "设备平台", "save": "{{common.save}}", "required-field": "{{validation.required-field}}", @@ -387,16 +387,16 @@ "never": "从不" }, "relationship-pipe": { - "adaptation": "适应", - "alternative-setting": "替代设置", - "alternative-version": "替代版本", - "character": "特征", + "adaptation": "改编", + "alternative-setting": "另类设定", + "alternative-version": "另类版本", + "character": "角色", "contains": "包含", "doujinshi": "同人", "other": "其他", "prequel": "前传", "sequel": "续篇", - "side-story": "支线故事", + "side-story": "支线", "spin-off": "外传", "parent": "原作", "edition": "版本" @@ -621,7 +621,7 @@ "specials-tab": "特刊", "related-tab": "相关", "recommendations-tab": "建议", - "send-to": "文件已通过电子邮件发送至{{deviceName}}", + "send-to": "文件已通过电子邮件发送到{{deviceName}}", "no-pages": "{{toasts.no-pages}}", "no-chapters": "本卷没有章节,无法读取。", "cover-change": "浏览器刷新图片可能需要一分钟的时间。在此期间,某些页面可能仍显示旧的图片。" @@ -694,11 +694,11 @@ "help-us-part-1": "通过遵循我们的 ", "help-us-part-2": "命名指南", "help-us-part-3": "命名和组织您的媒体。", - "naming-conventions-part-1": "Kavita 有 ", + "naming-conventions-part-1": "Kavita资料库的文件夹命名必须符合 ", "naming-conventions-part-2": "文件夹要求。", - "naming-conventions-part-3": "查看此链接确保您正在遵守要求,否则执行扫描后文件无法显示。", - "cover-description": "自定义资料库图片图标是可选的", - "cover-description-extra": "资料库图片不应过大。建议使用较小的文件,尺寸为32x32像素。Kavita不验证文件大小。", + "naming-conventions-part-3": "请查看此链接确保您正在遵守要求,否则执行扫描后文件无法正确显示。", + "cover-description": "自定义资料库的图标是可选项", + "cover-description-extra": "资料库图片不要过大,建议尺寸为32x32像素。Kavita不验证图片文件的尺寸。", "manage-collection-label": "管理收藏", "manage-collection-tooltip": "是否允许Kavita根据ComicInfo.xml/opf文件中的SeriesGroup标签创建收藏", "manage-reading-list-label": "管理阅读列表", @@ -999,14 +999,14 @@ "on-deck-last-chapter-add-label": "最近阅读上一次章节加入(天数)", "on-deck-last-chapter-add-tooltip": "上一次章节内容加入至最近阅读的天数。", "allow-stats-label": "允许匿名收集使用数据", - "allow-stats-tooltip-part-1": "采用匿名方式将使用数据发送到Kavita服务器。这些数据包括使用使用某些功能、文件数量、操作系统版本、Kavita版本号、CPU和内存。我们将使用这些信息来确定功能开发、修复错误和性能调整的优先级。需要重新启动才能生效。请参阅 ", + "allow-stats-tooltip-part-1": "采用匿名方式将使用数据发送到Kavita服务器。这些数据包括使用的某些功能、文件数量、操作系统版本、Kavita版本、CPU和内存。我们将使用这些信息来确定功能开发、错误修复和性能调整的优先级。需要重新启动才能生效。请参阅 ", "allow-stats-tooltip-part-2": "了解收集的内容。", "send-data": "发送数据", "opds-label": "OPDS", "opds-tooltip": "OPDS支持所有用户使用OPDS功能从服务器阅读和下载内容。", "enable-opds": "启用OPDS", "folder-watching-label": "监控文件夹", - "folder-watching-tooltip": "允许Kavita监视资料库文件夹以检测更改并在发生更改时激活扫描。这样可以在没有手动激活扫描或等待每晚扫描计划任务的情况下更新内容。", + "folder-watching-tooltip": "允许Kavita监控资料库文件夹以检测更改,并在文件夹发生更改时激活扫描。这样可以在没有手动激活扫描或等待每晚扫描计划任务的情况下更新内容。", "enable-folder-watching": "启用监控文件夹", "reset-to-default": "{{common.reset-to-default}}", "reset": "{{common.reset}}", @@ -1031,7 +1031,7 @@ "wiki-title": "wiki:", "discord-title": "discord:", "donations-title": "捐赠:", - "source-title": "来源:", + "source-title": "源代码:", "feature-request-title": "功能请求" }, "manage-tasks-settings": { @@ -1122,8 +1122,8 @@ "recommended-tab": "推荐" }, "library-recommended": { - "no-data": "这里没有要显示的内容。请给资料库添加一些元数据,阅读一些内容或对某些内容进行评价。也可能是因为此资料库的推荐功能被关闭了。", - "more-in-genre": "更多内容在{{genre}}", + "no-data": "没有要显示的内容。请给资料库添加一些元数据,阅读一些内容或对某些内容进行评价。也可能是资料库的推荐功能被关闭了。", + "more-in-genre": "{{genre}}类别的更多内容", "rediscover": "重温", "highly-rated": "最高评价", "quick-catchups": "快速回顾", @@ -1142,9 +1142,9 @@ "statistics-tab": "统计数据", "system-tab": "系统", "kavita+-tab": "Kavita+", - "kavita+-desc-part-1": "Kavita+ 是一个高级订阅服务,为 Kavita 上的所有用户解锁高级订阅功能。订阅加以解锁 ", + "kavita+-desc-part-1": "Kavita+是一项高级订阅服务,可为Kavita上的所有用户解锁功能。购买订阅解锁 ", "kavita+-desc-part-2": "高级会员福利", - "kavita+-desc-part-3": "今天!" + "kavita+-desc-part-3": "!" }, "collection-detail": { "no-data": "暂无项目。请尝试添加一个系列。", @@ -1414,7 +1414,7 @@ "format-title": "格式:", "created-title": "创建时间:", "last-read-title": "上次阅读:", - "last-added-title": "最后添加的项目:", + "last-added-title": "最后加入条目:", "last-scanned-title": "上次扫描:", "folder-path-title": "文件路径:", "publication-status-title": "出版状态:", @@ -1491,8 +1491,8 @@ "total-tags-tooltip": "标签总数: {{count}}", "total-people-label": "创作人员总数", "total-people-tooltip": "创作人员总数: {{count}}", - "total-read-time-label": "总阅读时间", - "total-read-time-tooltip": "总阅读时间: {{count}}", + "total-read-time-label": "总阅读时长", + "total-read-time-tooltip": "总阅读时长: {{count}}", "series": "系列", "reads": "次阅读", "release-years-title": "发行年份计数", @@ -1562,7 +1562,7 @@ "mark-unread": "标记为未读", "series-removed-want-to-read": "已移除“想读”中的系列", "series-deleted": "系列已移除", - "file-send-to": "文件已通过邮件发送至{{name}}", + "file-send-to": "文件已通过邮件发送给{{name}}", "theme-missing": "当前的主题已不存在。请刷新页面。", "email-sent": "已发送邮件到{{email}}", "k+-license-saved": "许可密钥已保存,但不是有效的。点击检查以重新验证订阅。首次注册可能需要一分钟来传播。", @@ -1615,7 +1615,7 @@ "others": "其他", "add-to-reading-list": "添加到阅读清单", "add-to-collection": "添加到收藏", - "send-to": "发送至", + "send-to": "发送到", "delete": "删除", "download": "下载", "read-incognito": "隐身阅读", @@ -1746,7 +1746,8 @@ "is-after": "晚于", "is-in-last": "在最近", "is-not-in-last": "不在最近", - "does-not-contain": "不包含" + "does-not-contain": "不包含", + "must-contains": "必须包含" }, "cover-image-size": { "default": "默认 (320x455)", diff --git a/openapi.json b/openapi.json index e971432ac..326534753 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" }, - "version": "0.7.7.19" + "version": "0.7.7.20" }, "servers": [ { @@ -12115,6 +12115,9 @@ "chapterId": { "type": "integer", "format": "int32" + }, + "series": { + "$ref": "#/components/schemas/SeriesDto" } }, "additionalProperties": false