* feat: Add versioning to categories
* feat: use random UID for categories.
For legacy and migration we should assign uid on insert, and modify existing one as well in the migration.
* feat: sync category metadata
Add version, uid and lastModifiedAt fields to Category model to allow syncing.
* chore: fix category merging logic
Improve the category merging logic by matching using UIDs first, with a fallback to matching by name for legacy remote categories.
Previously, categories were only matched by name, which could lead to incorrect merges if names were changed. This change ensures more accurate synchronization by prioritizing the unique identifier. Conflict resolution is now based on the `version` field, and logging has been added for better visibility into the merging process.
* refactor: prioritize UID when restoring categories
If a category with the same UID exists, update it instead of creating a new one. Fallback to matching by name if no UID match is found.
* chore: add isSyncing flag like before.
This make sure the version is consistent, and it's not accidentally appended by the trigger, if it does then one device will always be ahead, than previous, and they need to make multiple changes to increase the version.
* Apply suggestion from @jobobby04
Use SY specific numbers(601, 602 for now)
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
* chore: commit review, re-order.
* chore: surround changes in // SY --> // SY <--
* refactor: fallback to existing category UID if backup UID is 0 during restore.
when dealing with old backups (backups created before we added UIDs). In those old backups, backupCategory.uid defaults to 0.
If a user restored an old backup, it would match by name, and then overwrite the newly generated local UID with 0. This would break the synchronization.
* refactor: change to 6xx
* feat: improve sync reliability for categories and settings
- Refactor `mergeCategoriesLists` to correctly match categories by name when UID matching fails, ensuring better reconciliation across devices.
- Fix a bug in category merging where multiple categories with UID 0 (common for non-synced items) caused data loss.
- Update `SyncManager` to detect changes in categories, sources, preferences, saved searches, and extension repos, ensuring they synchronize even when the library favorites haven't changed.
- Convert `BackupCategory` and `BackupExtensionRepos` to data classes to support robust content-aware comparison during the sync process.
- Fix data loss in `mergeSourcesLists`, `mergePreferencesLists`, and `mergeSavedSearchesLists` by retaining local versions when conflicting with remote data.
* fix(sync): properly sync category deletions across devices
Previously, the sync system could not distinguish between a category that was deleted locally and a new category created on another device, causing deleted categories to be restored from the remote backup.
- Update `SyncService` to use `lastSyncTimestamp` to deduce if a missing local category was deleted (if modified before last sync) or newly created remotely (if modified after).
- Update `SyncManager` to explicitly delete local categories that are absent from the merged remote backup, propagating deletions to other devices.
- Fix `RestoreOptions` in `SyncManager` to respect the user's sync preferences instead of hardcoding `categories = true`.
* chore: change it to 6xx and not 600.
* chore: don't need to change this.
* chore: use kotlin time duration units
---------
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
* Add Filters to Updates screen
Behaves basically like the filters in the library:
- Unread: Show/Don't show unread chapters
- Downloaded: Show/Don't show downloaded chapters
- Started: Show/Don't show chapters that have some progress but aren't
fully Read
- Bookmarked: Show/Don't show chapters that have been bookmarked
Started behaves differently from its Library counterpart because the
actual manga data is not available at this point in time and I thought
calling getManga for each entry without caching would be a pretty bad
idea.
I have modelled this closely on the filter control flow in the
Library, but I'm sure this can be simplified/adjusted in some way.
* Move most filtering logic to SQL
Unread, Started, and Bookmarked filters are now part of the SQL query.
Download state cannot be filtered in the database so it remains in
Kotlin.
Because the Downloaded filter has to be run in Kotlin, the combine
flow uses the preferences flow twice, once to get the SQL query params
and once for the Kotlin filters (only Downloaded at this time).
* Add "Hide excluded scanlators" to update filters
Based on the work done in #1623 but integrated with the other filters
in this PR. Added the user as a co-author for credit.
Co-authored-by: Dani <17619547+shabnix@users.noreply.github.com>
---------
Co-authored-by: Dani <17619547+shabnix@users.noreply.github.com>
(cherry picked from commit bbe9aa8561360f030072fbc49f79748e71c6535e)
# Conflicts:
# CHANGELOG.md
# app/src/main/java/eu/kanade/tachiyomi/di/PreferenceModule.kt
# data/src/main/java/tachiyomi/data/updates/UpdatesRepositoryImpl.kt
# data/src/main/sqldelight/tachiyomi/migrations/9.sqm
# domain/src/main/java/tachiyomi/domain/updates/interactor/GetUpdates.kt
* Remove detekt (mihonapp/mihon#1130)
Annoying. More annoying in this project.
(cherry picked from commit 777ae2461e1eb277a3aa0c998ff69e4f100387a1)
* Add spotless (with ktlint) (mihonapp/mihon#1136)
(cherry picked from commit 5ae8095ef1ed2ae9f98486f9148e933c77a28692)
* Address spotless lint errors (mihonapp/mihon#1138)
* Add spotless (with ktlint)
* Run spotlessApply
* screaming case screaming case screaming case
* Update PagerViewerAdapter.kt
* Update ReaderTransitionView.kt
(cherry picked from commit d6252ab7703d52ecf9f43de3ee36fd63e665a31f)
* Generate locales_config.xml in build dir
(cherry picked from commit ac41bffdc97b4cfed923de6b9e8e01cccf3eb6eb)
* Address more spotless lint errors in SY
* some more missed
* more missed
* still missing, not sure while it won't report error when running locally
* one more
* more
* more
* correct comment
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* Moves upcoming requirement from existence to current day or later.
* Suppress millis conversion warning
(cherry picked from commit c9fddf9e388cff5e4071a89719825dee466deaf4)
* Work in progress upcoming feature
* Checkpointing WIP upcoming feature
* Functional Upcoming Screen
* Rename UpdateCalendar to UpdateUpcoming
* Converted Strings to resources
* Cleanup
* Fixed detekt issues
* Removed Link icon per @AntsyLich's suggestion.
* Detekt
* Fixed Calendar display on wide form factor devices
* Added Key to upcoming lazycolumn
* Updated tablet mode UI to support two column view
* Updated header creation logic
* Updated header creation logic... again
* Moved stray string to resources
* Fixed PR Comments and query refactor
* Tweaks to query, refactored to flow, comments on calendar
* Switched to Date Formatter
* Cleaned up date formatter
* More Refactor work
* Updated Calendar to support localized week formats
* Fixed year format
* Refactored Header animation
* Moved upcoming FAQ
* Completed YearMonth Migration
* Replaced currentYearMonth with delegate
* Even more cleanup
* cleaned up alignment modifiers
* Click Handler and other refactors
* Removed Wrapped Content Height/Size/extra clips
* Huge Refactor for CalendarDay
* Another cleanup attempt
* Migrated to new mihon.feature.* module pattern
* changed access modifier
* A Bunch of changes from the next round of reviews
* Cleanups
* Cleanup 2
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 72222ad86d6fb328d20eead86c6357833d08c061)
# Conflicts:
# app/src/main/java/eu/kanade/domain/DomainModule.kt
# gradle/libs.versions.toml
* WIP Extension Repo DB Support
* Wired in to extension screen, browse settings screen
* Detekt changes
* Ui tweaks and open in browser
* Migrate ExtensionRepos on Update
* Migration Cleanup
* Slight cleanup / error handling
* Update ExtensionRepo from Repo.json during extension search.
Added Manual refresh in extension repos page.
* Split repo fetching into separate API module, major refactor work
* Removed development strings
* Moved migration to #3
* Fixed rebase
* Detekt changes
* Added Replace Repository Dialog
* Cleanup, removed platform specific code, PR comments
* Removed extra function, reverted small change
* Detekt cleanup
* Apply suggestions from code review
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* Fixed error introduced in cleanup
* Tweak for multiline when
* Moved getCount() to flow
* changed getCount to non-suspend, used property delegation
* Apply suggestions from code review
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
* Fixed formatting with updated comment string
* Big wave of PR comments, renaming/other tweaks
* onOpenWebsite changes
* onOpenWebsite changes
* trying to make single line
* Renamed ExtensionRepoApi.kt to ExtensionRepoService.kt
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 4b4e46851083c29ca412c114b1b96136fcc21442)
# Conflicts:
# app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
# app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionApi.kt
# app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
# data/src/main/sqldelight/tachiyomi/migrations/3.sqm
* feat: db changes to accommodate new syncing logic.
Using timestamp to sync is a bit skewed due to system clock etc and therefore there was a lot of issues with it such as removing a manga that shouldn't have been removed. Marking chapters as unread even though it was marked as a read. Hopefully by using versioning system it should eliminate those issues.
* chore: add new line.
* chore: remove isSyncing from Chapter/Manga model.
* chore: remove isSyncing leftover.
* chore: remove isSyncing.
* refactor: remove isSync guard.
Just use it directly to 1 now since we don't have the isSyncing field in Manga or Chapter.
* Lint and stuff
* Add missing ,
---------
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 4ae9dbe52487185ef9ee25f58fabe5025bb2278b)
# Conflicts:
# app/build.gradle.kts
# app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt
# app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupChapter.kt
# app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupManga.kt
# data/src/main/java/tachiyomi/data/chapter/ChapterRepositoryImpl.kt
# data/src/main/sqldelight/tachiyomi/migrations/2.sqm
# domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt
* Add custom thumbnail url. Support backup & restore
- add custom thumbnail url in edit info/custom
- include it in backup n restore
* increase chop char
* edit chop char again to match screenshoot
* tweak truncating middle part
* apply edited cover to history, updates , others
* simplify placeholder logic
---------
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
Some behavior changes:
- It prioritizes new entries, then anything more recently updated
- It copies the more recently updated entry's metadata (description, thumbnail, etc.)
(cherry picked from commit 58daedc89ee18d04e7af5bab12629680dba4096c)
# Conflicts:
# app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt
# app/src/main/java/eu/kanade/tachiyomi/source/model/SMangaExtensions.kt