mirror of
https://github.com/Suwayomi/Tachidesk.git
synced 2026-01-26 13:34:06 +01:00
* feat(sync/koreader): implement reading progress synchronization This commit introduces a comprehensive integration with KOReader Sync Server to enable two-way synchronization of reading progress. The core logic is encapsulated in a new `KoreaderSyncService`, which handles authentication, registration, and progress pushing/pulling based on user-defined strategies (LATEST, KOSYNC, SUWAYOMI). Key changes include: - A new GraphQL API is added to manage the KOReader Sync connection: - `connectKoSyncAccount` mutation provides a simplified flow that attempts to log in and, if the user doesn't exist, automatically registers them. - `logoutKoSyncAccount` mutation to clear credentials. - `koSyncStatus` query to check the current connection status. - Reading progress is now synchronized at key points: - The `fetchChapterPages` mutation pulls the latest progress from the sync server before loading the reader. It respects the configured sync strategy and updates the local database if necessary. - The `updateChapters` and other progress-updating methods now push changes to the sync server automatically. - OPDS chapter entries also pull the latest progress, ensuring clients receive up-to-date reading status. - Supporting backend changes have been made: - The `Chapter` table is extended with a `koreader_hash` column to uniquely identify documents. A database migration is included. - New configuration options are added to `server.conf` to manage the feature (enable, server URL, credentials, strategy, etc.). * perf(opds): defer KOReader sync to improve chapter feed performance Removes the KOReader Sync progress-pulling logic from the `createChapterListEntry` function. The previous implementation triggered a network request to the sync server for every single chapter when generating a list, leading to severe performance issues and slow load times on feeds with many entries. This change reverts to the more performant approach of always linking to the chapter's metadata feed. The expensive sync operation will be handled within the metadata entry generation instead, ensuring it's only triggered on-demand for a single chapter. This restores the responsiveness of browsing chapter feeds. * refactor(koreader): Use enums for sync settings and correct OPDS logic Refactor Koreader Sync settings to use enums instead of raw strings for `checksumMethod` and `strategy`. This improves type safety, prevents typos, and makes the configuration handling more robust. The changes include: - Introducing `KoreaderSyncChecksumMethod` and `KoreaderSyncStrategy` enums. - Updating `ServerConfig`, GraphQL types, and backup models to use these new enums. - Refactoring `KoreaderSyncService` to work with the enum types. Additionally, this commit fixes an issue in `OpdsEntryBuilder` where the logic for determining which sync progress to use (local vs. remote) was duplicated. The builder now correctly delegates this decision to `KoreaderSyncService.pullProgress`, which already contains the necessary strategy logic. This centralizes the logic and ensures consistent behavior. * refactor(koreader): Improve config handling and remove redundant update This commit combines several refactoring and cleanup tasks: - **Koreader Sync:** The sync service is updated to use the modern `serverConfig` provider instead of the legacy `GlobalConfigManager`. This aligns it with the current configuration management approach in the project. - **Download Provider:** A redundant `pageCount` database update is removed from `ChaptersFilesProvider`. This operation was unnecessary because the `getChapterDownloadReady` function, which is called earlier in the download process, already verifies and corrects the page count. This change eliminates a superfluous database write and fixes a related import issue. * feat(sync/koreader)!: enhance sync strategy and add progress tolerance This commit overhauls the KOReader synchronization feature to provide more granular control and robustness. The simple on/off toggle has been replaced with a more flexible strategy-based system. Key changes include: - Replaced `koreaderSyncEnabled` with a more powerful `koreaderSyncStrategy` enum. - Introduced new sync strategies: `PROMPT`, `SILENT`, `SEND`, `RECEIVE`, and `DISABLE`, allowing for fine-grained control over the sync direction and conflict resolution. - Added a `koreaderSyncPercentageTolerance` setting. This prevents unnecessary sync updates for minor progress differences between Suwayomi and KOReader. - Refactored the `KoreaderSyncService` to implement the new strategies and use the configurable tolerance. - Updated GraphQL schemas, mutations, and server configuration to remove the old setting and incorporate the new ones. - Adjusted the backup and restore process to correctly handle the new configuration parameters. - Modified API endpoints and internal logic to check and apply remote progress based on the selected strategy. BREAKING CHANGE: The `koreaderSyncEnabled` setting is removed and replaced by a more granular `koreaderSyncStrategy`. The enum values for the strategy have been completely changed, making previous configurations incompatible. * fix: remove unused imports * feat(opds, sync): enhance Koreader sync and OPDS conflict handling This commit introduces significant improvements to the Koreader synchronization feature, focusing on providing a better user experience for handling progress conflicts in both OPDS and GraphQL clients. Key changes include: - **OPDS Conflict Resolution:** When a reading progress conflict is detected, the OPDS feed for a chapter now provides two distinct "Read Online" links: one to continue from the local progress and another to continue from the synced progress from the remote device (e.g., "Continue Reading Online (Synced from KOReader)"). This empowers users to choose which progress to follow. - **GraphQL Sync Conflict Information:** The `fetchChapterPages` GraphQL mutation now includes a `syncConflict` field in its payload. This field provides the remote device name and page number, allowing GraphQL clients to implement a user-facing prompt to resolve sync conflicts. - **Improved Sync Strategy Handling:** - The `connectKoSyncAccount` mutation no longer unconditionally sets the sync strategy to `PROMPT`. It now respects the user's existing setting, preventing accidental configuration changes upon re-login. - The default `koreaderSyncStrategy` in the configuration is changed to `DISABLED`, providing a safer and more intuitive default for new users. - **Refinements & Fixes:** - The fallback for the remote device name is now centralized within the KoreaderSyncService, defaulting to "KOReader" if not provided. - Renamed `KoreaderSyncStrategy.DISABLE` to `DISABLED` for consistency. - Updated i18n strings for OPDS links to be more descriptive and user-friendly. * refactor(kosync): rename stream page link titles for consistency * refactor(kosync): return SettingsType in auth mutation payloads The `connectKoSyncAccount` and `logoutKoSyncAccount` mutations modify server settings (username and userkey) but did not previously return the updated configuration. This forced client applications to manually refetch settings to avoid a stale cache. This change modifies the payloads for both mutations to include the full `SettingsType`. By returning the updated settings directly, GraphQL clients like Apollo Client can automatically update their cache, simplifying client-side state management and ensuring the UI always reflects the current server configuration. Additionally, `clientMutationId` has been added to `KoSyncConnectPayload` for consistency with GraphQL practices, aligning it with the logout mutation. Refs: #1560 * refactor(kosync): replace KoSyncConnectPayload with ConnectResult in connect method * fix(kosync): add koreaderSyncPercentageTolerance default setting