diff --git a/public/locales/en.json b/public/locales/en.json index a4cea328..0209e1cf 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -81,8 +81,8 @@ "confirmation_other": "You are about to download {{count}} chapters.\nSuwayomi is not a mass downloader and too many downloads can get you banned from sources and/or cause performance issues.", "error_one": "Could not add the download", "error_other": "Could not add downloads", - "next_one": "Next chapter", - "next_other" : "Next {{count}} chapters", + "next_one": "Next chapter", + "next_other": "Next {{count}} chapters", "success_one": "Download added", "success_other": "{{count}} downloads added", "unread": "$t(global.filter.label.unread)" @@ -1377,6 +1377,55 @@ } } }, + "opds": { + "binary_file_sizes": { + "label": { + "description": "Display file sizes in binary (KiB, MiB, GiB) instead of decimal (KB, MB, GB)", + "title": "Binary file size", + "unit_one": "item", + "unit_other": "items" + } + }, + "chapter_sort_order": { + "label": { + "description": "Choose the order in which chapters are displayed.", + "title": "Chapter sort order" + } + }, + "enable_page_read_progress": { + "label": { + "description": "Track and update your reading progress by page for each chapter during page streaming", + "title": "Enable page read progress" + } + }, + "items_per_page": { + "label": { + "description": "Number of items per page in OPDS feeds (e.g., Library History, Manga Chapters). \nHigher values may affect client performance.", + "title": "Items per page", + "unit_one": "item", + "unit_other": "items" + } + }, + "mark_as_read_on_download": { + "label": { + "description": "Automatically mark chapters as read when you download them.", + "title": "Mark chapters as read on download" + } + }, + "show_only_downloaded_chapters": { + "label": { + "description": "Filter manga feed to display only chapters you have downloaded.", + "title": "Show only downloaded chapters" + } + }, + "show_only_unread_chapters": { + "label": { + "description": "Filter manga feed to display only chapters you haven’t read yet.", + "title": "Show only unread chapters" + } + }, + "title": "OPDS" + }, "requests": { "sources": { "parallel": { diff --git a/src/lib/graphql/fragments/SettingsFragments.ts b/src/lib/graphql/fragments/SettingsFragments.ts index 141f42c1..96faefba 100644 --- a/src/lib/graphql/fragments/SettingsFragments.ts +++ b/src/lib/graphql/fragments/SettingsFragments.ts @@ -79,5 +79,14 @@ export const SERVER_SETTINGS = gql` flareSolverrSessionName flareSolverrSessionTtl flareSolverrAsResponseFallback + + # OPDS + opdsUseBinaryFileSizes + opdsItemsPerPage + opdsEnablePageReadProgress + opdsMarkAsReadOnDownload + opdsShowOnlyUnreadChapters + opdsShowOnlyDownloadedChapters + opdsChapterSortOrder } `; diff --git a/src/lib/graphql/generated/apollo-helpers.ts b/src/lib/graphql/generated/apollo-helpers.ts index d078f2ef..7e65883b 100644 --- a/src/lib/graphql/generated/apollo-helpers.ts +++ b/src/lib/graphql/generated/apollo-helpers.ts @@ -552,7 +552,7 @@ export type PageInfoFieldPolicy = { hasPreviousPage?: FieldPolicy | FieldReadFunction, startCursor?: FieldPolicy | FieldReadFunction }; -export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[]; +export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'opdsChapterSortOrder' | 'opdsEnablePageReadProgress' | 'opdsItemsPerPage' | 'opdsMarkAsReadOnDownload' | 'opdsShowOnlyDownloadedChapters' | 'opdsShowOnlyUnreadChapters' | 'opdsUseBinaryFileSizes' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[]; export type PartialSettingsTypeFieldPolicy = { autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction, autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction, @@ -589,6 +589,13 @@ export type PartialSettingsTypeFieldPolicy = { maxLogFiles?: FieldPolicy | FieldReadFunction, maxLogFolderSize?: FieldPolicy | FieldReadFunction, maxSourcesInParallel?: FieldPolicy | FieldReadFunction, + opdsChapterSortOrder?: FieldPolicy | FieldReadFunction, + opdsEnablePageReadProgress?: FieldPolicy | FieldReadFunction, + opdsItemsPerPage?: FieldPolicy | FieldReadFunction, + opdsMarkAsReadOnDownload?: FieldPolicy | FieldReadFunction, + opdsShowOnlyDownloadedChapters?: FieldPolicy | FieldReadFunction, + opdsShowOnlyUnreadChapters?: FieldPolicy | FieldReadFunction, + opdsUseBinaryFileSizes?: FieldPolicy | FieldReadFunction, port?: FieldPolicy | FieldReadFunction, socksProxyEnabled?: FieldPolicy | FieldReadFunction, socksProxyHost?: FieldPolicy | FieldReadFunction, @@ -695,7 +702,7 @@ export type SetSourceMetaPayloadFieldPolicy = { clientMutationId?: FieldPolicy | FieldReadFunction, meta?: FieldPolicy | FieldReadFunction }; -export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[]; +export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'opdsChapterSortOrder' | 'opdsEnablePageReadProgress' | 'opdsItemsPerPage' | 'opdsMarkAsReadOnDownload' | 'opdsShowOnlyDownloadedChapters' | 'opdsShowOnlyUnreadChapters' | 'opdsUseBinaryFileSizes' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[]; export type SettingsFieldPolicy = { autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction, autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction, @@ -732,6 +739,13 @@ export type SettingsFieldPolicy = { maxLogFiles?: FieldPolicy | FieldReadFunction, maxLogFolderSize?: FieldPolicy | FieldReadFunction, maxSourcesInParallel?: FieldPolicy | FieldReadFunction, + opdsChapterSortOrder?: FieldPolicy | FieldReadFunction, + opdsEnablePageReadProgress?: FieldPolicy | FieldReadFunction, + opdsItemsPerPage?: FieldPolicy | FieldReadFunction, + opdsMarkAsReadOnDownload?: FieldPolicy | FieldReadFunction, + opdsShowOnlyDownloadedChapters?: FieldPolicy | FieldReadFunction, + opdsShowOnlyUnreadChapters?: FieldPolicy | FieldReadFunction, + opdsUseBinaryFileSizes?: FieldPolicy | FieldReadFunction, port?: FieldPolicy | FieldReadFunction, socksProxyEnabled?: FieldPolicy | FieldReadFunction, socksProxyHost?: FieldPolicy | FieldReadFunction, @@ -746,7 +760,7 @@ export type SettingsFieldPolicy = { webUIInterface?: FieldPolicy | FieldReadFunction, webUIUpdateCheckInterval?: FieldPolicy | FieldReadFunction }; -export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[]; +export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadIgnoreReUploads' | 'autoDownloadNewChapters' | 'autoDownloadNewChaptersLimit' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'flareSolverrAsResponseFallback' | 'flareSolverrEnabled' | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrTimeout' | 'flareSolverrUrl' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxLogFileSize' | 'maxLogFiles' | 'maxLogFolderSize' | 'maxSourcesInParallel' | 'opdsChapterSortOrder' | 'opdsEnablePageReadProgress' | 'opdsItemsPerPage' | 'opdsMarkAsReadOnDownload' | 'opdsShowOnlyDownloadedChapters' | 'opdsShowOnlyUnreadChapters' | 'opdsUseBinaryFileSizes' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPassword' | 'socksProxyPort' | 'socksProxyUsername' | 'socksProxyVersion' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[]; export type SettingsTypeFieldPolicy = { autoDownloadAheadLimit?: FieldPolicy | FieldReadFunction, autoDownloadIgnoreReUploads?: FieldPolicy | FieldReadFunction, @@ -783,6 +797,13 @@ export type SettingsTypeFieldPolicy = { maxLogFiles?: FieldPolicy | FieldReadFunction, maxLogFolderSize?: FieldPolicy | FieldReadFunction, maxSourcesInParallel?: FieldPolicy | FieldReadFunction, + opdsChapterSortOrder?: FieldPolicy | FieldReadFunction, + opdsEnablePageReadProgress?: FieldPolicy | FieldReadFunction, + opdsItemsPerPage?: FieldPolicy | FieldReadFunction, + opdsMarkAsReadOnDownload?: FieldPolicy | FieldReadFunction, + opdsShowOnlyDownloadedChapters?: FieldPolicy | FieldReadFunction, + opdsShowOnlyUnreadChapters?: FieldPolicy | FieldReadFunction, + opdsUseBinaryFileSizes?: FieldPolicy | FieldReadFunction, port?: FieldPolicy | FieldReadFunction, socksProxyEnabled?: FieldPolicy | FieldReadFunction, socksProxyHost?: FieldPolicy | FieldReadFunction, diff --git a/src/lib/graphql/generated/graphql.ts b/src/lib/graphql/generated/graphql.ts index 5b422d43..c31f6fe1 100644 --- a/src/lib/graphql/generated/graphql.ts +++ b/src/lib/graphql/generated/graphql.ts @@ -1556,6 +1556,13 @@ export type PartialSettingsType = Settings & { maxLogFiles?: Maybe; maxLogFolderSize?: Maybe; maxSourcesInParallel?: Maybe; + opdsChapterSortOrder?: Maybe; + opdsEnablePageReadProgress?: Maybe; + opdsItemsPerPage?: Maybe; + opdsMarkAsReadOnDownload?: Maybe; + opdsShowOnlyDownloadedChapters?: Maybe; + opdsShowOnlyUnreadChapters?: Maybe; + opdsUseBinaryFileSizes?: Maybe; port?: Maybe; socksProxyEnabled?: Maybe; socksProxyHost?: Maybe; @@ -1605,6 +1612,13 @@ export type PartialSettingsTypeInput = { maxLogFiles?: InputMaybe; maxLogFolderSize?: InputMaybe; maxSourcesInParallel?: InputMaybe; + opdsChapterSortOrder?: InputMaybe; + opdsEnablePageReadProgress?: InputMaybe; + opdsItemsPerPage?: InputMaybe; + opdsMarkAsReadOnDownload?: InputMaybe; + opdsShowOnlyDownloadedChapters?: InputMaybe; + opdsShowOnlyUnreadChapters?: InputMaybe; + opdsUseBinaryFileSizes?: InputMaybe; port?: InputMaybe; socksProxyEnabled?: InputMaybe; socksProxyHost?: InputMaybe; @@ -1966,6 +1980,13 @@ export type Settings = { maxLogFiles?: Maybe; maxLogFolderSize?: Maybe; maxSourcesInParallel?: Maybe; + opdsChapterSortOrder?: Maybe; + opdsEnablePageReadProgress?: Maybe; + opdsItemsPerPage?: Maybe; + opdsMarkAsReadOnDownload?: Maybe; + opdsShowOnlyDownloadedChapters?: Maybe; + opdsShowOnlyUnreadChapters?: Maybe; + opdsUseBinaryFileSizes?: Maybe; port?: Maybe; socksProxyEnabled?: Maybe; socksProxyHost?: Maybe; @@ -2020,6 +2041,13 @@ export type SettingsType = Settings & { maxLogFiles: Scalars['Int']['output']; maxLogFolderSize: Scalars['String']['output']; maxSourcesInParallel: Scalars['Int']['output']; + opdsChapterSortOrder: SortOrder; + opdsEnablePageReadProgress: Scalars['Boolean']['output']; + opdsItemsPerPage: Scalars['Int']['output']; + opdsMarkAsReadOnDownload: Scalars['Boolean']['output']; + opdsShowOnlyDownloadedChapters: Scalars['Boolean']['output']; + opdsShowOnlyUnreadChapters: Scalars['Boolean']['output']; + opdsUseBinaryFileSizes: Scalars['Boolean']['output']; port: Scalars['Int']['output']; socksProxyEnabled: Scalars['Boolean']['output']; socksProxyHost: Scalars['String']['output']; @@ -2879,7 +2907,7 @@ export type MangaScreenFieldsFragment = { __typename?: 'MangaType', artist?: str export type MangaLibraryDuplicateScreenFieldsFragment = { __typename?: 'MangaType', description?: string | null, id: number, title: string, thumbnailUrl?: string | null, thumbnailUrlLastFetched?: string | null, inLibrary: boolean, initialized: boolean, sourceId: string, unreadCount: number, downloadCount: number, bookmarkCount: number, hasDuplicateChapters: boolean, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }; -export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean }; +export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean, opdsUseBinaryFileSizes: boolean, opdsItemsPerPage: number, opdsEnablePageReadProgress: boolean, opdsMarkAsReadOnDownload: boolean, opdsShowOnlyUnreadChapters: boolean, opdsShowOnlyDownloadedChapters: boolean, opdsChapterSortOrder: SortOrder }; export type SourceMetaFieldsFragment = { __typename?: 'SourceMetaType', sourceId: string, key: string, value: string }; @@ -3241,14 +3269,14 @@ export type ResetServerSettingsMutationVariables = Exact<{ }>; -export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } }; +export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean, opdsUseBinaryFileSizes: boolean, opdsItemsPerPage: number, opdsEnablePageReadProgress: boolean, opdsMarkAsReadOnDownload: boolean, opdsShowOnlyUnreadChapters: boolean, opdsShowOnlyDownloadedChapters: boolean, opdsChapterSortOrder: SortOrder } } }; export type UpdateServerSettingsMutationVariables = Exact<{ input: SetSettingsInput; }>; -export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } } }; +export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean, opdsUseBinaryFileSizes: boolean, opdsItemsPerPage: number, opdsEnablePageReadProgress: boolean, opdsMarkAsReadOnDownload: boolean, opdsShowOnlyUnreadChapters: boolean, opdsShowOnlyDownloadedChapters: boolean, opdsChapterSortOrder: SortOrder } } }; export type GetSourceMangasFetchMutationVariables = Exact<{ input: FetchSourceMangaInput; @@ -3634,7 +3662,7 @@ export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateSt export type GetServerSettingsQueryVariables = Exact<{ [key: string]: never; }>; -export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean } }; +export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyVersion: number, socksProxyHost: string, socksProxyPort: string, socksProxyUsername: string, socksProxyPassword: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadNewChaptersLimit: number, autoDownloadIgnoreReUploads?: boolean | null, extensionRepos: Array, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, systemTrayEnabled: boolean, maxLogFileSize: string, maxLogFiles: number, maxLogFolderSize: string, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string, flareSolverrEnabled: boolean, flareSolverrUrl: string, flareSolverrTimeout: number, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrAsResponseFallback: boolean, opdsUseBinaryFileSizes: boolean, opdsItemsPerPage: number, opdsEnablePageReadProgress: boolean, opdsMarkAsReadOnDownload: boolean, opdsShowOnlyUnreadChapters: boolean, opdsShowOnlyDownloadedChapters: boolean, opdsChapterSortOrder: SortOrder } }; export type GetSourceBrowseQueryVariables = Exact<{ id: Scalars['LongString']['input']; diff --git a/src/modules/settings/screens/ServerSettings.tsx b/src/modules/settings/screens/ServerSettings.tsx index d397e996..118ca814 100644 --- a/src/modules/settings/screens/ServerSettings.tsx +++ b/src/modules/settings/screens/ServerSettings.tsx @@ -32,6 +32,7 @@ import { MetadataUpdateSettings } from '@/modules/app-updates/AppUpdateChecker.t import { ServerSettings as GqlServerSettings } from '@/modules/settings/Settings.types.ts'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts'; +import { SortOrder } from '@/lib/graphql/generated/graphql'; type ServerSettingsType = Pick< GqlServerSettings, @@ -57,6 +58,13 @@ type ServerSettingsType = Pick< | 'flareSolverrSessionName' | 'flareSolverrSessionTtl' | 'flareSolverrAsResponseFallback' + | 'opdsUseBinaryFileSizes' + | 'opdsItemsPerPage' + | 'opdsEnablePageReadProgress' + | 'opdsMarkAsReadOnDownload' + | 'opdsShowOnlyUnreadChapters' + | 'opdsShowOnlyDownloadedChapters' + | 'opdsChapterSortOrder' >; const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType => ({ @@ -82,6 +90,13 @@ const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType flareSolverrSessionName: settings.flareSolverrSessionName, flareSolverrSessionTtl: settings.flareSolverrSessionTtl, flareSolverrAsResponseFallback: settings.flareSolverrAsResponseFallback, + opdsUseBinaryFileSizes: settings.opdsUseBinaryFileSizes, + opdsItemsPerPage: settings.opdsItemsPerPage, + opdsEnablePageReadProgress: settings.opdsEnablePageReadProgress, + opdsMarkAsReadOnDownload: settings.opdsMarkAsReadOnDownload, + opdsShowOnlyUnreadChapters: settings.opdsShowOnlyUnreadChapters, + opdsShowOnlyDownloadedChapters: settings.opdsShowOnlyDownloadedChapters, + opdsChapterSortOrder: settings.opdsChapterSortOrder, }); const getLogFilesCleanupDisplayValue = (ttl: number): string => { @@ -430,6 +445,92 @@ export const ServerSettings = () => { handleChange={(maxLogFolderSize) => updateSetting('maxLogFolderSize', maxLogFolderSize)} /> + + {t('settings.server.opds.title')} + + } + > + + + updateSetting('opdsUseBinaryFileSizes', e.target.checked)} + /> + + updateSetting('opdsItemsPerPage', value)} + /> + + + updateSetting('opdsEnablePageReadProgress', e.target.checked)} + /> + + + + updateSetting('opdsMarkAsReadOnDownload', e.target.checked)} + /> + + + + updateSetting('opdsShowOnlyUnreadChapters', e.target.checked)} + /> + + + + updateSetting('opdsShowOnlyDownloadedChapters', e.target.checked)} + /> + + + settingName={t('settings.server.opds.chapter_sort_order.label.title')} + dialogDescription={t('settings.server.opds.chapter_sort_order.label.description')} + value={serverSettings.opdsChapterSortOrder} + values={[ + [SortOrder.Asc, { text: t('global.sort.label.asc') }], + [SortOrder.Desc, { text: t('global.sort.label.desc') }], + ]} + handleChange={(value) => updateSetting('opdsChapterSortOrder', value)} + /> + ); }; diff --git a/versionToServerVersionMapping.json b/versionToServerVersionMapping.json index 6b1c1dd1..8c16faff 100644 --- a/versionToServerVersionMapping.json +++ b/versionToServerVersionMapping.json @@ -1,7 +1,7 @@ [ { "uiVersion": "PREVIEW", - "serverVersion": "r1719" + "serverVersion": "r1754" }, { "tag": "20250703.01",