Compare commits

...

691 Commits

Author SHA1 Message Date
Jobobby04 509ace1a38 Revert "Reapply "Fix thread starvation caused by not yielding or using an inappropriate thread pool (#2955)""
This reverts commit 9c01119d24.

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2026-04-08 15:02:37 -04:00
Jobobby04 170358f88e Revert "Reapply "Fix cache invalidation isn't done at startup (#2970)""
This reverts commit c17e9573b7.
2026-04-08 14:52:15 -04:00
Jobobby04 5c14879c12 Fix build 2026-04-06 16:25:25 -04:00
ArthurKun 1682962703 Add gradle.properties to build-logic synced with root gradle.properties (#3159)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2026-04-06 16:22:14 -04:00
Mend Renovate a1daf53188 Update dependency com.gradleup.tapmoc:tapmoc-gradle-plugin to v0.4.1 (#3173) 2026-04-06 16:03:22 -04:00
Mend Renovate b0bdee8c72 Update dependency io.kotest:kotest-assertions-core to v6.1.10 (#3172) 2026-04-06 16:03:16 -04:00
MajorTanya 72c091d317 Add informative error for unapproved MAL titles (#3155)
MAL has a concept of "titles waiting for approval". These titles
cannot be added to user lists, but they do show up on the website and
crucially, in search results.

However, trying to add such an "unapproved" title will return a 400
error response with the error "invalid_content".

Previously, the awaitSuccess() call would mean the generic "HTTP 400"
toast would be shown. Now, a dedicated informative error message is
shown instead.
# Conflicts:
#	CHANGELOG.md
2026-04-06 16:02:51 -04:00
Mend Renovate 1cc796a62e Update dependency androidx.compose:compose-bom-beta to v2026.03.01 (#3147) 2026-04-06 16:02:30 -04:00
Mend Renovate cd40c0fb32 Update dependency androidx.work:work-runtime to v2.11.2 (#3146) 2026-04-06 16:02:15 -04:00
Christos 88edd18d02 Use plural forms for update error notification (#3090)
* Use plural forms for update error notification

Replace the hardcoded 'X update(s) failed' string with Android
plural resources so the notification correctly shows '1 update failed'
vs '2 updates failed', enabling proper localization.

Fixes #3051

* Address review: rename plural key and remove comment

Rename plural key to notification_update_errors to avoid potential
conflicts with existing translated string keys. Remove leftover
comment from strings.xml.

* Revert key rename per review
2026-04-06 16:02:10 -04:00
Mend Renovate ba9d010f78 Update dependency io.kotest:kotest-assertions-core to v6.1.9 (#3137) 2026-04-06 16:02:02 -04:00
Mend Renovate 1ed375968e Update dependency io.kotest:kotest-assertions-core to v6.1.8 (#3132) 2026-04-06 16:01:55 -04:00
MajorTanya 9e525515ea Address Gradle warning about Task.project (#3118)
Apparently, this is all that's needed to replace the forbidden
`Task.project` accessor, which would be an error in Gradle v10 (it's
been deprecated for a while)

This will also allow us to use the Configuration Cache if we wanted
to.
2026-04-06 16:01:47 -04:00
AntsyLich bd7201cfb9 Fix app crash on startup on some Android TV
Why do you guys even exist

# Conflicts:
#	CHANGELOG.md
2026-04-06 16:01:40 -04:00
AntsyLich d9ca2b69e8 Fix occasional crash when mass installing/uninstalling extension using PackageManager
# Conflicts:
#	CHANGELOG.md
2026-04-06 16:01:20 -04:00
AntsyLich 925fb118af Potentially fix 'database is locked' crash
# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt
2026-04-06 15:59:05 -04:00
AntsyLich 4552221020 Fix wrong exception being caught after 8c480c6355 migration
`android.database.sqlite.SQLiteException` instead of `android.database.SQLException`

# Conflicts:
#	CHANGELOG.md
2026-04-06 15:54:09 -04:00
MajorTanya 24b66b7030 Address CancellableContinuation.resume deprecation (#3115)
According to the source docs, this has been a warning since
kotlinx.coroutines 1.9.0.
2026-04-06 15:52:45 -04:00
Mend Renovate 58decd076c Update Gradle to v9 (#2333) 2026-04-06 15:50:18 -04:00
AntsyLich a7d93ae751 Cleanup and rework build logic (#3113)
# Conflicts:
#	app/build.gradle.kts
#	app/shortcuts.xml
#	app/src/main/res/xml/shortcuts.xml
#	app/src/main/shortcuts.xml
#	build.gradle.kts
#	buildSrc/src/main/kotlin/mihon/buildlogic/AndroidConfig.kt
#	core/archive/build.gradle.kts
#	core/common/build.gradle.kts
#	gradle/build-logic/src/main/kotlin/mihon/gradle/BuildConfig.kt
#	settings.gradle.kts
#	source-api/build.gradle.kts
#	source-local/build.gradle.kts
#	telemetry/build.gradle.kts
2026-04-06 15:50:09 -04:00
Weblate (bot) d225b7c586 Translations update from Hosted Weblate (#3003)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/be/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/be/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/lv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ta/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: A <ogloppi@mailbox.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Kehribar <103407696+dpentx@users.noreply.github.com>
Co-authored-by: Lucas Correia <anicetoclucas@gmail.com>
Co-authored-by: ScratchBuild <foobarbuzz@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
Co-authored-by: lilp <felipegabriel.avila6@gmail.com>
Co-authored-by: nadevko <ormak@protonmail.com>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Co-authored-by: 안세훈 <on9686@gmail.com>
# Conflicts:
#	i18n/src/commonMain/moko-resources/be/strings.xml
2026-04-06 15:27:10 -04:00
AntsyLich 4c51d01236 Merge and cleanup version catalogs (#3103)
# Conflicts:
#	app/build.gradle.kts
#	core/archive/build.gradle.kts
#	gradle/libs.versions.toml
#	i18n/build.gradle.kts
#	settings.gradle.kts
#	source-api/build.gradle.kts
2026-04-06 15:26:05 -04:00
Mend Renovate 4d46e84f54 Update dependency com.google.firebase:firebase-bom to v34.11.0 (#3094) 2026-04-06 15:06:15 -04:00
AntsyLich af51607053 Replace preference getter functions with properties (#3091)
# Conflicts:
#	app/src/main/java/eu/kanade/domain/source/interactor/GetEnabledSources.kt
#	app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
#	app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt
#	app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
#	app/src/main/java/eu/kanade/presentation/reader/settings/GeneralSettingsPage.kt
#	app/src/main/java/eu/kanade/presentation/reader/settings/ReadingModePage.kt
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/di/PreferenceModule.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/base/delegate/SecureActivityDelegate.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/stats/StatsScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt
#	app/src/main/java/mihon/feature/migration/list/MigrationListScreenModel.kt
#	core/common/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt
#	domain/src/main/java/tachiyomi/domain/library/service/LibraryPreferences.kt
2026-04-06 15:06:05 -04:00
Leodyver Semilla 1c8e6dcd6f Fix extension actions disappearing after installing and uninstalling in same session (#3049)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
# Conflicts:
#	CHANGELOG.md
2026-04-06 14:20:49 -04:00
AntsyLich 7a398dabba Make retry in reader redownload image (#3089)
# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
2026-04-06 14:18:57 -04:00
Leodyver Semilla b7fcf7ccda Fix WebView JavaScript dialogs popup after screen is closed (#3041)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
# Conflicts:
#	CHANGELOG.md
2026-04-06 14:13:39 -04:00
Leodyver Semilla acbda604cc MangaUpdates API content-type heade (#3021)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
# Conflicts:
#	CHANGELOG.md
2026-04-06 14:13:18 -04:00
Leodyver Semilla 97f3dd3b25 Fix tracker-induced duplicate key crash in duplicate detection (#3040)
# Conflicts:
#	CHANGELOG.md
2026-04-06 14:12:59 -04:00
Mend Renovate 60758f89ed Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.4.0 (#3086) 2026-04-06 14:12:41 -04:00
KaiserBh e96895345e feat(sync): prevent deleted "ghost chapters" from reappearing during sync. (#1575)
* feat(sync): prevent deleted "ghost chapters" from reappearing during sync.

- Pass lastSyncTime down to mergeChapters in SyncService.kt.
- Apply timestamp-based tombstoning logic to chapter merging. When a chapter is missing from either the local or remote backup, its `lastModifiedAt` timestamp is checked against the device's last sync time.
- Ensure that chapters deleted on one device (or removed by a source) are recognized as deletions and dropped from the merged backup, rather than being erroneously restored as "new" chapters on subsequent syncs.

* chore: change timestamp to use duration-based calculations

* chore: spotless
2026-04-06 13:08:30 -04:00
MediocreLegion eec1236b8b fix(delegate): migrate NH to the v2 api (#1581)
* fix(delegate): migrate NH to the v2 api

* remove extra comment

* remove redundant data

* linting

* Code cleanup

---------

Co-authored-by: Jobobby04 <jobobby04@users.noreply.github.com>
2026-04-03 12:59:13 -04:00
Weblate (bot) ee1e783126 Translations update from Hosted Weblate (#1577)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translation: Mihon/TachiyomiSY

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: ScratchBuild <foobarbuzz@gmail.com>
Co-authored-by: ZenVinny <atdenada@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
2026-04-03 12:50:27 -04:00
renovate[bot] f3ab39cb1f Update dependency net.zetetic:sqlcipher-android to v4.14.1 (#1583)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 12:50:00 -04:00
KaiserBh ba75395648 refactor: improve sync merging categories (#1559)
* 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>
2026-04-03 12:49:37 -04:00
Weblate (bot) fe0b14ab97 Translations update from Hosted Weblate (#1561)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/be/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/be/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ta/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Kehribar <103407696+dpentx@users.noreply.github.com>
Co-authored-by: Lucas Correia <anicetoclucas@gmail.com>
Co-authored-by: lilp <felipegabriel.avila6@gmail.com>
Co-authored-by: nadevko <ormak@protonmail.com>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
2026-03-18 19:55:58 -04:00
renovate[bot] 91d2140288 Update koin to v4.2.0 (#1569)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-18 19:47:20 -04:00
renovate[bot] 0417969dd6 Update dependency net.zetetic:sqlcipher-android to v4.14.0 (#1567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-18 19:47:08 -04:00
AntsyLich 5d8d2ce48a Switch to AndroidX bundled sqlite driver (#3082)
# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/di/AppModule.kt
2026-03-18 19:45:20 -04:00
Mend Renovate b15277f134 Update paging.version to v3.4.2 (#3063) 2026-03-18 19:21:01 -04:00
Mend Renovate 76ca27f681 Update kotlin monorepo to v2.3.20 (#3074) 2026-03-18 19:20:57 -04:00
Mend Renovate 56923c76d4 Update sqldelight to v2.3.2 (#3077) 2026-03-18 19:20:53 -04:00
MajorTanya 32e19736b9 Address bundleOf deprecation (#3073) 2026-03-18 19:20:48 -04:00
Mend Renovate 11b01b2771 Update sqldelight to v2.3.1 (#3071)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2026-03-18 19:20:45 -04:00
Mend Renovate 460ff13e54 Update dependency io.kotest:kotest-assertions-core to v6.1.7 (#3062) 2026-03-18 19:20:42 -04:00
Mend Renovate 57f77c8105 Update moko to v0.26.1 (#3068) 2026-03-18 19:20:39 -04:00
Mend Renovate a2eb22964a Update dependency com.squareup.okio:okio to v3.17.0 (#3070) 2026-03-18 19:20:36 -04:00
Mend Renovate 7158bae26a Update dependency androidx.activity:activity-compose to v1.13.0 (#3065) 2026-03-18 19:20:32 -04:00
Mend Renovate 807ce846d5 Update dependency androidx.core:core-ktx to v1.18.0 (#3067) 2026-03-18 19:20:29 -04:00
Mend Renovate 0b68f2c62a Update dependency androidx.compose:compose-bom to v2026.03.00 (#3066) 2026-03-18 19:20:26 -04:00
AntsyLich b7d6cc8dd0 Add installation id for feature flags (#3052)
# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt
#	app/src/main/java/mihon/core/migration/migrations/Migrations.kt
2026-03-18 19:20:17 -04:00
Mend Renovate 8b1fd30902 Update dependency androidx.compose:compose-bom to v2026.02.01 (#3009) 2026-03-18 19:09:37 -04:00
Mend Renovate aff43f3aeb Update dependency com.google.firebase:firebase-bom to v34.10.0 (#3006) 2026-03-18 19:09:29 -04:00
Mend Renovate 0047d2e5d8 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.3.0 (#3029) 2026-03-18 19:09:22 -04:00
Mend Renovate d87385f5b3 Update dependency com.materialkolor:material-kolor to v5.0.0-alpha07 (#3024) 2026-03-18 19:09:15 -04:00
AntsyLich c17e9573b7 Reapply "Fix cache invalidation isn't done at startup (#2970)"
This reverts commit d219c5e3bbcfb24c40fa69e40bff11b6fd81fd7f.

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt
2026-03-18 19:08:43 -04:00
AntsyLich 9c01119d24 Reapply "Fix thread starvation caused by not yielding or using an inappropriate thread pool (#2955)"
This reverts commit 1d7c838ae64e624d9dd0884722f0c6ae5d18e386.

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/cache/ChapterCache.kt
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2026-03-18 19:06:16 -04:00
Jobobby04 bbc839e234 Lint 2026-02-27 22:44:01 -05:00
Jobobby04 917f20894b Bump version code 2026-02-27 22:08:28 -05:00
Jobobby04 3a3b719b8b Copy last page read in migrate 2026-02-27 22:07:59 -05:00
Jobobby04 1903437ecf Cleanup 2026-02-27 22:07:42 -05:00
Jobobby04 5c26bb3a52 Add recommended proguard rules 2026-02-27 22:07:31 -05:00
Jobobby04 07599ade3a Fix blank page on cloudflare guard 2026-02-27 13:49:26 -05:00
Jobobby04 0a9f36402b Remove migrate button from merged manga 2026-02-27 13:38:28 -05:00
Weblate (bot) d2b325cd02 Translations update from Hosted Weblate (#2997)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon

Co-authored-by: Filip Jaruška <filip.jaruska@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
(cherry picked from commit cc3f640faa7df9f2a64976d2639e6dfd60ebe213)
2026-02-27 13:33:34 -05:00
AntsyLich cdc64aceb7 Fix extension install/update stuck at pending (#3000)
Co-authored-by: p
(cherry picked from commit 84265febf3ce24d71994ced2b81215f858430d4e)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:33:28 -05:00
Mend Renovate 4bfd6e4026 Update dependency io.kotest:kotest-assertions-core to v6.1.4 (#2998)
(cherry picked from commit 171a06a8baccae7fb21d2c60150639941747d90c)
2026-02-27 13:33:01 -05:00
Weblate (bot) 50eebdf7d3 Translations update from Hosted Weblate (#2980)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translation: Mihon/Mihon

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Jakub Szafranek13 Fabijan <jakubfabijan@tuta.io>
Co-authored-by: KraXen <dpelech1@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
(cherry picked from commit 565379779f82ee7dfdad45e251d82ff73dc3b7b2)
2026-02-27 13:32:56 -05:00
AntsyLich f843de28d7 Run automatic library updates even when connected to a VPN (#2996)
Co-authored-by: jeremiejig <3978761+jeremiejig@users.noreply.github.com>
(cherry picked from commit 039471427448347a1c12c39a488a1127a3ea1497)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
2026-02-27 13:32:48 -05:00
Cuong-Tran d250a9a680 Going back now first clears search query on browse extension tab (#2906)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 75b445fa8fd42b882266e27d9b979b22ca37d42a)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:30:07 -05:00
AntsyLich 4130db3920 Add all pages of adjacent chapters in the UI instead of only the first or last three (#2995)
(cherry picked from commit 0cc724108b4f29a3d1d33ac4666a14873460a657)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:29:44 -05:00
Mend Renovate f2cbff04ab Update dependency io.coil-kt.coil3:coil-bom to v3.4.0 (#2992)
(cherry picked from commit 5b85084d0a90b241fdf1d3ad018a27b49db15f12)
2026-02-27 13:29:19 -05:00
AntsyLich 061e9359e8 Fix migration dialog not showing for consecutive prompts from the same screen (#2994)
(cherry picked from commit 8b2d35f3068a3f9c5e1bba77ed825ae51531c91c)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:29:16 -05:00
AntsyLich 73258e9e05 Fix migration's selected sources order not preserved (#2993)
(cherry picked from commit 47816d4b218e6a62ef9fcd3097b6b0b8f2f95b17)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:28:55 -05:00
NarwhalHorns 73e4982ffb Utilize tracker for library duplicate detection (#2978)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 89bbdb17fb4ed1cbe99c14f389940e0f91093a10)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:28:38 -05:00
NarwhalHorns 185cd923c0 Add option for bookmarked chapters to download dropdown (#2891)
(cherry picked from commit 3c6f0f1697ccab055ee7af47da84b2161d406f0c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
2026-02-27 13:28:16 -05:00
NarwhalHorns 3cfc53bf11 Optimize tracked library filter (#2977)
Co-authored-by: NarwhalHorns <onefailedgamer@gamil.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit ab214526c6f24466a0432b5c5c7d254a244cd958)

# Conflicts:
#	CHANGELOG.md
2026-02-27 13:21:29 -05:00
Weblate (bot) 1301acfdb7 Translations update from Hosted Weblate (#2843)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon

Co-authored-by: Ai Ai Ecchi <aiaiecchi9og@gmail.com>
Co-authored-by: Alexandre Dhooge <alexandre.dhooge@zaclys.net>
Co-authored-by: Cuong Tran <cuongtran.tm@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Hualiang <642615676@qq.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Jakub Szafranek13 Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: MuhamadSyabitHidayattulloh <tebepc@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Throw Away <throwawayacc4gulshan@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: clukki <nguyenhuuminh16911@gmail.com>
Co-authored-by: momoehab <momoehab@gmail.com>
Co-authored-by: yumekon <konrad.nowicki91@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
(cherry picked from commit 7c7d35e2c64d4f85b0db431fbe18408698af9c6e)
2026-02-27 13:21:06 -05:00
Cuong-Tran 9d9dbea48d Remove redundant userSelected from selection methods (#2976)
(cherry picked from commit 9867c160f781b52cd297f7b1202cc6963b375df0)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/updates/UpdatesUiItem.kt
2026-02-27 13:19:34 -05:00
Cuong-Tran c1df3eb1d0 Don't wrap an intent-chooser inside another intent-chooser (#2921)
(cherry picked from commit 20c899f2cd83fdd37dfc14d58ded6ae7581d3d65)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
2026-02-27 13:19:12 -05:00
Jobobby04 3154c97aee Fix some build warnings 2026-02-27 13:17:48 -05:00
Mend Renovate ffe1b160de Update moko to v0.26.0 (#2967)
(cherry picked from commit 27749fc583527ab1360594a69ef586a4311c93f5)
2026-02-27 13:10:37 -05:00
Mend Renovate 23272375b7 Update dependency com.google.firebase:firebase-bom to v34.9.0 (#2964)
(cherry picked from commit 2248bdac546914492b0adf75425915b899749900)
2026-02-27 13:10:30 -05:00
Mend Renovate 863b6ee784 Update dependency org.junit.jupiter:junit-jupiter to v6.0.3 (#2963)
(cherry picked from commit 42c7329a9e17ab15c0dc1c1f33eabf54286f9339)
2026-02-27 13:10:25 -05:00
Mend Renovate c4c8d4b9c3 Update dependency androidx.compose:compose-bom to v2026.02.00 (#2962)
(cherry picked from commit 5be5a4e81978954713da6f7faa24cc9956c823e9)
2026-02-27 13:10:18 -05:00
Mend Renovate b2bbbca585 Update dependency androidx.activity:activity-compose to v1.12.4 (#2959)
(cherry picked from commit b924d582f459835f533fa54badbe129eede4388f)
2026-02-27 13:10:12 -05:00
Mend Renovate df3b879cf6 Update kotlin monorepo to v2.3.10 (#2960)
(cherry picked from commit 6f601a18c5beb78a70a94471abc2960fb37199b4)
2026-02-27 13:10:05 -05:00
Mend Renovate 47c4f2cc8c Update paging.version to v3.4.1 (#2961)
(cherry picked from commit 1ff9a5625c442be1c9504df0f0eabdaf24aa2fda)
2026-02-27 13:10:00 -05:00
Luca Auer 905a1c1230 Add missing indexes to improve database query performance (#2950)
(cherry picked from commit cae9fbf3213987e7d263845431dfac10a2ecb3b0)

# Conflicts:
#	data/src/main/sqldelight/tachiyomi/migrations/10.sqm
2026-02-27 13:09:55 -05:00
Mend Renovate bcaf7f6415 Update dependency io.kotest:kotest-assertions-core to v6.1.3 (#2939)
(cherry picked from commit d17976c91068944be1a5cba9a959c3763f589590)
2026-02-27 13:02:50 -05:00
Mend Renovate 4639b3ecc3 Update dependency com.materialkolor:material-kolor to v5.0.0-alpha06 (#2938)
(cherry picked from commit b609166702e0788160a557fa1470c6dd8e585169)
2026-02-27 13:02:44 -05:00
MajorTanya 2034971cc0 Clean up some build warnings (#2929)
* Replace deprecated rememberPlainTooltipPositionProvider

* Remove superfluous when branch

This when is marked as exhaustive.

* Replace deprecated LibrariesContainer call

AboutLibraries now wants us to produce the libraries ourselves.

* Replace deprecated ClipboardManager with Clipboard

Clipboard uses suspend functions, hence the coroutine scope addition.

* Use multi-dollar strs to simplify GraphQL queries

These have been available since Kotlin 2.1.

* Remove various redundant casts & conversions

- WebViewScreenContent: loadingState is in the LoadingState.Loading
  branch, no need to cast at all
- Bangumi: username is not modified, make val
- Kavita: token is already a String
- PagerViewerAdapter: insertPageLastPage is already null-checked
- PagerViewerAdapter: use reified filterIsInstance
- ReaderViewModel: chapter IDs are already Longs
- CloudflareInterceptor: webview is smart-cast to non-null here

* Replace deprecated MenuAnchorType

Literally just a typealias for ExposedDropdownMenuAnchorType anyway.

* OptimizeNonSkippingGroups is enabled by default

* Suppress shadowing warning

This is explicitly intentional according to the KDocs.

* Migrate Context Receivers to Context Parameters

Requires changing the compiler arg, but that is part of the migration:

https://blog.jetbrains.com/kotlin/2025/04/update-on-context-parameters

Apparently, the only visible change is that names are required now.
"_" can be used for anonymous context parameters.

* Fix expression bodies with explicit return

Naming conflict resolved by aliasing.

From 2.4/2.5 onward, these will only be allowed with explicit return
types, or have to be turned into a block body. I opted for the latter
since the function is reasonably dense already.

see: https://youtrack.jetbrains.com/issue/KTLC-288

* Suppress deprecation of non-AutoMirrored icons

We use these arrows for navigation in the Upcoming screen.
I strongly doubt the AutoMirrored versions would make sense for our
use-case.

* Explicitly opt-in to new annotation default rules

affects the following annotated value-parameters:
- Preference.SliderPreference.steps (`@IntRange`)
- ReaderViewModel.State.brightnessOverlayValue (`@IntRange`)
- ReadingMode.iconRes (`@DrawableRes`)
- MigrationListScreenModel.Dialog.Progress.progress (`@FloatRange`)

see: https://youtrack.jetbrains.com/issue/KT-73255
see: https://github.com/Kotlin/KEEP/blob/change-defaulting-rule/proposals/annotation-target-in-properties.md

Warning message was the following:

    This annotation is currently applied to the value parameter only, but in the future it will also be applied to field.
    - To opt in to applying to both value parameter and field, add '-Xannotation-default-target=param-property' to your compiler arguments.
    - To keep applying to the value parameter only, use the '@param:' annotation target.

(cherry picked from commit b543bc089a442c5e93b0fb6c83bc4037740b1eb5)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt
#	core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt
#	core/common/src/main/kotlin/mihon/core/common/archive/ArchiveInputStream.kt
2026-02-27 13:02:31 -05:00
Mend Renovate bb8698b2a6 Update dependency androidx.compose:compose-bom to v2026.01.01 (#2913)
(cherry picked from commit 100cea0757c930b153e50ca2ba52e4c06f14800d)
2026-02-27 12:52:37 -05:00
Mend Renovate cd69b09dd0 Update dependency androidx.work:work-runtime to v2.11.1 (#2914)
(cherry picked from commit e092b4208a0f8476c81ed58a2b0efd3a7c5996cf)
2026-02-27 12:52:29 -05:00
Mend Renovate 462b2164e8 Update paging.version to v3.4.0 (#2916)
(cherry picked from commit 1bf4eff931781eff11e3c1d59ca3747ffb069203)
2026-02-27 12:52:23 -05:00
Mend Renovate fb1a4ad828 Update dependency androidx.activity:activity-compose to v1.12.3 (#2917)
(cherry picked from commit b70edfac58e8e5722a51be398212ac025b818258)
2026-02-27 12:52:17 -05:00
Mend Renovate 3bd89cee26 Update markdown to v0.39.2 (#2923)
(cherry picked from commit 9c0eebb55ceb6a7edc50e414b4be19faf256bcda)
2026-02-27 12:52:11 -05:00
Mend Renovate 6f43e98fff Update dependency io.kotest:kotest-assertions-core to v6.1.2 (#2908)
(cherry picked from commit f6f1d13addea504ff7ed6ec87276d1cfdfcf2013)
2026-02-27 12:52:06 -05:00
Mend Renovate 6feeb4b1ee Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.2.1 (#2909)
(cherry picked from commit 31a9ff261e5e195fa2e27615bae0a86956a3c90a)
2026-02-27 12:52:00 -05:00
Mend Renovate fcfe750fcf Update dependency io.mockk:mockk to v1.14.9 (#2904)
(cherry picked from commit c0a1203541931a9090e6769acdb596c9ea4a011b)
2026-02-27 12:51:55 -05:00
Cuong-Tran 6e314e3643 Fix Add Repo input not taking up the full dialog width (#2816)
(cherry picked from commit 82ffc8efa69cb86229fe8b677f12942c80b88a15)

# Conflicts:
#	CHANGELOG.md
2026-02-27 12:51:48 -05:00
Mend Renovate 487ca49c11 Update serialization.version to v1.10.0 (#2879)
(cherry picked from commit d6e17b04c39c9d800c57d75e29714a51fbf902f8)
2026-02-27 12:51:27 -05:00
Mend Renovate 698abe8667 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.2.0 (#2892)
(cherry picked from commit e6c67003511b601d49bc175b83596568ddfe09d9)
2026-02-27 12:51:20 -05:00
Mend Renovate 13c9daf9a9 Update dependency io.kotest:kotest-assertions-core to v6.1.1 (#2893)
(cherry picked from commit ede2f56bc6531f69553d0f95cf422b7f6d15b90b)
2026-02-27 12:51:14 -05:00
Mend Renovate eb21454d6d Update Gradle to v8.14.4 (#2894)
(cherry picked from commit 2037ec45006b54da0e64b3e07bae4c87e261ee59)
2026-02-27 12:51:07 -05:00
Cuong-Tran 56347e6d52 Fix memoization in manga bottom action menus (#2886)
(cherry picked from commit 533a578bdb438fe4a23e069386a6616c7daedcc4)
2026-02-27 12:50:46 -05:00
MajorTanya 5c085a36e8 Reword download index message (#2874)
I'm tired of people thinking the current wording is an error. Improved wordings welcome, this was just my first decent guess.

(cherry picked from commit 05d90ea4d652cd7ead385ec954e0ae2dc332a012)

# Conflicts:
#	CHANGELOG.md
2026-02-27 12:50:38 -05:00
Mend Renovate 65ab676946 Update dependency io.kotest:kotest-assertions-core to v6.1.0 (#2870)
(cherry picked from commit 49c4d08b22b6a440b93b58bd78280807550d6198)
2026-02-27 12:50:19 -05:00
MajorTanya 1f51569a35 Add Filters to Updates screen (#2851)
* 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
2026-02-27 12:35:44 -05:00
Jobobby04 b0d6e16ca3 Fix build 2026-02-27 11:51:08 -05:00
Mend Renovate 85cf54ccc8 Update dependency com.google.firebase:firebase-bom to v34.8.0 (#2856)
(cherry picked from commit 13975d6f7eea21b3ba4be31736038ef2f855bfea)
2026-02-27 11:46:14 -05:00
Mend Renovate 602df5a729 Update dependency androidx.compose:compose-bom to v2026 (#2853)
(cherry picked from commit e659e90c26814c9a29bf668545b4f10294f3c6b9)
2026-02-27 11:46:08 -05:00
Mend Renovate c8102836ce Update dependency com.materialkolor:material-kolor to v5.0.0-alpha05 (#2849)
(cherry picked from commit 99e6fa3c06e1dc24255a73aa5741a72c82d94d91)
2026-02-27 11:46:02 -05:00
Mend Renovate e641575941 Update markdown to v0.39.1 (#2850)
(cherry picked from commit cf13012629571e2097796b50df238f69e62843b3)
2026-02-27 11:45:49 -05:00
NGB-Was-Taken 83afcee4d1 Fix crash when trying to install/update extensions while shizuku isn't running (#2837)
(cherry picked from commit 4ce249c1a0ee9f3a20d91214fd09145e0924b2e4)

# Conflicts:
#	CHANGELOG.md
2026-02-27 11:45:04 -05:00
MajorTanya 2102e0594e Fix nullability of MAL authors breaking search (#2834)
One of these days I'll get through a tracker change without
nullability problems...

(cherry picked from commit edcf84d9022e7436606a0b8c493c1035888ac60a)
2026-02-27 11:44:38 -05:00
Constantin Piber 14c91da6b3 Add a small increment to chapter number before comparison to fix progress sync issues for Suwayomi (#2675)
Due to a `Float->Double->Float` conversion somewhere inside Mihon, the
tracker sees 2.1 as 2.0999999046325684, which means this filter ignores
the 2.1 chapter (which we just tried to mark as read). This small
epsilon is small enough to never bother any serious usage, but large
enough to ignore any such conversion errors.

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit bd5c4d48f980d2d3dcc1112fe499dba17ef8e507)

# Conflicts:
#	CHANGELOG.md
2026-02-27 11:44:26 -05:00
MajorTanya 46c1c6463a Add authors/artists to MAL search results (#2833)
(cherry picked from commit 51b3ab3fd19bdf6a7c3bd2085104392a9c412622)

# Conflicts:
#	CHANGELOG.md
2026-02-27 11:44:10 -05:00
Weblate (bot) 89a521b836 Translations update from Hosted Weblate (#2806)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ceb/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ceb/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Ahmed TOUCHANE <ahmedtouchane0@gmail.com>
Co-authored-by: Anderhale <anderhale@users.noreply.hosted.weblate.org>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eugene <e.shlyapkin99@gmail.com>
Co-authored-by: Gino Cicatiello <ginocic@gmail.com>
Co-authored-by: Hiroshi <borlonjhayron1119@gmail.com>
Co-authored-by: Luis Antonio <getcyonic+zaorinu@gmail.com>
Co-authored-by: NormalRandomPeople <normal.scribe833@silomails.com>
(cherry picked from commit e6f72000ba62302c3e4817a5f17057e5a8d7eafc)
2026-02-27 11:43:50 -05:00
MajorTanya 65c6ed21ab Optimise MAL search queries by ~11x (#2832)
Previously, the app made one request for the search, and then fired
off 1 request per search result to obtain additional data, such as
each title's synopsis, etc.

However, MAL's search allows field selection during the initial query,
which will return all the data in that first response, avoiding the
massive bunch of requests (and alleviating some pressure on MAL from
our userbase).

By combining the selected fields into one constant, I was able to also
get rid of the MALUserListSearch entirely because it was redundant.
This allows for a unified MALManga->TrackSearch helper, further
reducing complexity.

I got to my "11x" improvement because on page of search results has 10
elements, and this change turns 11 (1+10 for results) requests into 1.

(cherry picked from commit 9bf2d78a421213b1885456f5b54c3286edc539e1)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt
2026-02-27 11:42:54 -05:00
Mend Renovate 1b911e7e15 Update dependency org.junit.jupiter:junit-jupiter to v6.0.2 (#2830)
(cherry picked from commit 89c4e3bb39b7450a9aedcf9d720c74c04cd560ff)
2026-02-27 11:41:41 -05:00
Mend Renovate 0535e41051 Update dependency org.jsoup:jsoup to v1.22.1 (#2826)
(cherry picked from commit 47fe792ddc5a342ecc4685d57143cfb40f0682f7)
2026-02-27 11:41:32 -05:00
AntsyLich 3fc802f837 Remember descriptionAnnotator across composition
Closes #2510

Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
(cherry picked from commit 906d6f3cdbd6f7168d9cdea0c3eb8f9c663a09c2)
2026-02-27 11:41:17 -05:00
AntsyLich 976b5cc03e Cleanup extension screen search query predicate
(cherry picked from commit e059190fabe3cbe8498fc3cec7e39b0350f3c289)
2026-02-27 11:41:10 -05:00
AntsyLich a9fe971337 Switch to M3E ExtendedFloatingActionButton
(cherry picked from commit a39b5a56e853a9c11c0984b0385a2e60b0addc3a)
2026-02-27 11:40:06 -05:00
AntsyLich 5d1dbcb390 Switch to MaterialExpressiveTheme
(cherry picked from commit 3e6afee13b9fd5716f7f2d547b3edcd3e17915db)
2026-02-27 11:28:24 -05:00
AntsyLich 8d11ef3244 Use materilalKolor for monet compat color scheme
(cherry picked from commit 9a11ec8ead41cb7199e10f3c7464790a0bd3b1ad)
2026-02-27 11:28:18 -05:00
Weblate (bot) 724a61f513 Translations update from Hosted Weblate (#1536)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Champ0999 <champ0999@users.noreply.hosted.weblate.org>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Erick Alejandro <erickux@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Luis Antonio <getcyonic+zaorinu@gmail.com>
Co-authored-by: Metin <durmus38metin@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: NormalRandomPeople <normal.scribe833@silomails.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: momoehab <momoehab@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
2026-02-27 11:25:48 -05:00
renovate[bot] 724c774dc9 Update dependency net.zetetic:sqlcipher-android to v4.13.0 (#1544)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 11:21:21 -05:00
renovate[bot] 29e0b2e4a5 Update actions/upload-artifact action to v7 (#1557)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 11:21:12 -05:00
KaiserBh 2776e41127 feat: Add sync events to SyncYomi (#1558)
* feat: Add sync events to SyncYomi

Now it will send the events back to `SyncYomi` server and then forward those to the notifications services that are enabled, such as discord, telegram, and etc.

* chore: fix build error.
2026-02-27 11:20:59 -05:00
Jobobby04 af1f77418f This is SY not Mihon Crashing 2026-02-13 22:41:04 -05:00
MajorTanya c1df5da062 This is SY not Mihon (#1549) 2026-01-31 11:24:37 -05:00
Jobobby04 f8f645772d Crashfix
Co-authored-by: name <arkon@users.noreply.github.com>
2026-01-01 12:26:13 -05:00
Jobobby04 b1e6fa65d6 Or 2025-12-26 23:31:31 -05:00
Jobobby04 01e8c6cc12 Use ComposeStars from RatingBar library. 2025-12-26 14:56:38 -05:00
Jobobby04 b4668c6829 Lint 2025-12-25 17:43:46 -05:00
Jobobby04 08d6c604bc Cleanup 2025-12-25 17:42:40 -05:00
Constantin Piber 02cec06535 Implement automatic removal of downloads on Suwayomi after reading, configurable via extension settings (#2673)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 1263df9d4111511e49a43463c9808060433ce76d)

# Conflicts:
#	CHANGELOG.md
2025-12-25 17:26:02 -05:00
Weblate (bot) ebdb3f7478 Translations update from Hosted Weblate (#2711)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ka/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ka/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Anderhale <anderhale@users.noreply.hosted.weblate.org>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Hasanur Rahman Biplob <hrbiplob10@gmail.com>
Co-authored-by: Jakub Szafranek13 Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Co-authored-by: ابْنُ السَدِيمِ <amarlubs2@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>
(cherry picked from commit c96b6ae562cee1220b9fec74708d447413ab8c35)
2025-12-25 17:25:49 -05:00
Mend Renovate 3724d79825 Update dependency androidx.compose:compose-bom to v2025.12.01 (#2651)
(cherry picked from commit 23c427cf60701e46e470fee8b0a7564804ec599e)
2025-12-25 17:25:46 -05:00
Mend Renovate c3e2eb6672 Update markdown to v0.39.0 (#2804)
(cherry picked from commit e3260d56f713d4f5411ae00dfd3da2aba87f4cf2)
2025-12-25 17:25:39 -05:00
Mend Renovate fa91695add Update aboutlib.version to v13.2.1 (#2803)
(cherry picked from commit f37afbcec9f21823cd894036b6ca7f464eb34481)
2025-12-25 17:25:35 -05:00
MajorTanya e7786bd16f Fix pre-1970 upload date display in chapter list (#2779)
A user in #2777 was using the ComicInfo.xml Year/Month/Day fields to
indicate date of publication for some American comics, which often
predate the UNIX Epoch of 1970.

They were seeing "N/A" displays because this line of code discarded
date information for any time before Jan 1st, 1970.

The `toRelativeString` extension function used in the other
`relativeDateText` function already accounts for very distant dates
(anything >7 days away turns into full date, not relative, regardless
of setting, though disabling the relative timestamp setting
circumvents this with the same result). Removing this line should not
cause any issues as it is purely a display difference and the use case
of backdating comics to pre-1970 is worth it in my opinion.

(cherry picked from commit 7a1c8a1b61e07d2e1a402b5daf0e7c04c232f655)

# Conflicts:
#	CHANGELOG.md
2025-12-25 17:25:31 -05:00
Mend Renovate 3d70476b9f Update dependency androidx.activity:activity-compose to v1.12.2 (#2797)
(cherry picked from commit 532b5cf290b448814ce5370bde461d9d5c8f086a)
2025-12-25 17:25:07 -05:00
Mend Renovate e74e0de8f5 Update kotlin monorepo to v2.3.0 (#2794)
(cherry picked from commit 3cb1b2e17a5f77d6133e6bf244304c2d6719aa04)
2025-12-25 17:24:59 -05:00
Luca Auer a2f552d6d2 Minimize memory usage by reducing in-memory cover cache size (#2266)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 4c9cfd8da5f9c67daa4b6401a910f979fd79179f)

# Conflicts:
#	CHANGELOG.md
2025-12-25 17:24:53 -05:00
AntsyLich a6bd0bbd2a Fix reader not saving read duration when changing chapter (#2784)
(cherry picked from commit 2e0786f699cc6d4863eb20331739c8325a451e63)

# Conflicts:
#	CHANGELOG.md
2025-12-25 17:24:36 -05:00
Mend Renovate fd42bba188 Update dependency com.google.firebase:firebase-bom to v34.7.0 (#2782)
(cherry picked from commit e7e4d9b6b35033a0568f40e32e94aaf336c96c39)
2025-12-25 17:24:06 -05:00
AntsyLich a0ec735066 Use AGP provided NDK and Build Tools version
(cherry picked from commit 5fe7dd9f0612412afabd7646f89ba38b230fb7e7)

# Conflicts:
#	buildSrc/src/main/kotlin/mihon/buildlogic/AndroidConfig.kt
2025-12-25 17:23:59 -05:00
Mend Renovate 89f5fce19d Update dependency com.android.tools.build:gradle to v8.13.2 (#2780)
(cherry picked from commit 4cb05cc738862be52c5f53e43c943f20712c6153)
2025-12-25 17:23:18 -05:00
Jobobby04 bf711a995c Fix build 2025-12-25 17:23:01 -05:00
AntsyLich d977614b7a Update tracker icons (#2773)
(cherry picked from commit 876c3f951b7e9782054d8f788ab39772ae6cf440)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt
2025-12-25 17:22:53 -05:00
Mend Renovate d282df6973 Update dependency androidx.activity:activity-compose to v1.12.1 (#2760)
(cherry picked from commit 08a61a42e9b01f5591615e298c2fecc9f59762ac)
2025-12-25 16:55:40 -05:00
Mend Renovate db5b3a69cc Update dependency io.mockk:mockk to v1.14.7 (#2771)
(cherry picked from commit cadd36ad9a5721d19ea51b68910b8b3276965b3d)
2025-12-25 16:55:35 -05:00
Mend Renovate c70c5dff25 Update dependency io.kotest:kotest-assertions-core to v6.0.7 (#2749)
(cherry picked from commit 556371e1c89bfb0961b63629e79d3fed6a8e7999)
2025-12-25 16:55:24 -05:00
AntsyLich 25ace80419 Cleanup BaseOAuthLoginActivity and TrackLoginActivity (#2748)
(cherry picked from commit c222a28bd14c989b6fa0d53d7497bf063887c9ec)
2025-12-25 16:55:13 -05:00
Jobobby04 b8b468cea7 Minor fixes 2025-12-25 16:49:01 -05:00
NGB-Was-Taken 0ffc798e9a Add preference to toggle chapter URL hash for downloads (#1533) 2025-12-25 16:47:56 -05:00
renovate[bot] ad5a76741a Update actions/upload-artifact action to v6 (#1530)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-25 16:46:49 -05:00
Weblate (bot) 003c5ad39a Translations update from Hosted Weblate (#1529)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Gino Cicatiello <ginocic@gmail.com>
Co-authored-by: Hiroshi <borlonjhayron1119@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: MuhamadSyabitHidayattulloh <tebepc@gmail.com>
Co-authored-by: Nataniel Dika Kurniawan <hikawaart2@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
2025-12-25 16:46:06 -05:00
NGB-Was-Taken 582d0ef121 Add handling for previously unhandled preferences (delegated MD) (#1524)
* Include romanized titles of the original language in description

* Implement handling for `finalChapterInDesc` preference.

* Handle `preferExtensionLangTitle` preference when fetching manga details.

* Address some warnings, clean up unused code and spotless apply.
2025-12-11 13:58:56 -05:00
NGB-Was-Taken 5566db160b fix deletion of duplicate downloaded chapters when automatically marked as read (#1500) 2025-12-11 13:56:57 -05:00
renovate[bot] 6fb6838656 Update actions/checkout action to v6 (#1522)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:48:09 -05:00
renovate[bot] 1e5d490c22 Update actions/upload-artifact action to v5 (#1513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:48:02 -05:00
renovate[bot] 276aeb0f59 Update gradle/actions action to v5 (#1508)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:47:56 -05:00
renovate[bot] c62d9d1446 Update actions/github-script action to v8 (#1497)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:47:44 -05:00
renovate[bot] 4ff18364d9 Update actions/setup-java action to v5 (#1493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:47:36 -05:00
renovate[bot] 6c8e4e951a Update dependency net.zetetic:sqlcipher-android to v4.12.0 (#1485)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:47:28 -05:00
renovate[bot] dc1fde628d Update koin to v4.1.1 (#1466)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 13:47:09 -05:00
Weblate (bot) 241b70e5ce Translations update from Hosted Weblate (#1465)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/hu/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Acelith <joel.jon@moix.me>
Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Anderhale <anderhale@users.noreply.hosted.weblate.org>
Co-authored-by: Champ0999 <champ0999@users.noreply.hosted.weblate.org>
Co-authored-by: Conrad Mateman <conradmateme001@gmail.com>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Deleted User <noreply+48943@weblate.org>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Dika <hikawaart2@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: João Sousa <joaopsousa99@gmail.com>
Co-authored-by: Karley <siegitsi@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: MajorTanya <github@majortanya.eu>
Co-authored-by: Manjul Tamrakar <manjultamrakar4@gmail.com>
Co-authored-by: Manuela Silva <mmsrs@sky.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mohamed kh <mohamedkhamekhami@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Omgeta <anooptiger@hotmail.com>
Co-authored-by: Rahim Kansous <rahimkansous18@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: WarriorDan <Danpgl@live.it>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: dianisaac <muhandreop@gmail.com>
Co-authored-by: f_pluz <pedroh.lobo20@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Đào Ngọc Đang Khoa <daongocdangkhoa2510@gmail.com>
Co-authored-by: ابْنُ السَدِيمِ <amarlubs2@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
2025-12-11 13:46:18 -05:00
Jobobby04 64c755ddf3 Lint 2025-12-05 13:45:55 -05:00
Jobobby04 3ae6c0131b Lanraragi delegation 2025-12-05 13:44:58 -05:00
NGB-Was-Taken e3b43de298 Spotless apply 2025-11-26 18:41:48 +05:45
AntsyLich 02ff6b4e2f Fix mass migration not using the same search queries as individual migration (#2736)
(cherry picked from commit 7161bc2e825bdfd66a1829f7dce42bd0570b1008)
2025-11-26 15:06:06 +05:45
NGB-Was-Taken ee8379b12a Fix shizuku installer not updating installed extensions (#2697)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit c3d858a5613a133352f6b140916d05de7f752771)
2025-11-26 15:05:26 +05:45
Mend Renovate 20e1cc0a7d Update dependency com.pinterest.ktlint:ktlint-cli to v1.8.0 (#2708)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 13552c5ffa796aa9bf5db5e12c758a4b3763bf2b)
2025-11-26 15:02:17 +05:45
Mend Renovate 78b434e794 Update dependency androidx.activity:activity-compose to v1.12.0 (#2725)
(cherry picked from commit e6ca458e1f4cad3786d685ce8412ad40aed5155d)
2025-11-26 14:59:51 +05:45
Mend Renovate 52c8b260e0 Update moko to v0.25.2 (#2723)
(cherry picked from commit 05c7df2ed32b429f1ed3f1425e854c1867813a21)
2025-11-26 14:59:51 +05:45
Mend Renovate cccdc99977 Update sqlite to v2.6.2 (#2724)
(cherry picked from commit 4a3339a21f479bd57a7765cbeb092674aa2e8507)
2025-11-26 14:59:51 +05:45
Mend Renovate ca15d2ccc5 Update lifecycle.version to v2.10.0 (#2726)
(cherry picked from commit 6f497ed03181b15cb79899c689ffe70353656f0b)
2025-11-26 14:59:51 +05:45
Jobobby04 b7b0ffc885 Remove old SmartSearch 2025-11-20 13:20:53 -05:00
Mend Renovate f1a57749c4 Update dependency com.squareup.okio:okio to v3.16.4 (#2716)
(cherry picked from commit c17fc6792a3b8a5b6f31c107f165bfcda44617ae)
2025-11-20 12:53:57 -05:00
Mend Renovate 26d6c09d21 Update dependency io.kotest:kotest-assertions-core to v6.0.5 (#2717)
(cherry picked from commit 9e27ae3d2b63210714d6b16add687d2b37a34736)
2025-11-20 12:53:51 -05:00
Mend Renovate 088e3b6800 Update okhttp monorepo to v5.3.2 (#2720)
(cherry picked from commit 8b5dd39f1cbfd2eb8dd09cf42757206eeba631f7)
2025-11-20 12:53:45 -05:00
Mend Renovate c8ee2dbff4 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8.1.0 (#2721)
(cherry picked from commit 8d81c94679e4ecc9e452b03feb7c08f524a4969d)
2025-11-20 12:53:39 -05:00
Mend Renovate 835a21b426 Update dependency com.google.firebase:firebase-bom to v34.6.0 (#2707)
(cherry picked from commit e5a693f224190a662f2192a06fd12ae2a03e7dc3)
2025-11-20 12:53:32 -05:00
Mend Renovate 8d67c87639 Update okhttp monorepo to v5.3.1 (#2712)
(cherry picked from commit 7947e1bd6a7bdd99fe6badde8b665da24f92ab7c)
2025-11-20 12:53:24 -05:00
Jobobby04 73cd25e8ba Remove unused migration preferences 2025-11-20 12:50:33 -05:00
Jobobby04 e9ed861f00 Minor cleanup 2025-11-20 12:49:42 -05:00
Jobobby04 e7c1d4deef Minor cleanup 2025-11-20 12:38:09 -05:00
Jobobby04 b8eb75fc68 Throttle E-Hentai requests 2025-11-20 12:37:37 -05:00
NGB-Was-Taken 3d34f3dd2f Exclude MergedSource from MigrationConfigScreen 2025-11-17 08:49:15 +05:45
NGB-Was-Taken 01dc277877 Replace topbar in ReaderAppBars with ReaderTopBar 2025-11-16 20:35:50 +05:45
NGB-Was-Taken b809ae5c6f Optimize imports 2025-11-16 18:48:51 +05:45
NGB-Was-Taken 4c563122f8 Spotless apply 2025-11-16 18:14:20 +05:45
NGB-Was-Taken 4c1124fdb0 Fix compile time errors and make it build 2025-11-16 18:07:44 +05:45
NGB-Was-Taken bdbaecd975 Fix queries and mappers to work with updated views 2025-11-16 18:07:44 +05:45
Mend Renovate 2b8641c1dd Update dependency com.squareup.okio:okio to v3.16.3 (#2709)
(cherry picked from commit cab729c9396d54c98b1e8c4716b93814016deab4)
2025-11-16 18:07:44 +05:45
Mend Renovate f1a90000b2 Update dependency app.cash.sqldelight:sqlite-3-38-dialect to v2.2.1 (#2703)
(cherry picked from commit f6a95a741667871df34288bdb6b67cafe2f79d54)
2025-11-16 18:07:44 +05:45
Weblate (bot) 3bd0f0b447 Translations update from Hosted Weblate (#2687)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/am/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ms/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Anderhale <anderhale@users.noreply.hosted.weblate.org>
Co-authored-by: Anderhale <safwanistaken@gmail.com>
Co-authored-by: Ardiansyahset <ardiantozep@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: MajorTanya <github@majortanya.eu>
Co-authored-by: NGB-Was-Taken <76197326+NGB-Was-Taken@users.noreply.github.com>
Co-authored-by: amigo browser <juniperforest1@proton.me>
(cherry picked from commit 32db0a5f4c261062883a11f86b7091f654bff568)
2025-11-16 18:07:44 +05:45
NGB-Was-Taken cb5b618266 Stop tap zones from triggering when scrolling is stopped by tapping (#2680)
(cherry picked from commit 2ec67ac0c1831a68d8d73e2679f8c98a5a48acf5)
2025-11-16 18:07:44 +05:45
Mend Renovate c71c07690a Update sqldelight to v2.2.1 (#2704)
(cherry picked from commit b1b79a63f0ec570ba2eac41f8faa50ecf7301e5d)
2025-11-16 18:07:44 +05:45
Mend Renovate d85d77da01 Update dependency com.android.tools.build:gradle to v8.13.1 (#2685)
(cherry picked from commit ec99ab3aef734e8b9ce156fe7493f72e7a8cc03a)
2025-11-16 18:07:44 +05:45
Weblate (bot) 164d7bc70f Translations update from Hosted Weblate (#2676)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/am/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bg/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ceb/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/da/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/gl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/he/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/lt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/lv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ms/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sah/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sq/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/th/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Gino Cicatiello <ginocic@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: MajorTanya <github@majortanya.eu>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: NGB-Was-Taken <76197326+NGB-Was-Taken@users.noreply.github.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>

(cherry picked from commit 84d620978bbc5a4698787f5ab81686e7e60767c9)
2025-11-16 18:07:44 +05:45
AntsyLich db51b09f80 Revert "Fix reader tap zones triggering after scrolling was stopped by the user" (#2670)
(cherry picked from commit 412815af067cdf343a6b5c7b5cd38eeb8190d543)
2025-11-16 18:07:44 +05:45
Weblate (bot) 5f8d03ba9b Translations update from Hosted Weblate (#2656)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/jv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Doministo <doministo@seznam.cz>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Nataniel Dika Kurniawan <hikawaart2@gmail.com>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: amigo browser <juniperforest1@proton.me>

(cherry picked from commit f7fb68692a7c41f9f09721dde8db574df1fde1ce)
2025-11-16 18:07:44 +05:45
AntsyLich 4cae7b27a6 Fix extra padding appearing in reader after user interactions (#2669)
(cherry picked from commit aa300cb53ea3a02b63c3b3f3fca60d5e7533a8f1)
2025-11-16 18:07:44 +05:45
Trevor Paley edcf939611 Improve WebView multi-window UX (#2662)
- Navigation history for lower windows is preserved when a popup is opened
- Back gesture will close a popup window rather than the entire WebView activity when there is no previous page
- The leftmost close button closes the entire activity as before
- When a popup window is shown, a new button appears to close just that window

(cherry picked from commit 855eea2ada8c09404dee99a965325913b246618f)
2025-11-16 18:07:44 +05:45
Mend Renovate 208d291b3c Update dependency androidx.core:core-splashscreen to v1.2.0 (#2661)
(cherry picked from commit f4703ed83a32afe1d39669f4988233c1fe7c3f32)
2025-11-16 18:07:44 +05:45
NGB-Was-Taken 19f049189a Fix flaky migration tests (#2663)
(cherry picked from commit 506d51a007e730594e4e5f05f00b4f94c4f24e05)
2025-11-16 18:07:44 +05:45
AntsyLich c855276555 Revert "Update dependency androidx.compose:compose-bom to v2025.10.01 (#2522)"
This reverts commit e8bdf58530cdfd6d530ea9a282785bd313e69be4.

(cherry picked from commit ace387f8bf8f451887b8055213be78312a5b4ea7)
2025-11-16 18:07:43 +05:45
Weblate (bot) 9e244e0889 Translations update from Hosted Weblate (#2646)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/jv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ms/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nataniel Dika Kurniawan <hikawaart2@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
(cherry picked from commit 5e428071c9a12bc637cbfcf235a33dc19cdef197)
2025-11-16 18:07:43 +05:45
AntsyLich bf7a067908 Fix long strip reader not scrolling on consecutive taps (#2650)
(cherry picked from commit 0acd80dd95094a837c8dc05f3fc29ef3e69bdc21)
2025-11-16 18:07:43 +05:45
bapeey 67c4b71b88 Fix WebView crash introduced in v0.19.2 (#2649)
(cherry picked from commit bdb0ce4779d565fc528e97bd38133a72ff3c1724)
2025-11-16 18:07:43 +05:45
Mend Renovate 1fa8a86cce Update dependency androidx.compose:compose-bom to v2025.10.01 (#2522)
(cherry picked from commit e8bdf58530cdfd6d530ea9a282785bd313e69be4)
2025-11-16 18:07:43 +05:45
Weblate (bot) 73eb98960f Translations update from Hosted Weblate (#2639)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translation: Mihon/Mihon

Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
(cherry picked from commit e36b4ce60b2b7141c5b6a4205e98853a0d07438b)
2025-11-16 18:07:43 +05:45
AntsyLich 59704221b7 Migrated to the Android specific about libraries gradle plugin
(cherry picked from commit 6d543024a32bba3136841a19942bed4ea8f0736b)
2025-11-16 18:07:43 +05:45
AntsyLich 19c23943ec Handle reader cutout setting with Insets to support Android 15+ (#2640)
(cherry picked from commit 0e0b6d92833f8e4f3aebdcc1f7c8c175084175d6)
2025-11-16 18:07:43 +05:45
Weblate (bot) d068559dee Translations update from Hosted Weblate (#2373)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/jv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ms/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/jv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ko/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ms/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/th/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Efe Akın <efeakin1122@gmail.com>
Co-authored-by: Evan Jones (原文轩) <evanjones1883@gmail.com>
Co-authored-by: Farith <mail2@farithadnan.net>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <167056923+itsmechinmoy@users.noreply.github.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Madddog1997 <madddog1997@gmail.com>
Co-authored-by: Manjul Tamrakar <manjultamrakar4@gmail.com>
Co-authored-by: Manuela Silva <mmsrs@sky.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mohamed kh <mohamedkhamekhami@gmail.com>
Co-authored-by: MuhamadSyabitHidayattulloh <tebepc@gmail.com>
Co-authored-by: Nataniel Dika Kurniawan <hikawaart2@gmail.com>
Co-authored-by: Omgeta <anooptiger@hotmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: Throw Away <throwawayacc4gulshan@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: keegang 6705 <darunphobwi@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: 안세훈 <on9686@gmail.com>

(cherry picked from commit 860955389661ce35d37f499efdd27259b93d8e56)
2025-11-16 18:07:43 +05:45
AntsyLich 8e6b5b8bee Make reader edge-to-edge (#1908)
(cherry picked from commit 5f0c4606681cd59b38ae0855c7827e149fa5488c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
#	app/src/main/java/eu/kanade/presentation/reader/ReaderPageIndicator.kt
#	app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt
#	app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderBottomBar.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2025-11-16 18:07:43 +05:45
Naputt1 c99ddbe10f Fix reader tap zones triggering after scrolling was stopped by the user (#2518)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit ac28b6c80cee7605052299d6f5f43bc588f701d8)
2025-11-16 18:07:43 +05:45
Constantin Piber 23925c4ba6 Update Suwayomi tracker to use GraphQL API instead of REST API (#2585)
(cherry picked from commit cc2877673539db779af00fbefab3802ac52a7719)
2025-11-16 18:07:43 +05:45
Trevor Paley e71f0afd99 Added proper multi window support in WebView instead of treating everything as a redirect (#2584)
(cherry picked from commit 6ab87c793122165f98c36b4b7d9158069ea40f5a)
2025-11-16 18:07:43 +05:45
Kashish Aggarwal 014bf97248 Fix date picker not allowing the same start and finish date in negative time zones (#2617)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 8662f80fbf6b7c3aee4945bf656def8341cfdfd3)
2025-11-16 18:07:43 +05:45
anirudhn fc0d666366 Fix scrollbar not showing when animator duration scale animation is turned off (#2398)
(cherry picked from commit 09ec9fc8c54e126692ae68ff260058f3be46a5dd)
2025-11-16 18:07:43 +05:45
c2y5 eb7465e6f9 Fix extension download stuck at pending state in some cases (#2483)
Also auto update extension list whenever a repository is added or removed

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 87c6f34a558b009be4d316e396ec3eeb4cfbbbf8)
2025-11-16 18:07:43 +05:45
AntsyLich ff6ad20a77 Add option to customize concurrent downloads, increase page concurrency (#2637)
(cherry picked from commit 643762f91325a460c74398d472a555fb00ed9f63)
2025-11-16 18:07:43 +05:45
Mend Renovate 17c528a206 Update markdown to v0.38.1 (#2636)
(cherry picked from commit 7e880014b0f2c42bc430765a19068d93640ce603)
2025-11-16 18:07:43 +05:45
AntsyLich 63f4034a7f Add subtitle support to slider preference and general cleanup (#2635)
(cherry picked from commit f36c259c1faf2ee4a108fd98a5d27d93014ba34c)
2025-11-16 18:07:43 +05:45
AntsyLich 6c1bfc2177 Fix reader "Unable to edit key" error (#2634)
(cherry picked from commit aef3beb15fb2d4acbde9cb2ea4c5f639606d9fc8)
2025-11-16 18:07:43 +05:45
NGB-Was-Taken 45ff1f06ba Update shizuku.version to v13.1.5 (#2566)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit e9469451acf6c7ad39ff08e344ad5013ddc39337)
2025-11-16 18:07:43 +05:45
AntsyLich 3e287a593a Bump app version code and default user agent
(cherry picked from commit f9793d33233ceb7729fa9cfe5ae55b45a372c54c)
2025-11-16 18:07:43 +05:45
AntsyLich 01420154be Fix migration "Attempt to invoke virtual method" crash (#2632)
(cherry picked from commit 93ba6acea56334573fc506d593affd5bea2a86b2)
2025-11-16 18:07:43 +05:45
AntsyLich 1e4c596d0e Fix migration dialog migrating to wrong entry (#2631)
(cherry picked from commit 5e7fecc2c11b4a175fe1c3f698f7daeb58fe311f)
2025-11-16 18:07:43 +05:45
Mend Renovate 26cb2bbbd1 Update dependency org.junit.jupiter:junit-jupiter to v6.0.1 (#2630)
(cherry picked from commit 343074da5f7b5b6b2bb8116cc65348684d4bf615)
2025-11-16 18:07:43 +05:45
AntsyLich 588db79a64 Fix mass migration advanced search query building (#2629)
(cherry picked from commit 7c08b75555a5444ede4912dc5e32607fac2b9678)
2025-11-16 18:07:43 +05:45
Constantin Piber e5aaf3b31f Migrate Kitsu to use library_id and remote_id properly (#2609)
(cherry picked from commit cbf72f4c60cb85f29f8446ba1adb1cfd29d38a59)

# Conflicts:
#	CHANGELOG.md
#	data/src/main/sqldelight/tachiyomi/migrations/8.sqm
2025-11-16 18:07:43 +05:45
Mend Renovate 9c222b128b Update okhttp monorepo to v5.3.0 (#2628)
(cherry picked from commit 0b6de39f2f878f1188a4fc1ea989517bad38e6ca)
2025-11-16 18:07:43 +05:45
Mend Renovate c66e08d43e Update plugin google-services to v4.4.4 (#2573)
(cherry picked from commit 72c4d1fdee981ca0bc94cd32d0a43bb739f43a61)
2025-11-16 18:07:43 +05:45
Mend Renovate 493d8fc45f Update dependency androidx.work:work-runtime to v2.11.0 (#2626)
(cherry picked from commit 3ff25bc984717052b57484859283c96583d152b2)
2025-11-16 18:07:43 +05:45
Mend Renovate 47993cb55d Update dependency com.squareup.okio:okio to v3.16.2 (#2576)
(cherry picked from commit e9224bc2ba19a5a78dd16c30615f2cae5b02ba5d)
2025-11-16 18:07:43 +05:45
Mend Renovate 4701cbea23 Update dependency com.google.firebase:firebase-bom to v34.5.0 (#2575)
(cherry picked from commit 5ac58d01b82daae809139ccb4245802816d23ff8)
2025-11-16 18:07:43 +05:45
Mend Renovate 70efd6f2bf Update xml.serialization.version to v0.91.3 (#2625)
(cherry picked from commit eefaf028ce7bca41d25f77c73e44a1f36af8703a)
2025-11-16 18:07:43 +05:45
Mend Renovate b85b6a713c Update kotlin monorepo to v2.2.21 (#2624)
(cherry picked from commit 582ccca1ab327864e72fff0fe05da6757584c280)
2025-11-16 18:07:43 +05:45
Mend Renovate 6291529a10 Update dependency io.kotest:kotest-assertions-core to v6.0.4 (#2594)
(cherry picked from commit 8f972115a82cda8619577e22465a047c2a863a1a)
2025-11-16 18:07:43 +05:45
Mend Renovate 160907ab52 Update aboutlib.version to v13 (major) (#2580)
Update aboutlib.version to v13

(cherry picked from commit 6f6c0338110e0fdd16cfc997981a21b6ed4859bc)
2025-11-16 18:07:43 +05:45
Mend Renovate bccd30a80f Update okhttp monorepo to v5.2.1 (#2577)
(cherry picked from commit 57a0ab67112d1966c00d7ec433a2cff70064495e)
2025-11-16 18:07:43 +05:45
Radon Rosborough ef4d3e6c4d Improve handling of downloads for chapters with same metadata and optionally for OSes that don't support Unicode in filename (#2305)
Co-authored-by: jkim <jhskim@hotmail.com>
Co-authored-by: fatotak <111342761+fatotak@users.noreply.github.com>
Co-authored-by: MajorTanya <39014446+MajorTanya@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 58b25d697f7987e9888344e815d5646ec010a663)
2025-11-16 18:07:43 +05:45
Mend Renovate 4fe7a1375a Update okhttp monorepo to v5.2.0 (#2564)
(cherry picked from commit 1a31c7c7ee31eee19030875d11ec1f31eab895a4)
2025-11-16 18:07:43 +05:45
NGB-Was-Taken 02bc195068 Fix disabling incognito mode from notification (#2512)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 96e5131358110079587d262d37ec346e10941758)
2025-11-16 18:07:43 +05:45
Mend Renovate 1e20913237 Update dependency com.google.firebase:firebase-bom to v34.3.0 (#2508)
(cherry picked from commit 1d5bc8d2c2e3cb6df56561782e2e2842af3eaa50)
2025-11-16 18:07:43 +05:45
Mend Renovate 48b488fa59 Update dependency org.junit.jupiter:junit-jupiter to v6 (#2553)
(cherry picked from commit 9a45d248b1545ec192b4d5cff9b0756d0a7a12dd)
2025-11-16 18:07:43 +05:45
Mend Renovate 893f3b2e34 Update moko to v0.25.1 (#2550)
(cherry picked from commit 04168ecec84a3e2b470468002c05bbe9e5e538b5)
2025-11-16 18:07:43 +05:45
Mend Renovate 25be12852f Update dependency io.mockk:mockk to v1.14.6 (#2549)
(cherry picked from commit 607f0ea9cd08c070323c4c1a46efec53dc4b1358)
2025-11-16 18:07:43 +05:45
Secozzi 4f0292b000 Update markdown to 0.37.0 (#2516)
(cherry picked from commit 27a4f6f45c0ba639450428f5f58b1c938fe3032e)
2025-11-16 18:07:43 +05:45
Mend Renovate f669fd9205 Update kotlin monorepo to v2.2.20 (#2498)
(cherry picked from commit 5236d003d27d2aaa8a4baaa8aa4dfc0c8b299fea)
2025-11-16 18:07:43 +05:45
Mend Renovate c3e0646b61 Update dependency androidx.work:work-runtime to v2.10.5 (#2523)
(cherry picked from commit d61a41e8192786c8bb958652098a704d79ad5f5d)
2025-11-16 18:07:43 +05:45
Mend Renovate 0d2cad8693 Update sqlite to v2.6.1 (#2525)
(cherry picked from commit 5637860dd2ed637223014433e1e6005885af10a1)
2025-11-16 18:07:43 +05:45
Mend Renovate 237916a37b Update dependency com.diffplug.spotless:spotless-plugin-gradle to v8 (#2526)
(cherry picked from commit d4d18d0898d7fec07e6021e60481948a40b162ad)
2025-11-16 18:07:43 +05:45
Guzmazow 16653f9585 Improve spoofing of X-Requested-With header to support newer WebView versions (#2491)
(cherry picked from commit 065147472e8e683c47d11f3e00386aba2a7c1bac)
2025-11-16 18:07:43 +05:45
Constantin Piber 392b1009c9 Delegate Suwayomi tracker authentication to extension (#2476)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 6f635782c22cc0844caa4e4d88cf390005989b0b)
2025-11-16 18:07:43 +05:45
Mend Renovate 10c184e58a Update lifecycle.version to v2.9.4 (#2503)
Update dependency androidx.lifecycle:lifecycle-process to v2.9.4

(cherry picked from commit 86d85f74c097b8b52eb6a91887a055c92e1066f5)
2025-11-16 18:07:43 +05:45
Mend Renovate f6b8756dc0 Update sqlite to v2.6.0 (#2504)
(cherry picked from commit 29e6a2c4a6a32deae4c067c51b7e863b8f8128bb)
2025-11-16 18:07:43 +05:45
Mend Renovate f2654807a4 Update dependency androidx.core:core-ktx to v1.17.0 (#2402)
(cherry picked from commit 60c66bbd3a12e48bff52257c27d6b868e97da1d7)
2025-11-16 18:07:43 +05:45
Mend Renovate ab90b75d73 Update dependency androidx.activity:activity-compose to v1.11.0 (#2499)
(cherry picked from commit 060e5b2e2e8ad85886c4d3362ba1ae56fac52f79)
2025-11-16 18:07:43 +05:45
AntsyLich 0b58a081af Replace compose-stable-marker with compose-runtime-annotation
(cherry picked from commit 4ac9fcd4d3ff2eed59d9c8454d7463b7c9e6dda6)
2025-11-16 18:07:43 +05:45
AntsyLich ae98a5fe58 Bump compile and target sdk
(cherry picked from commit d3b7f7e55ff6609a2cddf1765205ba35c6c26b83)
2025-11-16 18:07:43 +05:45
Mend Renovate 74fa4e3503 Update dependency com.google.firebase:firebase-bom to v34.2.0 (#2376)
(cherry picked from commit 0d926626a1916783b67b3ae8cd2142aa90120e30)
2025-11-16 18:07:43 +05:45
Mend Renovate c20b0f67a8 Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.4.1 (#2496)
(cherry picked from commit 6495a2ea430c82a8481b10ef345669d8ff915cac)
2025-11-16 18:07:43 +05:45
Mend Renovate 098c7196de Update dependency androidx.work:work-runtime to v2.10.4 (#2497)
(cherry picked from commit 94f711ba2a67d0da52ba26978f5c4a103abc7f69)
2025-11-16 18:07:43 +05:45
Mend Renovate 99a25560c1 Update dependency androidx.compose:compose-bom to v2025.09.00 (#2401)
(cherry picked from commit 9f5c4e03b23dab80051afa458361ce62133febbf)
2025-11-16 18:07:43 +05:45
Mend Renovate 79d19a2d8b Update lifecycle.version to v2.9.3 (#2447)
(cherry picked from commit 49562e1915108ac28fa3308d4eed319bb9ed61d5)
2025-11-16 18:07:43 +05:45
Mend Renovate 061d0809bd Update dependency org.jsoup:jsoup to v1.21.2 (#2438)
(cherry picked from commit 57c82b30bab20110832eecc4a825441708eaa02b)
2025-11-16 18:07:43 +05:45
Mend Renovate 0ce0c45cc7 Update dependency io.kotest:kotest-assertions-core to v6.0.3 (#2439)
(cherry picked from commit e573f72cfd5b6c66709ba948ce29c7246a9832e8)
2025-11-16 18:07:43 +05:45
Mend Renovate e910362b16 Update dependency com.android.tools.build:gradle to v8.13.0 (#2449)
(cherry picked from commit bd90307df9ca2f0d424483b29c0dd640eabc0f5f)
2025-11-16 18:07:43 +05:45
Secozzi 96c05bf113 Fix migration progress not updating and category flag mischeck (#2484)
- Fixed an issue where migration progress wasn't updated after a manual source search
- Fixed incorrect logic where the category migration flag was ignored due to checking the chapter flag instead

(cherry picked from commit 16b5317b90b3064d12aa38f687cc30110fd8cdb3)
2025-11-16 18:07:43 +05:45
Mend Renovate 6d2bda5c9d Update plugin firebase-crashlytics to v3.0.6 (#2374)
(cherry picked from commit 83f4b486296f6998efc8ef95fa9d58b75e5de130)
2025-11-16 18:07:43 +05:45
Mend Renovate 4a080fba3f Update dependency com.github.skydoves:compose-stable-marker to v1.0.7 (#2428)
(cherry picked from commit 85f5e5019e59a178f24c93c71644b1c4a08549f3)
2025-11-16 18:07:43 +05:45
AntsyLich ac5b3b164f Bump targetSdk to 35
(cherry picked from commit 4bc3b9f3b6fc87a9285ad3ca1aa8c81d8269d373)
2025-11-16 18:07:43 +05:45
Mend Renovate c43d7dbb31 Update dependency com.android.tools.build:gradle to v8.12.1 (#2417)
(cherry picked from commit feda4101525163c3978a2eb9ab934f9c4db1e873)
2025-11-16 18:07:43 +05:45
Mend Renovate d218fdfcf4 Update dependency sh.calvin.reorderable:reorderable to v3 (#2419)
(cherry picked from commit 200c2df5ba72a39c4116d14827d54a126b77cdc7)
2025-11-16 18:07:43 +05:45
Mend Renovate e59af2fd1f Update dependency io.kotest:kotest-assertions-core to v6 (#2416)
(cherry picked from commit be09cddde2f0799e7eff0003f9dacdb5a6e09947)
2025-11-16 18:07:43 +05:45
AntsyLich 3d761b5bf4 Switch to a fork of QuickJS Java
(cherry picked from commit 498317de52c119a08daaa8d38f3f7d859e7b4990)
2025-11-16 18:07:43 +05:45
Mend Renovate 1892101359 Update kotlin monorepo to v2.2.10 (#2404)
(cherry picked from commit 33b876edc6cd20c73682a165359bec1268aa1199)
2025-11-16 18:07:43 +05:45
Secozzi d76d25379e Don't hardcode app name in strings.xml (#2394)
(cherry picked from commit 3d3c36078a3b8cb741adffd46931aeab9cb38578)
2025-11-16 18:07:43 +05:45
Secozzi c96cf4b11a Fix height of description not being calculated correctly if images are present (#2382)
(cherry picked from commit c6a96b3970f0ba4643f438155653790973fa00f6)
2025-11-16 18:07:27 +05:45
krysanify 31601f523d Fix crash opening filter sheet with empty library and mark as read/unread for selected items (#2355)
(cherry picked from commit d88dbe6409b9c4dd7fbb37757e89c09af73f1fd3)
2025-11-16 17:48:12 +05:45
AntsyLich f9abe20b84 Remove gradle toolchains plugin
(cherry picked from commit d0bad9f0bd6b9d9dc641c81ee2428a0f859d01a8)
2025-11-16 17:48:12 +05:45
AntsyLich f7030ed800 Fix 'Default' category showing in library with no user-added categories (#2371)
(cherry picked from commit 7d717ee7fd9779b85fee29cadc946292cfdcee89)
2025-11-16 17:48:12 +05:45
AntsyLich f4173b3766 Fix title text color in light mode on mass migration list (#2370)
(cherry picked from commit a93f71b82be4489a7a2aefd8fa08bb114cae8db5)
2025-11-16 17:48:12 +05:45
AntsyLich 221a564644 Fix local source EPUB files not loading (#2369)
(cherry picked from commit 9bf3f15fff96b48e6847034c9fcd07f14675130b)
2025-11-16 17:48:12 +05:45
AntsyLich 7458eff2d8 Revert "Add full predictive back support (#2085)" (#2362)
This reverts commit c12bdbae8e7bc14da8966e45a3c450913e32129f.

(cherry picked from commit 1c3e96bf7f463949997c03e2119cfa55fd63dcd0)
2025-11-16 17:48:11 +05:45
Weblate (bot) 187245885a Translations update from Hosted Weblate (#1879)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/bg/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bg/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/gl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/he/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/th/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Co-authored-by: Ahmed TOUCHANE <ahmedtouchane0@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: Alex Maryson Jr <akamar87@gmail.com>
Co-authored-by: Aviv Ben Ami <avivbenami@gmail.com>
Co-authored-by: B4LiN7 <87660017+B4LiN7@users.noreply.github.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Conrad Mateman <conradmateme001@gmail.com>
Co-authored-by: Crazyom <naxom@laposte.net>
Co-authored-by: Danilo Issida Goncalves <danissida@hotmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Doministo <doministo@seznam.cz>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Guillaume Lecocq <guillaume.taylor@gmail.com>
Co-authored-by: Homura Akemi <amber_c001@protonmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: João Sousa <joaopsousa99@gmail.com>
Co-authored-by: Karley <siegitsi@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Mario Kevin D. A <programas013@gmail.com>
Co-authored-by: Mehedi Talha <meheditalha007@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mohamed kh <mohamedkhamekhami@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Prem Kumar <prem12321kumar@gmail.com>
Co-authored-by: Ryo Richie <ryorichie@gmail.com>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
Co-authored-by: Sky children of the Light <tu25261@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Tahsin Gökalp <tahsinsaan@gmail.com>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: Yurt Page <yurtpage@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: altinat <al@altqx.com>
Co-authored-by: amigo browser <juniperforest1@proton.me>
Co-authored-by: edgole <test.backache009@aleeas.com>
Co-authored-by: f_pluz <pedroh.lobo20@gmail.com>
Co-authored-by: fl0k1 <michele.carnova@gmail.com>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: gulse02 <gnoeoxgulse@gmail.com>
Co-authored-by: kevans <albapazpi@gmail.com>
Co-authored-by: naikhon <naikhon5@gmail.com>
Co-authored-by: pancake <ppzh0@users.noreply.hosted.weblate.org>
Co-authored-by: scb261 <65343233+scb261@users.noreply.github.com>
Co-authored-by: scb261 <scb261261@gmail.com>
Co-authored-by: Đào Ngọc Đang Khoa <daongocdangkhoa2510@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Артур Давлетов <ar.davletov2013@gmail.com>
Co-authored-by: Георгій Обушенков <heorhii.obushenkov@gmail.com>
Co-authored-by: Димитър Георгиев <dimitar13226@gmail.com>
Co-authored-by: ابومسلم <linuxmint1978@gmail.com>
Co-authored-by: ابْنُ السَدِيمِ <amarlubs2@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>

(cherry picked from commit 45c1a314887732f691e349a9e7684952830341f0)
2025-11-16 17:48:11 +05:45
Radon Rosborough e5d8c2edbc Use ComicInfo.xml for chapter metadata in localSource (#2332)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 32257e438e2f0bea7e0bfe84dc72135795d620ad)
2025-11-16 17:48:11 +05:45
anirudhn be4aa39c8a Fixed scrollbar sometimes not showing during scroll or not reaching the bottom with few items (#2304)
(cherry picked from commit 095ef8e74b1c208be25b616ce01d5b198749ee2e)
2025-11-16 17:48:11 +05:45
MajorTanya 014c697773 Add label to privately installed extensions (#2349)
Just adds the same word as the install option ("Private" in English)
next to the extension version and 18+ label.

(cherry picked from commit 549d74a2c9aef0eb41ea18378cd29d4ab9eee2b4)
2025-11-16 17:48:11 +05:45
AntsyLich ea733de80e Fix same manga check logic in mass migration
(cherry picked from commit f1193866f4306384a2a466c6353446bfed2bd9aa)
2025-11-16 17:48:11 +05:45
AntsyLich 3ac5dcd66e Potentially fix library IndexOutOfBound crash (#2341)
(cherry picked from commit c4407eda0eed5a7faed47d4470d79e6b1512b5c2)
2025-11-16 17:48:11 +05:45
AntsyLich 054de1cc6f Remove checksum from release notes and improve download tip
(cherry picked from commit b93337cb3d53278e191cf1dceeaf6c4effdb141d)
2025-11-16 17:48:11 +05:45
AntsyLich b525c0988a Support mass migration in 'Browse -> Migrate' (#2338)
(cherry picked from commit 22f851173b1eca242645f328a46e6038c035d5ec)
2025-11-16 17:48:11 +05:45
AntsyLich 691efe0831 Support mass migration for selected library items (#2336)
(cherry picked from commit 982ebcf777215c90584ad28fae79e9ca8a22a951)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaBottomActionMenu.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt
2025-11-16 17:48:11 +05:45
AntsyLich 8317a30d6e Optimize and cleanup library code (#2329)
(cherry picked from commit e62cd0e816402303fdf12513816894624f77e208)

# Conflicts:
#	.editorconfig
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/library/components/LibraryContent.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/stats/StatsScreenModel.kt
#	data/src/main/sqldelight/tachiyomi/migrations/6.sqm
#	data/src/main/sqldelight/tachiyomi/view/libraryView.sq
2025-11-16 17:48:11 +05:45
Mend Renovate 633937b0bc Update dependency com.android.tools.build:gradle to v8.12.0 (#2331)
(cherry picked from commit 1365b28106c6fb01c920e997ad63c993e6703eef)
2025-11-16 17:48:11 +05:45
Mend Renovate 3152d2803a Update dependency androidx.test.ext:junit-ktx to v1.3.0 (#2327)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 7ec28eb3bd2d2ce409249e09b90189af21c2c2e6)
2025-11-16 17:48:11 +05:45
Mend Renovate 883c90adc8 Update dependency androidx.test.espresso:espresso-core to v3.7.0 (#2326)
(cherry picked from commit ff9dfe45ed4b9d4fa07cbc1b7bffbff86f596e5c)
2025-11-16 17:48:11 +05:45
Mend Renovate 8e658be7d7 Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.4.0 (#2325)
(cherry picked from commit 967750ba5804f7ddf4ba230d8f3bb942096025b3)
2025-11-16 17:48:11 +05:45
Mend Renovate c27a4e2bf5 Update dependency androidx.work:work-runtime to v2.10.3 (#2324)
(cherry picked from commit 269af7fe2b5e1b444c1806bbeddfa89ec070ceab)
2025-11-16 17:48:11 +05:45
AwkwardPeak7 257f544a89 Include Manga initialized status in backup (#2285)
(cherry picked from commit 62eec15fe61be88e0ebc8be89a1e445dde55ba7e)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupManga.kt
2025-11-16 17:48:11 +05:45
Secozzi f8cb08ce52 Add option for rendering images in description (#2076)
# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/ui/UiPreferences.kt
2025-11-16 17:48:03 +05:45
Mend Renovate d970eea7cf Update dependency androidx.compose:compose-bom to v2025.07.00 (#2284)
(cherry picked from commit 4f1faf49f3c1fee757b6a9ec58b15c2a010085c3)
2025-11-16 12:37:36 +05:45
Mend Renovate a45fad81c8 Update okhttp monorepo to v5.1.0 (#2257)
(cherry picked from commit 6d717ea88b7545b3c7edba2dd051ce01f8f8aa7f)
2025-11-16 12:37:36 +05:45
Mend Renovate 76d6cf129a Update kotlin monorepo to v2.2.0 (#2235)
(cherry picked from commit fbb5e6b92f48b5f11fa4413f3a48e475cd431c11)
2025-11-16 12:37:36 +05:45
Mend Renovate 879427446f Update dependency org.jsoup:jsoup to v1.21.1 (#2233)
(cherry picked from commit 8f5f29e7376f0ecd275ed2fb95d13b1b10e8c04c)
2025-11-16 12:37:36 +05:45
Mend Renovate 9edd7b0c04 Update dependency com.squareup.okio:okio to v3.16.0 (#2320)
(cherry picked from commit a4b9c704b65027cd2066802960aeb248dbdf1c1f)
2025-11-16 12:37:36 +05:45
Mend Renovate d97b83fe93 Update plugin firebase-crashlytics to v3.0.5 (#2307)
(cherry picked from commit 9352201b03fad147b16423cf33584ecd58548700)
2025-11-16 12:37:36 +05:45
Mend Renovate 027e6bbb05 Update dependency com.google.firebase:firebase-bom to v34 (#2310)
(cherry picked from commit c715e981bffe2ad896559369515c491d2a76946f)
2025-11-16 12:37:36 +05:45
AntsyLich 4cdead8006 Make local source default chapter sorting match file explorer behavior
Closes #2225

(cherry picked from commit 7f56555d632508379037eb0fba4411079c27ad5b)
2025-11-16 12:37:36 +05:45
Mend Renovate aaff472317 Update dependency com.squareup.logcat:logcat to v0.4 (#2319)
(cherry picked from commit 8636b7a68526e033ced6767666f730e6c50ac1b3)
2025-11-16 12:37:36 +05:45
Mend Renovate 9b2febcd6d Update xml.serialization.version to v0.91.2 (#2317)
(cherry picked from commit a49670bf0dc1bfa3250356be2883ebc2f0b603c3)
2025-11-16 12:37:36 +05:45
Mend Renovate 5de355238d Update dependency com.squareup.logcat:logcat to v0.3 (#2309)
(cherry picked from commit 61cee5c5e04550a9c1f16a40600d9e60e28f072c)
2025-11-16 12:37:36 +05:45
Mend Renovate 644c8ec491 Update dependency com.pinterest.ktlint:ktlint-cli to v1.7.1 (#2281)
(cherry picked from commit d805f0cd2a93720726cc2284a384de3fb1f6abbd)
2025-11-16 12:37:36 +05:45
Mend Renovate 4b516ae4c5 Update dependency io.coil-kt.coil3:coil-bom to v3.3.0 (#2308)
(cherry picked from commit ce07259e8e8fb602d1028013aa0c27ee0ce705c9)
2025-11-16 12:37:36 +05:45
Mend Renovate 223251f868 Update lifecycle.version to v2.9.2 (#2283)
Update dependency androidx.lifecycle:lifecycle-process to v2.9.2

(cherry picked from commit 2f10e7beaa11bdddcb409a2fed9d5f0b97b8ade8)
2025-11-16 12:37:36 +05:45
Mend Renovate 9b7d6bace1 Update dependency io.mockk:mockk to v1.14.5 (#2282)
(cherry picked from commit 4ef8fb958824c500f1a2155951d12490fb55c709)
2025-11-16 12:37:36 +05:45
Mend Renovate c15b8b65e5 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.2.1 (#2293)
(cherry picked from commit 084e626669793cf637830827b5b03ae898c3814a)
2025-11-16 12:37:36 +05:45
Mend Renovate 4e9eaa5e81 Update dependency org.junit.jupiter:junit-jupiter to v5.13.4 (#2296)
(cherry picked from commit f93ccaaaa42fdf8091c89260803d9d518d06b9ac)
2025-11-16 12:37:36 +05:45
Mend Renovate 066e10246f Update dependency com.android.tools.build:gradle to v8.11.1 (#2277)
(cherry picked from commit 5585388e2d22879ac62e7fceaf26ae7f40cb8bde)
2025-11-16 12:37:36 +05:45
Matthias Ahouansou 3294dd6ca8 Use median to determine smart update interval (#2251)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit d60241690b373e42215761b4108e52a7655daaeb)
2025-11-16 12:37:36 +05:45
Mend Renovate 2315295985 Update dependency com.squareup.okio:okio to v3.15.0 (#2256)
(cherry picked from commit 84aa07b7f0b15bbe9f400596007f6714005118bb)
2025-11-16 12:37:36 +05:45
Mend Renovate 56ddf21107 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.1.0 (#2274)
(cherry picked from commit 0cc1224094069a321634cc3c1d5924b246ec7959)
2025-11-16 12:37:36 +05:45
Mend Renovate 3f47df21b8 Update serialization.version to v1.9.0 (#2252)
(cherry picked from commit a5a0d8330248174dc86d8f9a238a1c8489c291a6)
2025-11-16 12:37:36 +05:45
Mend Renovate 712407f524 Update dependency org.junit.jupiter:junit-jupiter to v5.13.3 (#2263)
(cherry picked from commit 1fde0275e313412af601e2ffdd79c7cf800678fb)
2025-11-16 12:37:36 +05:45
Mend Renovate 3a49a0a21a Update dependency gradle to v8.14.3 (#2264)
(cherry picked from commit a992f2d46758b741125c416c58a861a6f9ae9bc7)
2025-11-16 12:37:36 +05:45
Mend Renovate 04b3e13ba1 Update aboutlib.version to v12.2.4 (#2261)
(cherry picked from commit d8dd170d1b416cae793db10f9ee0568bfbdfadf9)
2025-11-16 12:37:36 +05:45
Mend Renovate 39bc2b49c0 Update moko to v0.25.0 (#2258)
(cherry picked from commit 6953090dabe3e90132c7c89a55e359a40257751e)
2025-11-16 12:37:36 +05:45
Mend Renovate 9765282640 Update plugin google-services to v4.4.3 (#2250)
(cherry picked from commit ab452a9945c6d34463e100ab63f614b1cf10b76c)
2025-11-16 12:37:36 +05:45
Mend Renovate 320a620afa Update dependency com.google.firebase:firebase-bom to v33.16.0 (#2248)
(cherry picked from commit 7dd595f16e2f484bd46f925c03b77675918208fc)
2025-11-16 12:37:36 +05:45
Mend Renovate ec2a720617 Update dependency com.android.tools.build:gradle to v8.11.0 (#2241)
(cherry picked from commit 6eb2a022f1e0b4a4da5714d69efe69bef584e179)
2025-11-16 12:37:36 +05:45
Mend Renovate 83d2ca7a54 Update dependency org.junit.jupiter:junit-jupiter to v5.13.2 (#2240)
(cherry picked from commit d61c66c286cf2c6d269809e2fbb5d601ed2d59e0)
2025-11-16 12:37:36 +05:45
Mend Renovate 891503c793 Update dependency io.mockk:mockk to v1.14.4 (#2232)
(cherry picked from commit 1e4ee1460893f7969a17f05b569f3673a42b77f0)
2025-11-16 12:37:36 +05:45
AntsyLich 43abc6c797 Fix background crash in mass migration screen
(cherry picked from commit 63943debc2fd4efa1a0418bbfefaea93a24b49fd)
2025-11-16 12:37:36 +05:45
Danny Wu f916e94a4c Add option to hide missing chapter count (#2108)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit d2c1ff6adf5543e5a593949704d41f2358252593)
2025-11-16 12:37:36 +05:45
AntsyLich fc9b2b6e1e Update manga without chapters even if restricted by source (#2224)
(cherry picked from commit b9e02e92bedf66aa2c4f7ed42b2c6899ed7fd013)
2025-11-16 12:37:36 +05:45
Mend Renovate 66bdd70485 Update dependency com.mohamedrejeb.richeditor:richeditor-compose to v1.0.0-rc13 (#2213)
(cherry picked from commit 103218681a6d9eda2f264e8f09724814dc8d5a96)
2025-11-16 12:37:36 +05:45
Mend Renovate 29024ea03a Update dependency androidx.compose:compose-bom to v2025.06.01 (#2220)
(cherry picked from commit 07136d3969daee988ddc129d091a6923d50f6a5a)
2025-11-16 12:37:36 +05:45
Mend Renovate 6af33905be Update dependency androidx.work:work-runtime to v2.10.2 (#2221)
(cherry picked from commit 4962deeb0cb5766d22ec0d3fb6e88ac50be327de)
2025-11-16 12:37:36 +05:45
Mend Renovate f97d918728 Update dependency com.squareup.okio:okio to v3.13.0 (#2201)
(cherry picked from commit cecf4596f9580806cf3208a518e5acac30becb50)
2025-11-16 12:37:36 +05:45
Mend Renovate 6a38e501d9 Update aboutlib.version to v12.2.3 (#2205)
(cherry picked from commit 0c77afbe038c2ad3db3f09d221f2a03fc2cec237)
2025-11-16 12:37:36 +05:45
Mend Renovate 8310733c4c Update sqlite to v2.5.2 (#2210)
(cherry picked from commit d126b84f954d6a35dd3cc1a29849fb0822714552)
2025-11-16 12:37:36 +05:45
AwkwardPeak7 28f0946877 Ensure app waits for Cloudflare challenge to complete before continuing (#2200)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 2df3382148c76d287943fc36e2f55bc16df1cd83)
2025-11-16 12:37:36 +05:45
jobobby04 e135a0dc71 Mass migration implementation (#2110)
There is no way to trigger mass migration at the moment. The functionality will be added in a follow up PR.

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit ee19050cc00b0a787af65b641624d07bb194e155)
2025-11-16 12:37:36 +05:45
AntsyLich 05a65773f0 Further tweak migration config screen sheet
(cherry picked from commit 019fc08da2392725c36e064ffadc4e645edafb63)
2025-11-16 12:37:36 +05:45
AntsyLich 8d794560a0 Add more migration config options and remove skipping option (#2193)
(cherry picked from commit 288f577a45a6835c34ad41caab95794f164b7a0b)
2025-11-16 12:37:36 +05:45
Mend Renovate 4341a98413 Update aboutlib.version to v12.2.2 (#2190)
(cherry picked from commit a47d4ebbdd04ce439c25a564afdb813dc80615d4)
2025-11-16 12:37:36 +05:45
Mend Renovate 24f5a36350 Update dependency sh.calvin.reorderable:reorderable to v2.5.1 (#2183)
(cherry picked from commit 89954e68e3265936718b5dd0664102f9f37b554a)
2025-11-16 12:37:36 +05:45
Mend Renovate f125db6973 Update dependency sh.calvin.reorderable:reorderable to v2.5.0 (#2178)
(cherry picked from commit c3b590cd3dfe70a5736411c6533913f2dadb17bc)
2025-11-16 12:37:36 +05:45
Mend Renovate 4ec969657e Update dependency com.google.firebase:firebase-bom to v33.15.0 (#2177)
(cherry picked from commit cb3c5e9c9c8465d3b1228264964b19ecda8bfc98)
2025-11-16 12:37:36 +05:45
Mend Renovate cb7e790086 Update plugin firebase-crashlytics to v3.0.4 (#2174)
(cherry picked from commit 7fa2834009013b01b06e2d95a80a4b4e09f37d17)
2025-11-16 12:37:36 +05:45
Mend Renovate 9012dafed4 Update dependency gradle to v8.14.2 (#2168)
(cherry picked from commit 95e3c22429adc98fb3ad7b941b5a8aa45322bfdc)
2025-11-16 12:37:36 +05:45
Mend Renovate 8b24d7eded Update okhttp monorepo to v5.0.0-alpha.16 (#2149)
(cherry picked from commit 8bd70342fcd1355c53fef62e597e2aa20229e123)
2025-11-16 12:37:36 +05:45
Mend Renovate dcc537accb Update sqldelight to v2.1.0 (#2119)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 92ec6b17a315c12838bf94bd214d216435e0f8f9)
2025-11-16 12:37:36 +05:45
Mend Renovate ab67775f13 Update dependency org.junit.jupiter:junit-jupiter to v5.13.1 (#1754)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

(cherry picked from commit 591e9c13560f28d71598eb32648387d099ebc881)
2025-11-16 12:37:36 +05:45
Mend Renovate e105828e07 Update dependency androidx.compose:compose-bom to v2025.06.00 (#2175)
(cherry picked from commit 7fed9c2ccfed0179e50b4b8960fcd3eb6d229f53)
2025-11-16 12:37:36 +05:45
Mend Renovate 3c83edaad2 Update dependency com.squareup.logcat:logcat to v0.2.3 (#2126)
(cherry picked from commit ccb554c877e552433cc4fff9164207b02f0a17cf)
2025-11-16 12:37:36 +05:45
Mend Renovate b4f278e5fa Update dependency androidx.appcompat:appcompat to v1.7.1 (#2167)
(cherry picked from commit 5235713d83ab3643d30f2a7f087126d60dbb21f4)
2025-11-16 12:37:36 +05:45
Mend Renovate 29ca687a26 Update lifecycle.version to v2.9.1 (#2173)
(cherry picked from commit 4692010400d4fad2cc51901a355a0c15b865860c)
2025-11-16 12:37:36 +05:45
Mend Renovate ed975cae63 Update aboutlib.version to v12.2.1 (#2170)
(cherry picked from commit be528ba12b82d357170262d825b38033fbd83e91)
2025-11-16 12:37:36 +05:45
Mend Renovate 4fce0944b4 Update dependency me.zhanghai.android.libarchive:library to v1.1.6 (#2171)
(cherry picked from commit 405e536cbf4182e141d221795331c374236c9708)
2025-11-16 12:37:36 +05:45
AntsyLich 4a52898f08 Add option to skip migration config
(cherry picked from commit 8714653a2f3b1a1f536494bcefbe66e7a7bbb4f7)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBrowseScreen.kt
2025-11-16 12:37:36 +05:45
AntsyLich 92b48319ed Cleanup migrate manga dialog and related code (#2156)
(cherry picked from commit 2b126f1ff56b63e470b48a04149e28c609f01148)

# Conflicts:
#	app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/MigrationFlags.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenDialogScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSourceSearchScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/history/HistoryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/history/HistoryTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2025-11-16 12:37:36 +05:45
AntsyLich 9e113d80f7 Fix no sources while migrating alongside UI and code cleanup (#2155)
(cherry picked from commit 5919f34fc96f254724bd3042ac2b91ac65912930)
2025-11-16 12:37:36 +05:45
Mend Renovate f960554cf8 Update dependency com.github.requery:sqlite-android to v3.49.0 (#2150)
(cherry picked from commit a4df33caf937a79ab1f70e33ad56e5b3899917e2)
2025-11-16 12:37:36 +05:45
Mend Renovate 0bdea705a5 Update aboutlib.version to v12.2.0 (#2152)
(cherry picked from commit 3580d2da6cc7f09eb3b6f1345c958a0ab0574856)
2025-11-16 12:37:36 +05:45
claymorwan 33361ea7f6 Add Catppuccin theme (#2117)
Mocha for dark and Latte for light, mauve accent

(cherry picked from commit 77eb55874278b7740d43b9144d9253a075cc593c)
2025-11-16 12:37:36 +05:45
Mend Renovate 717240f53c Update dependency com.android.tools.build:gradle to v8.10.1 (#2148)
(cherry picked from commit e1f6d143933ebf445adec5e1b87086551c2dca84)
2025-11-15 18:19:53 +05:45
AntsyLich 5156248a96 Add migration config screen to select and prioritize target sources (#2144)
(cherry picked from commit 2e180005a01f633ad7fafc5cfb3079f0bc858448)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/manga/MigrateMangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
2025-11-15 18:19:53 +05:45
Mend Renovate e074df469e Update markdown to v0.35.0 (#2143)
(cherry picked from commit 0f59fc1dd42f770a0e7a9359a3eb8baebc826246)
2025-11-15 18:19:53 +05:45
Mend Renovate d1277ecb02 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.0.4 (#2146)
(cherry picked from commit d1055475e23a3e20ef41b228056611be82e62515)
2025-11-15 18:19:53 +05:45
Mend Renovate 8bcc235490 Update dependency com.squareup.okio:okio to v3.12.0 (#2147)
(cherry picked from commit 32470657ddcb6976bb4c8f852ec19fe1d4dfb542)
2025-11-15 18:19:53 +05:45
Mend Renovate aaa7171c10 Update dependency me.zhanghai.android.libarchive:library to v1.1.5 (#2142)
(cherry picked from commit 158896cfa9314b89848d4d45b3042b80cefb127e)
2025-11-15 18:19:53 +05:45
Jobobby04 887311b440 Fix notification settings under api 26 2025-06-16 14:44:30 -04:00
Jobobby04 1c90aac059 Add id to staff-edges 2025-06-16 11:28:31 -04:00
Jobobby04 3ad9765dcf Remove +1 in Page Layout reader settings 2025-06-10 14:40:28 -04:00
Jobobby04 cc934607c8 SpotlessApply 2025-05-24 21:07:29 -04:00
Weblate (bot) 5074e68b9c Translations update from Hosted Weblate (#1442)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Alex Maryson Jr <akamar87@gmail.com>
Co-authored-by: B4LiN7 <87660017+B4LiN7@users.noreply.github.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Hualiang <642615676@qq.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Kosťantin Horovij <lg096066587039@gmail.com>
Co-authored-by: Lapis (Bas77) <sebastianramli77@gmail.com>
Co-authored-by: LordTenebrous <danielmorenoperez836@gmail.com>
Co-authored-by: Mohamed kh <mohamedkhamekhami@gmail.com>
Co-authored-by: Sky children of the Light <tu25261@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: edgole <test.backache009@aleeas.com>
Co-authored-by: fl0k1 <michele.carnova@gmail.com>
Co-authored-by: naikhon <naikhon5@gmail.com>
Co-authored-by: qaugji <asteeky9@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Георгій Обушенков <heorhii.obushenkov@gmail.com>
Co-authored-by: ابومسلم <linuxmint1978@gmail.com>
2025-05-24 20:47:35 -04:00
多能豆 ade41f113d Fix E-Hentai Jump/Seek match for detailed date (#1450) 2025-05-24 20:44:55 -04:00
Jobobby04 95dc82594f More guards against edited data 2025-05-24 20:44:27 -04:00
NGB-Was-Taken 80e585fa91 Change log file extension to .txt (#1449) 2025-05-24 20:19:17 -04:00
Jobobby04 9f110f9db8 Bump version so migation actually runs 2025-05-24 20:18:14 -04:00
NGB-Was-Taken 71470b9e02 Remove the unused mark duplicate as read preference. (#1448)
* Remove the unused mark duplicate as read preference.

* Migrate the old preference to new preference
2025-05-24 20:16:44 -04:00
renovate[bot] 4fd24accac Update dependency net.zetetic:sqlcipher-android to v4.9.0 (#1447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-24 20:15:17 -04:00
NGB-Was-Taken 31312fecac Fixes screen staying on in library tab. (#1451) 2025-05-24 20:13:43 -04:00
Mend Renovate b80d057922 Update dependency androidx.compose:compose-bom to v2025.05.01 (#2133)
(cherry picked from commit 92b376d9af93da988b695c36c4775d5e6947c048)
2025-05-24 20:12:57 -04:00
Mend Renovate f01d8bc835 Update dependency gradle to v8.14.1 (#2138)
(cherry picked from commit 1a2f09a622017dc5b201eadc6acc667487cf3d4d)
2025-05-24 20:12:48 -04:00
Jobobby04 ddffe71a22 SpotlessApply 2025-05-24 20:12:38 -04:00
AntsyLich 649a19ec57 Fix content cut off in home screen
Closes #2141

(cherry picked from commit 209e982fe4f1da5d1d49cfbfdd178625ee3c70f4)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
2025-05-24 20:10:18 -04:00
Mend Renovate e82fd99a09 Update plugin org.gradle.toolchains.foojay-resolver-convention to v1 (#2130)
(cherry picked from commit 0109102901f942502807e2a7a9f1a58f951c763f)
2025-05-24 20:09:57 -04:00
Mend Renovate 67a9b8e2a0 Update dependency com.pinterest.ktlint:ktlint-cli to v1.6.0 (#2129)
(cherry picked from commit 4117a5167470ae36b4172721b4e4d40373f2a3c6)
2025-05-24 20:09:51 -04:00
Mend Renovate 2000f947c3 Update xml.serialization.version to v0.91.1 (#2112)
(cherry picked from commit 4090a61d08964a8e82f943ac4eb81a52c110005f)
2025-05-24 20:09:45 -04:00
Jobobby04 f992ada0a8 SpotlessApply 2025-05-16 21:16:09 -04:00
Jobobby04 f876cdb037 Use MediaServer in Json for NHentai
Co-authored-by: 4521 <18432684+az4521@users.noreply.github.com>
2025-05-16 20:34:03 -04:00
Jobobby04 f919d42370 Hello Discord 2025-05-16 12:02:37 -04:00
Mend Renovate ab5ff00c39 Update kotlin monorepo to v2.1.21 (#2102)
(cherry picked from commit 625c85cbd68086d605553b2d5ab9cc9cc9460688)
2025-05-15 13:50:17 -04:00
Mend Renovate 422738af56 Update dependency org.jetbrains.kotlinx:kotlinx-collections-immutable to v0.4.0 (#2104)
(cherry picked from commit 737ceeea576074cffcd2e96933aceffdbcc0a03a)
2025-05-15 13:50:08 -04:00
Mend Renovate 81751fc9ce Update dependency io.coil-kt.coil3:coil-bom to v3.2.0 (#2101)
(cherry picked from commit 7933c9eeb7b28ecc2ae31fa337654a80f2371b85)
2025-05-15 13:49:58 -04:00
Jobobby04 9b6c5effc9 Minor refactors 2025-05-15 13:38:03 -04:00
Jobobby04 129841d5c2 SpotlessApply and up version code due to database migration 2025-05-11 20:23:10 -04:00
AntsyLich 24d2460697 Disable reader's 'Keep screen on' setting by default (#2095)
(cherry picked from commit f0de8f973b331ebad6e1844aea7864f97f237941)

# Conflicts:
#	CHANGELOG.md
2025-05-11 20:18:36 -04:00
AntsyLich ef3d9626c1 Add full predictive back support (#2085)
Co-authored-by: p
(cherry picked from commit c12bdbae8e7bc14da8966e45a3c450913e32129f)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaCoverDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
2025-05-11 20:18:11 -04:00
Mend Renovate 5c7b3c6c3b Update markdown to v0.34.0 (#2086)
(cherry picked from commit 33d407ee9c2196f25aaee0978b6808b9c393841e)
2025-05-11 20:10:50 -04:00
AntsyLich 6257888735 Update voyager to v1.1.0-beta03 (#2087)
(cherry picked from commit ef8c3ca119dfbdfcb0588bde080a7c6203133024)
2025-05-11 20:10:43 -04:00
FlaminSarge f5e714f794 Add advanced option to always update manga title from source (#1182)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 8b45ef0e5d5d368e0925df9816ae423defaed4d9)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/manga/interactor/UpdateManga.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
2025-05-11 20:10:28 -04:00
AwkwardPeak7 3091f63504 Fix pressing Enter while searching also triggering navigation back on physical keyboards (#2077)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 86ebf5581598f28feab4090ac3bf627f54b511d7)

# Conflicts:
#	CHANGELOG.md
2025-05-11 20:00:59 -04:00
Mend Renovate 39755cccdc Update lifecycle.version to v2.9.0 (#2080)
(cherry picked from commit ddf282b10364fc71c5af4cfe77684a8ac0beaa5c)
2025-05-11 20:00:40 -04:00
Mend Renovate 9caf706ca3 Update sqlite to v2.5.1 (#2078)
(cherry picked from commit 744b809d458ba1bfee923f76493505768c261231)
2025-05-11 20:00:32 -04:00
Mend Renovate 6ba6a7c8d9 Update dependency androidx.compose:compose-bom to v2025.05.00 (#2079)
(cherry picked from commit cd2ce44efafbaf19e43ba342d417e4d553a8a0d7)
2025-05-11 20:00:26 -04:00
Mend Renovate 0a4a0e4c4c Update dependency com.android.tools.build:gradle to v8.10.0 (#2072)
(cherry picked from commit cae7c3dc588055dee5c9a99c331710e038b17794)
2025-05-11 20:00:19 -04:00
Mend Renovate b48d1e521a Update aboutlib.version to v12.1.2 (#2073)
(cherry picked from commit c0074402e7cc5917272459e7ebfb269e11af4c76)
2025-05-11 20:00:08 -04:00
AntsyLich 211d090a2d Add autofill support to tracker login dialog and update processing text (#2069)
(cherry picked from commit 7deeabe844d41d2b5e918ad747ddd548163c9fe3)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:59:44 -04:00
AntsyLich b6e5943e15 Fix downloader stopping after failing to create download directory of a manga (#2068)
(cherry picked from commit 536393a6d9941fac282f10b825aa611b91e1fcdb)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
2025-05-11 19:59:22 -04:00
AntsyLich 78f6a34339 Fix Pill not following the local text style
Closes #2009

(cherry picked from commit f8cb506137a3619f828dac94557b5448b2a7fa24)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:48:31 -04:00
AntsyLich de967ae149 Cleanup MarkdownRender
Co-authored-by: p
(cherry picked from commit 98230ed30f04fe754fd4bd407356c8c03d8d8719)
2025-05-11 19:48:04 -04:00
Mend Renovate 4d075ff190 Update dependency androidx.compose:compose-bom to v2025.04.01 (#2040)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit d721a4321bdc6fafdd32e7bfd451b61b2bdd66b7)
2025-05-11 19:47:58 -04:00
Mend Renovate 076e2961c6 Update aboutlib.version to v12.1.0 (#2052)
(cherry picked from commit 1ac4b72cfe09be10cbde45633fbd84ffd703fc70)
2025-05-11 19:47:52 -04:00
Mend Renovate 7149de1bc3 Update dependency io.mockk:mockk to v1.14.2 (#2057)
(cherry picked from commit 9331f2b93f907bf3f7c95eb850b5befce90b68c6)
2025-05-11 19:47:42 -04:00
Mend Renovate 091f2f583a Update dependency org.jsoup:jsoup to v1.20.1 (#2058)
(cherry picked from commit 99c2a999735e04d026b937b953cdd5f19b2e7b1f)
2025-05-11 19:47:36 -04:00
Mend Renovate 1c0ef2ca98 Update aboutlib.version (#2046)
(cherry picked from commit 001716e34b0c533cfd0318be5048d32bc107931b)
2025-05-11 19:47:29 -04:00
NarwhalHorns 2a845bd7b5 Fix empty layout not appearing in browse source screen in some cases (#2043)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 37e19edf8a5f6a15a95f160390cbcf22d8133380)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt
2025-05-11 19:47:22 -04:00
AntsyLich afe326006f Switch default user agent to Android Chrome (#2048)
(cherry picked from commit 8b7f35598833917c89f8ae53cca10578fd880d67)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:44:45 -04:00
Mend Renovate 4b80154b09 Update dependency com.google.firebase:firebase-bom to v33.13.0 (#2047)
(cherry picked from commit 0b777336739b6f91ebfe45772c2f139d4e60c555)
2025-05-11 19:44:30 -04:00
Mend Renovate d6b230b8f1 Update dependency androidx.work:work-runtime to v2.10.1 (#2041)
(cherry picked from commit 9be558d6c0e0e81c1f37fc3d01b19872879f2daa)
2025-05-11 19:44:23 -04:00
Mend Renovate d02a2cbd29 Update dependency gradle to v8.14 (#2049)
(cherry picked from commit 0c8c5dbba6bf60fbc4e3e4dad912e2be8ce25a79)
2025-05-11 19:44:17 -04:00
AntsyLich 17d225b0d9 Fix crash when trying use source sort filter without a pre-selection (#2036)
(cherry picked from commit 1c982c2a01c1bba5ec4a955c9bf61cb346c752e7)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:44:10 -04:00
Mend Renovate 6cbbaccaf4 Update dependency com.android.tools.build:gradle to v8.9.2 (#2033)
(cherry picked from commit eeab61fc94e1a9486eba42fd79a8169473ab6fde)
2025-05-11 19:43:51 -04:00
Mend Renovate 94cc4027c2 Update aboutlib.version to v12 (major) (#2016)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit a036407c75d83ef0ba5350cb1825b615361316c3)
2025-05-11 19:43:44 -04:00
AntsyLich 03ae6ed2b0 Update dependency com.mohamedrejeb.richeditor:richeditor-compose to v1.0.0-rc11
(cherry picked from commit 615d93f780b415e505fb2159f4cbdf4694749f82)
2025-05-11 19:43:35 -04:00
AntsyLich fa8c232a69 Fix content under source browse screen top appbar is interactable (#2026)
(cherry picked from commit 9750c1e4bd6b931e71b7b348abbe2638a8cf317b)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:43:27 -04:00
Secozzi 0386ce998a Update markdown to 0.33.0 and tweak visuals (#2024)
- Update markdown to 0.33.0
- Use github flavour for github changelog
- Fix bullet list alignment

(cherry picked from commit e2915a1f69340cad515962de8a0b9d11ecff8d42)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:43:12 -04:00
AwkwardPeak7 273f73e9a2 Remove Okhttp networking from WebView Screen (#2020)
(cherry picked from commit df2b4c754bab9dd96fe2199b9f6df62d87b7175e)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:42:33 -04:00
KokaKiwi 5e20e54649 Fix reader not updating progress (#2007)
The condition for updating progress is wrong since fefa8f84982b537ca930438f7976087844d5bb9c

(cherry picked from commit 6632a122288cc9733844c8dce1ee51b520c0a32e)
2025-05-11 19:42:06 -04:00
Joseph Madamba b8c3f9dcce Update Facebook and Reddit icon (#1994)
(cherry picked from commit 0cb1925cf158155665f3173bccb93f39d84b71e0)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:41:59 -04:00
ArthurKun 802b6508fa Replace Modifier.composed with Composable Modifier (#1959)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit a31b3b7bbf2c5164baf76ac4b36f1d27c5d43135)
2025-05-11 19:41:36 -04:00
AwkwardPeak7 b6409b05e7 Include source headers when opening failed images from reader (#2004)
(cherry picked from commit fea85241afac5a849aa418d01710f5cdc0c25b54)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:41:27 -04:00
Secozzi 129f355b9c Use simpler markdown flavour in manga description (#2000)
(cherry picked from commit e273a26c9b7f0a9dd9f8847cfc65e69453fa5905)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:41:01 -04:00
AwkwardPeak7 9ffacb80e3 Fix duplicate requests in WebView due to empty reasonPhrase (#2003)
(cherry picked from commit 818e6931c6bc89e0bb111e77418542a88f8db37c)

# Conflicts:
#	CHANGELOG.md
2025-05-11 19:40:27 -04:00
AwkwardPeak7 85726db45d Add option to keep read manga when clearing database (#1979)
(cherry picked from commit ecc6ede0815a89b7f8288e47c607c57bacc47e71)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt
#	data/src/main/sqldelight/tachiyomi/data/mangas.sq
2025-05-11 19:40:06 -04:00
AwkwardPeak7 746b1b051c Surface image loading error in Reader (#1981)
(cherry picked from commit fefa8f84982b537ca930438f7976087844d5bb9c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2025-05-11 19:36:53 -04:00
AwkwardPeak7 59887eed80 Change Page.State to sealed interface (#1988)
(cherry picked from commit f1e2efcb37e2c623b769e979fa1c7e9e5ad7117d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ArchivePageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
2025-05-11 19:35:07 -04:00
Mend Renovate b8267f1fef Update dependency androidx.core:core-ktx to v1.16.0 (#1990)
(cherry picked from commit 180318f57d82529c0040a2d310a679a493d2b9f3)
2025-05-11 19:12:53 -04:00
Mend Renovate 8c62bb6d6d Update plugin org.gradle.toolchains.foojay-resolver-convention to v0.10.0 (#1992)
(cherry picked from commit ed749de8066ac056bc0caa505739f1b7e45dea48)
2025-05-11 19:12:46 -04:00
Mend Renovate 751e04b87f Update markdown to v0.33.0-rc01 (#1999)
(cherry picked from commit bb33b0029ef630a609dd160ed278d5e8274f316d)
2025-05-11 19:12:40 -04:00
Mend Renovate 9f0161ed70 Update dependency androidx.compose:compose-bom to v2025.04.00 (#1989)
(cherry picked from commit 3a19e449b13c078d7c0b5762f0ba84a162cc7f71)
2025-05-11 19:12:33 -04:00
Mend Renovate 7b2c341386 Update dependency com.squareup.okio:okio to v3.11.0 (#1991)
(cherry picked from commit 818edf2776fd7706cd1a829a6bdc963a436f06d6)
2025-05-11 19:12:22 -04:00
Mend Renovate c8b29ecf1c Update dependency io.mockk:mockk to v1.14.0 (#1987)
(cherry picked from commit 47d2646751d40a155724f658ba6461e8a2d57aad)
2025-05-11 19:12:15 -04:00
Mend Renovate c30381c6ec Update dependency androidx.sqlite:sqlite-framework to v2.5.0 (#1986)
(cherry picked from commit a1a7d67afb16cc206f1d6c6d47da52b7705a417d)
2025-05-11 19:12:08 -04:00
Mend Renovate f489531543 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.0.3 (#1977)
(cherry picked from commit 2090a380e0e9ab4f74fd2e5e74e6c2807e96f23d)
2025-05-11 19:12:01 -04:00
Mend Renovate 4bbe795626 Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.10.2 (#1978)
(cherry picked from commit 8e5cfe9d0acf854c9387ed3405f0fe3cc9140733)
2025-05-11 19:11:54 -04:00
Cuong-Tran 8aa3dca95f Fix navigation issue after migrating a duplicated entry from History tab
(cherry picked from commit d9c4b56336c21db96a835630a48c46ee7a480342)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
2025-05-11 19:11:40 -04:00
NarwhalHorns 5e0f730159 Display total chapters on duplicates list items (#1963)
(cherry picked from commit 12abd9938b7c235d6a1c02391624703476c1f339)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	data/src/main/java/tachiyomi/data/manga/MangaMapper.kt
2025-05-11 19:03:47 -04:00
Mend Renovate f1aed0d8b9 Update dependency androidx.compose:compose-bom to v2025.03.01 (#1927)
(cherry picked from commit c1225a5ef96f5f77bd337e0481935cbef75cc711)
2025-05-11 18:57:57 -04:00
AntsyLich a3465c31c9 Update non-library manga data when browsing (#1967)
(cherry picked from commit a594ad392d4793f3a5cb2b709d29b2feab6120d3)

# Conflicts:
#	CHANGELOG.md
2025-05-11 18:57:50 -04:00
Mend Renovate 053c48613b Update xml.serialization.version to v0.91.0 (#1956)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 80de0328190bd3adac8e034c420e6a91d3d7cfc9)
2025-05-11 18:55:30 -04:00
NarwhalHorns 615adc567b Display all similarly named duplicates in duplicate manga dialogue (#1861)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 0d35b6fdafbf5451a2743ea9bcfc735bf49374a7)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/history/HistoryTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2025-05-11 18:14:26 -04:00
AntsyLich b0f645d906 Deduplicate entries when browsing (#1957)
(cherry picked from commit f81da3dcce9afba883b6a3accdd3bf4ea21cfa81)

# Conflicts:
#	CHANGELOG.md
#	data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt
2025-05-11 18:05:21 -04:00
Mend Renovate 023c78d0e8 Update serialization.version to v1.8.1 (#1953)
(cherry picked from commit 2ce9fa0271c16449475adb07eb6338a497e11e3c)
2025-05-11 17:58:51 -04:00
AntsyLich 824550175a Remove feature flag from Nord theme (#1951)
(cherry picked from commit 5d2110f3fb1aa6b15f62af0dcd3378cfbe475b7a)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/ui/model/AppTheme.kt
2025-05-11 17:32:37 -04:00
Secozzi ad53c0de83 Add markdown support for manga descriptions (#1948)
(cherry picked from commit 4e68339783b47b0780e1b9aee643404339d35ed1)

# Conflicts:
#	CHANGELOG.md
#	gradle/libs.versions.toml
2025-05-11 17:31:41 -04:00
AntsyLich c8039739d5 Significantly improve browsing speed (near instantaneous) (#1946)
(cherry picked from commit c8ffabc84a096207c1997ab69fc86176f3b53f00)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/manga/model/Manga.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt
#	data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt
#	data/src/main/sqldelight/tachiyomi/data/mangas.sq
#	domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt
#	domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt
#	domain/src/main/java/tachiyomi/domain/source/repository/SourceRepository.kt
2025-05-11 17:24:33 -04:00
Bartu Özen 26674136e6 Fix app bar action tooltips blocking clicks (#1928)
(cherry picked from commit 77e79233ab054d16bb5dc04a040d0d86a326136f)

# Conflicts:
#	CHANGELOG.md
2025-05-11 16:50:49 -04:00
AntsyLich 9972fa1053 Fix mark existing duplicate read chapters as read option not working in some cases (#1944)
(cherry picked from commit 8a21148578af3c1538e9ab2b1fe5bdf05b4e35c9)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2025-05-11 16:50:02 -04:00
AntsyLich ae3f974d8c Fix user notes not restoring when manga doesn't exist in DB (#1945)
(cherry picked from commit e91db86faef8d6b17961a1b73fbf07f0d2c8975d)

# Conflicts:
#	CHANGELOG.md
2025-05-11 16:44:09 -04:00
Mend Renovate 027f179a4b Update kotlin monorepo to v2.1.20 (#1883)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 556290f2d35f739bb4bddc012739acf10b92708d)
2025-05-11 16:43:30 -04:00
Mend Renovate e80cb1795e Update dependency com.android.tools.build:gradle to v8.9.1 (#1913)
(cherry picked from commit 8b947919acde9932808e666b8bb6a2df9613a67f)
2025-05-11 16:43:22 -04:00
Mend Renovate 66fe599498 Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.4 (#1926)
(cherry picked from commit b62a9b40eb8ecb4c0c9c861d66c9afc427bc6bbe)
2025-05-11 16:43:15 -04:00
AntsyLich c9e6e321b3 Update editor config for 'sq' and 'sqm' file [skip ci]
(cherry picked from commit a6b532ee57d24e1ad83f1daea415cad1f313b49c)
2025-05-11 16:43:02 -04:00
kunet fb3c996904 Add user manga notes (#428)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 8fbe630308b962043c7b59422878c94f80156e9f)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaToolbar.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/creators/MangaBackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupManga.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/MigrationFlags.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
#	data/src/main/sqldelight/tachiyomi/migrations/5.sqm
#	domain/src/main/java/tachiyomi/domain/manga/model/MangaUpdate.kt
2025-05-11 16:42:33 -04:00
perokhe 70b25825ec Fix page number not appearing when opening chapter (#1936)
(cherry picked from commit 132d77aa9947f891f90f1afcdcb24e20ce515438)

# Conflicts:
#	CHANGELOG.md
2025-05-11 16:26:43 -04:00
Cuong-Tran 290e8f5a1e Fix benchmark build (#1938)
(cherry picked from commit b00bbe91beb942f2ac18765be6c78b6f318cc66d)
2025-05-11 16:25:36 -04:00
Jayman Rana f6b1440bf2 Fix backup sharing from notifications not working when app is in background (#1929)
(cherry picked from commit 3e5d3d099fed5feb6a6807196bea5fed72973fe9)

# Conflicts:
#	CHANGELOG.md
2025-05-11 16:25:27 -04:00
perokhe 77a4919656 Fix next chapter button occasionally jumping to the last page of the current chapter (#1920)
(cherry picked from commit 941dde341eb11703eadae543f351c9284617541c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt
2025-05-11 16:25:14 -04:00
Ian Hunter 84d901b8a3 Add more Kaomoji for empty/error screens (#1909)
(cherry picked from commit d4aaf6521e86e8509d3971854c46b8520cef7f59)

# Conflicts:
#	CHANGELOG.md
2025-05-11 16:22:24 -04:00
Mend Renovate d27ed2580f Update dependency com.google.firebase:firebase-bom to v33.11.0 (#1890)
(cherry picked from commit f7046a503bea421a0310f8d2064888aea0a07d11)
2025-05-11 16:22:08 -04:00
MajorTanya 87ea971be0 Fix Bangumi search including novels (#1885)
(cherry picked from commit 953c4e7bc056ed8b9eebe1b111677a4616c4d694)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/dto/BGMSearch.kt
2025-05-11 16:22:01 -04:00
Weblate (bot) 91ea70b335 Translations update from Hosted Weblate (#1877)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: scb261 <scb261261@gmail.com>
(cherry picked from commit 1d6dc1e8b0de08af1370c04eff480e4555095c55)
2025-05-11 16:21:27 -04:00
AntsyLich 2e94e152c2 Use current time as build time for preview builds (#1876)
(cherry picked from commit 935f1fcf3f8e4f9da4774d932b65ae77b44cc773)

# Conflicts:
#	app/build.gradle.kts
2025-05-11 16:21:22 -04:00
Weblate (bot) eece46fb0f Translations update from Hosted Weblate (#1550)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/gl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/he/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/kk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/pl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/am/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/be/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bg/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ceb/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/gl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ka/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/km/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/lt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/mr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sah/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sq/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/th/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/uz/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Abay Emes <abayemes@gmail.com>
Co-authored-by: Acelith <joel.jon@moix.me>
Co-authored-by: Ahmad Ansori Palembani <palembani@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Champ0999 <il.migliore0999@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Doministo <doministo@seznam.cz>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Harshit Prajapati <harshitprajapati7666@gmail.com>
Co-authored-by: Hasanur Rahman Biplob <hrbiplob10@gmail.com>
Co-authored-by: Horace Johnson <horacejohnson99@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Jakub Fabijan <jakubfabijan@tuta.io>
Co-authored-by: Kerim Demirkaynak <aschannel111@gmail.com>
Co-authored-by: Koanrade <konrad.nowicki91@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: MD_Abdulla072 <md.abdullacse20@gmail.com>
Co-authored-by: Matyáš Caras <matyas@caras.wtf>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mochammad Nopal Attasya <meleboy22@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: NormalRandomPeople <normal.scribe833@silomails.com>
Co-authored-by: Pecs1 <mynameisnoname897@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Piyoka Smith <piyoka5697@ahaks.com>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Co-authored-by: Rom Savidor <romsavidor@gmail.com>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Shiratori <kuromaruhatake@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
Co-authored-by: Sixten Lund <arbitraryindices@users.noreply.hosted.weblate.org>
Co-authored-by: Sorawit Jannareubate <moszaduck007@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: dianisaac <muhandreop@gmail.com>
Co-authored-by: f0roots <f0rootss@gmail.com>
Co-authored-by: kevans <albapazpi@gmail.com>
Co-authored-by: staxhinho <staxhinho@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
(cherry picked from commit b3726572381abfa1eaaf31cf7f3b685b390f60bf)

# Conflicts:
#	i18n/src/commonMain/moko-resources/de/strings.xml
#	i18n/src/commonMain/moko-resources/kk/strings.xml
#	i18n/src/commonMain/moko-resources/lt/strings.xml
#	i18n/src/commonMain/moko-resources/ru/strings.xml
2025-05-11 16:19:26 -04:00
AntsyLich 34736bc26e For release builds use last commit time as build time (#1873)
(cherry picked from commit dae7d179662ff6d6654e7c10e57f1aeeaf579de8)

# Conflicts:
#	app/build.gradle.kts
2025-05-11 16:17:52 -04:00
renovate[bot] 82cf385f9d Update dependency net.zetetic:sqlcipher-android to v4.8.0 (#1429)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-11 16:14:08 -04:00
renovate[bot] 682dea2fb1 Update koin to v4.0.4 (#1428)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-11 16:12:00 -04:00
renovate[bot] c10588d183 Update tachiyomiorg/issue-moderator-action action to v2.6.1 (#1388)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-11 16:11:44 -04:00
Jobobby04 6db1637770 Fix library flags test 2025-05-11 14:57:14 -04:00
Jobobby04 5742d2e3fe Release 1.12.0 2025-05-11 14:24:22 -04:00
BrutuZ c2d0308ac0 Populate Author field and clear Description on a couple of delegated (#1432) 2025-05-11 14:16:43 -04:00
Callum Wong 84c7da5a7d Add QR code scan button for sync API key (#1430)
* Add dependency com.journeyapps:zxing-android-embedded:4.3.0

* Add widget parameter to EditTextPreferenceWidget

* Add QR code scanner icon button to sync API key preference which launches a ScanContract

* Remove screenOrientation property from CaptureActivity manifest

* Allow scanning both normal and inverted codes

* store values and make code more concise

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>

* Import local context

---------

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2025-05-11 14:15:05 -04:00
cfouche 274350c118 Change for t1 for better hit rate (#1425) 2025-05-11 14:12:44 -04:00
Weblate (bot) 6bd978eef1 Translations update from Hosted Weblate (#1422)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Alex Maryson Jr <akamar87@gmail.com>
Co-authored-by: B4LiN7 <87660017+B4LiN7@users.noreply.github.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Hualiang <642615676@qq.com>
Co-authored-by: Kosťantin Horovij <lg096066587039@gmail.com>
Co-authored-by: Sky children of the Light <tu25261@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: edgole <test.backache009@aleeas.com>
Co-authored-by: fl0k1 <michele.carnova@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Георгій Обушенков <heorhii.obushenkov@gmail.com>
Co-authored-by: ابومسلم <linuxmint1978@gmail.com>
2025-05-11 13:49:55 -04:00
Weblate (bot) e0f40fad8c Translations update from Hosted Weblate (#1408)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Champ0999 <il.migliore0999@gmail.com>
Co-authored-by: Corrado Belmonte <corrado.spam@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Nam Pai <namhg911@gmail.com>
Co-authored-by: Renan Sarto <app@renansg.com>
Co-authored-by: Sepultrex <sepultrex@gmail.com>
Co-authored-by: Shiratori <kuromaruhatake@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Tim Schneeberger <tim.schneeberger@outlook.de>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: dianisaac <muhandreop@gmail.com>
Co-authored-by: quangpao <ddquangbao@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2025-03-18 18:17:56 -04:00
renovate[bot] 5647665782 Update dependency com.google.oauth-client:google-oauth-client to v1.39.0 (#1410)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-18 18:16:40 -04:00
Jobobby04 df99e7ee49 SpotlessApply 2025-03-18 18:04:23 -04:00
cfouche dbd4437474 Update base URL and host for Pururin to pururin.me (#1415) 2025-03-18 17:43:03 -04:00
AntsyLich 9c198d0c33 Seperate mark duplicate read chapters as read behaviors as options (#1870)
(cherry picked from commit 8a3b6107755c768924a31c2b58d705296133839c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2025-03-18 17:37:58 -04:00
AntsyLich d62a8a138c Add back option to hide unread chapter badge in library (#1871)
(cherry picked from commit ac432e2e941f4689caad246bab6aa7d303c83bfa)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
2025-03-18 17:31:02 -04:00
Cuong-Tran f8a57ec98c Add back build tools version to sign-android-release (#1842)
(cherry picked from commit 7028b8673a6b78dc6ccc19f5b3242bf1b37ca908)
2025-03-18 17:29:07 -04:00
Mend Renovate aa6339df06 Update dependency org.jsoup:jsoup to v1.19.1 (#1822)
(cherry picked from commit 2dc8cf000b871b8ffe07016d76a4bc7114d6ea49)
2025-03-18 17:28:57 -04:00
Mend Renovate 3fbbfbd9cb Update dependency androidx.compose:compose-bom to v2025.03.00 (#1857)
(cherry picked from commit f76a3ad15ad3954c512c20d99337a207f2e2d37a)
2025-03-18 17:28:49 -04:00
AntsyLich 31d6bf1967 Remove closed issue/pr auto lock workflow [skip ci]
(cherry picked from commit f33aa1ac9223393d0921df2902e4b59589ab7d2d)

# Conflicts:
#	.github/workflows/lock.yml
2025-03-18 17:28:41 -04:00
MajorTanya 226b3f2ff4 Add app ID to debug info (#1847)
This will avoid the need to know which forks has which version numbers
and avoid confusion in support.

(cherry picked from commit eddf07f9ac31bab57d06515e42df9c854bc50eed)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/util/CrashLogUtil.kt
2025-03-18 17:27:55 -04:00
AntsyLich ac8dab75fe Make option to mark duplicate chapter as read apply when reading (#1839)
(cherry picked from commit 22b5fb58ff8e89635d646f8fa29256b53c41ffbf)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2025-03-18 17:27:12 -04:00
AntsyLich aad2bf4645 Make more sliders discrete and ensure they don't look out of place (#1840)
Also cleanup the underlying code

(cherry picked from commit 4f06c1cc09d15245b26b8a862738cb6a859fedcc)

# Conflicts:
#	CHANGELOG.md
2025-03-18 17:24:05 -04:00
AntsyLich 7f71296e1c Change label of setting to always use SSIV in long strip reader (#1834)
(cherry picked from commit 85d168ed5e201134558cc843aba896306617c9ca)

# Conflicts:
#	CHANGELOG.md
2025-03-18 16:57:58 -04:00
AntsyLich 9137170fb8 Bump default user agent (#1833)
(cherry picked from commit d3691cc2563815490683cc69cbc3260e4561906c)

# Conflicts:
#	CHANGELOG.md
2025-03-18 16:57:37 -04:00
FlaminSarge 0af667c9aa Attempt to fix crash when migrating or removing entries from library (#1828)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 563bc02113a5ebc53650fdfdd13f408284a0cdc8)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt
#	domain/src/main/java/tachiyomi/domain/manga/interactor/GetLibraryManga.kt
2025-03-18 16:57:00 -04:00
NarwhalHorns 8dc6a95ce6 Display staff information on Anilist tracker search results (#1810)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit b702603965044cfe3ee852f8d0c970b6eb93b97a)

# Conflicts:
#	CHANGELOG.md
2025-03-18 16:55:40 -04:00
Roshan Varughese 1eb64d117e Fix an issue where tracker reading progress is changed to a lower value (#1795)
(cherry picked from commit 2e2f1ed82d63a93ebf87ee8494434c1bad2e268c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2025-03-18 16:55:21 -04:00
Mend Renovate 8f48a80bc4 Update dependency com.android.tools.build:gradle to v8.9.0 (#1824)
(cherry picked from commit b2765a00d285040531619a287d5144718959dd49)
2025-03-18 16:54:37 -04:00
NarwhalHorns e76dd7fab0 Update track search preview (#1825)
(cherry picked from commit 0e6d6c087e5a4d889b9153b390d8335d7add1e87)
2025-03-18 16:54:29 -04:00
Smol Ame b53a9ce5ae Tweak and adjust issue template (#1817)
Co-authored-by: BrutuZ <brutuz@users.noreply.github.com>
(cherry picked from commit 4f7122d6f09f87930ccd7dae7c557f4b236bbc4b)
2025-03-18 16:54:22 -04:00
Mend Renovate 952f26929c Update dependency io.mockk:mockk to v1.13.17 (#1786)
(cherry picked from commit b763d3e2c24caac6898981395aece2984b3e03a3)
2025-03-18 16:54:12 -04:00
AwkwardPeak7 9ff048e683 Fix webview crash caused by 793d7fb (#1819)
(cherry picked from commit 9957fff2fbb6dad6f9df89bb2c16db34d9e4da96)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2025-03-04 11:33:14 -05:00
Jobobby04 a64fe8121b Guard against NPE in edit info dialog 2025-03-02 14:03:33 -05:00
Jobobby04 4db7a32075 Fix migration delete downloaded not registering properly 2025-03-02 14:01:39 -05:00
Jobobby04 20ee5ea3e1 Fix database migration 2025-03-02 13:42:54 -05:00
Jobobby04 d9200ef006 Build fix 2025-03-02 13:34:37 -05:00
AwkwardPeak7 dfde271f7f Spoof or remove X-Requested-With header from webview (#1812)
(cherry picked from commit 793d7fbe40c87ed233da8cc99d544d01024ed4f5)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	core/common/src/main/kotlin/eu/kanade/tachiyomi/network/NetworkHelper.kt
2025-03-02 13:18:06 -05:00
Mend Renovate 5346eac037 Update dependency com.google.firebase:firebase-bom to v33.10.0 (#1789)
(cherry picked from commit b12ee027ea8941cb29d0f83085481c75eb862ed4)
2025-03-02 13:14:32 -05:00
Smol Ame 95e151be4b Update Issue Request Template (#1808)
(cherry picked from commit d7a1ae27346a983f658fb88cb525cf8b785b3bb3)
2025-03-02 13:14:23 -05:00
rhjdvsgsgks 98af745e08 Add build tool version to android config (#1803)
(cherry picked from commit 7566918ee749e76c701aeda7e99d81003676a51c)
2025-03-02 13:14:05 -05:00
AntsyLich 56433a624e Add option to mark new duplicate read chapters as read (#1785)
(cherry picked from commit cd0481592c09dc9cfb331805e90e6e5c3752a08c)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
2025-03-02 13:13:33 -05:00
Mend Renovate c59cb620dd Update dependency com.android.tools.build:gradle to v8.8.2 (#1784)
(cherry picked from commit b93746b01e78d4e75dbd1c6e9dda1b7b1baa6831)
2025-03-02 13:10:30 -05:00
AntsyLich f60cb9bb64 Remove alphabetical category sort option (#1781)
(cherry picked from commit 2b0c28938bfd74577d2ff0736b2cc72f4e4705cf)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/category/CategoryScreen.kt
2025-03-02 13:10:23 -05:00
Mend Renovate 949a2a95ad Update dependency androidx.activity:activity-compose to v1.10.1 (#1782)
(cherry picked from commit 4db3817782e73c75abe0b40c93273df90c683a42)
2025-03-02 13:09:29 -05:00
Mend Renovate 0bd700699b Update dependency androidx.constraintlayout:constraintlayout to v2.2.1 (#1783)
(cherry picked from commit ec07843f0cab02d7d1fee9c90eed35441b7b671b)
2025-03-02 13:09:23 -05:00
Cuong-Tran 1d10925829 Add back support for drag-and-drop category reordering (#1427)
(cherry picked from commit 919607cd06ee45ac667a2fd650d85aaf6ebb9762)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/category/CategoryScreen.kt
2025-03-02 13:09:13 -05:00
Cuong-Tran 0e2866260f Add Xiaomi system app to list of invalid browsers (#1776)
(cherry picked from commit d91c7b609359e83fcbb1b93ac16f608f8d45a2f2)

# Conflicts:
#	CHANGELOG.md
2025-03-02 13:02:10 -05:00
Roshan Varughese 02ace23c38 Add option to export minimal library information to a CSV file (#1161)
(cherry picked from commit fab8b17d99c44a08555b1f584c56d62a47737ca0)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsDataScreen.kt
2025-03-02 13:01:51 -05:00
Jobobby04 3e16adf961 SpotlessApply 2025-03-02 12:59:36 -05:00
AntsyLich fb1a3da0ea Use .toUri() extension function
(cherry picked from commit 0dda64b9d80a47a96fb52d13b5e0ece6d5fca2b1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
2025-03-02 12:55:41 -05:00
AntsyLich 5f2e979bb5 Remove F-droid warnings
(cherry picked from commit 181dbbb638686a284fa24c4e43d7c022a4f8e4bb)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/MoreScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateNotifier.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/MoreTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt
#	domain/src/test/java/tachiyomi/domain/release/interactor/GetApplicationReleaseTest.kt
2025-03-02 12:54:48 -05:00
MajorTanya 5d4d15aa9c Add private tracking support for Kitsu (#1774)
(cherry picked from commit 1dd81ef1e1b383f379f4e8e53d27a47cf7f0278f)

# Conflicts:
#	CHANGELOG.md
2025-03-02 12:45:02 -05:00
Mend Renovate fb71d0cd68 Update dependency gradle to v8.13 (#1773)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 2d0be5b0c93c9e3991ca593304d81d4d22dd72de)
2025-03-02 12:44:44 -05:00
Mend Renovate a189a7eaec Update dependency com.android.tools:desugar_jdk_libs to v2.1.5 (#1772)
(cherry picked from commit 4d7350e3184f13cbcfda357f75859dad0d679154)
2025-03-02 12:44:36 -05:00
NarwhalHorns 59a6bd700b Support for private tracking with AniList and Bangumi (#1736)
Co-authored-by: MajorTanya <39014446+MajorTanya@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 49b2b346b65c2631a8369c8f6643e945720770de)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/track/BaseTracker.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/Tracker.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
#	app/src/main/java/eu/kanade/test/DummyTracker.kt
2025-03-02 12:44:26 -05:00
MajorTanya 278224676b Fix Bangumi login regression (#1770)
Caused by #1748.

Two different issues actually.

Firstly, the getUsername API call uses the authClient, which uses the
BangumiInterceptor to get the current OAuth data and attach the
Authorization header. However, on login, #1748 did not try to set the
new auth details until after attempting to call getUsername.
This would cause Mihon to think the user was not authenticated with
Bangumi and cancel the process.

This is fixed by having Mihon store the OAuth credentials in the
interceptor first before attempting to call getUsername.

The second issue is a simple trailing dollar sign in the API URL for
the getUsername method. This was removed.

(cherry picked from commit badc229a2312c0c750c34631f303ac4ca970dc71)
2025-03-02 12:30:27 -05:00
MajorTanya 66f2877a3f Add back explicit update(track) call to Bangumi (#1771)
Most if not all other trackers do this too. Technically this causes
some request duplication (since things like the BaseTracker's
setRemoteLastChapterRead fire anyway due to the tracker sheet being
open. But considering the reduced number of requests in other places,
I think this is still acceptable.

This change will allow #1736 to proceed, hopefully.

(cherry picked from commit 277d8bad8e8d21cd74dc1681da09a4b980f455e0)
2025-03-02 12:30:16 -05:00
MajorTanya a97deb0036 Add "Monochrome" theme (#1752)
This theme is mainly geared towards e-Ink displays with limited/no
colour capabilities. Previous themes like Yin & Yang would make heavy
use of greyscale colours which could look off on some devices.

This theme is probably not conformant to Material Design 3 colour
scheme guidelines, but it does boast some amazing WebAIM contrast
ratios (#FFFFFF text on #000000 background gets a ratio of 21:1, vice
versa too).

Initially, this was intended as a purely black and white theme but
some contrast issues arose, such as the download badges (tertiary
background, onTertiary text colour) having the same colour as unread
badges (primary/onPrimary), or the step indicators (stops) not being
visible on sliders (since they use the colours of the opposite state
track (active region stops are the colour of the inactive region track
and vice versa).

To mitigate this, each variant (dark/light) of the theme has one
additional grey mixed in for their tertiary and secondaryContainer
colours each. For the dark variant, this is a #A0A0A0 background for
#000000 text (8.03:1 contrast ratio) and for the light variant, it is
a #505050 background for #FFFFFF text (8.06:1 contrast ratio).
This results in distinct unread vs download badges and visible steps
in the sliders.

---------

Co-authored-by: Sunspark-007 <73711243+Sunspark-007@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 8b48d1016b851b425e4f66d44bca098220585c37)

# Conflicts:
#	CHANGELOG.md
2025-03-02 12:30:09 -05:00
MajorTanya ab976d8b07 Migrate to Bangumi's newer v0 API (#1748)
This comes with many benefits:
- Starting dates are now available and shown to users
- Lays groundwork to add private tracking for Bangumi, e.g. in #1736
- Mihon makes approximately 2-4 times fewer calls to Bangumi's API
- Simplified interceptor for the access token addition
  - v0 does not allow access tokens in the query string
- There is actively maintained documentation for it

Also shrunk the DTOs for Bangumi by removing attributes we have no
use for either now or in the foreseeable future. Volume data remains
in case Mihon wants to ever support volumes. But attributes such as
user avatars, nicknames, data relating to Bangumi's tag & meta-tag
systems, etc. have been removed or just not added to the DTOs.

(cherry picked from commit a96fbba3dc354e363b85923c52feceb88dc34447)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
2025-03-02 12:29:47 -05:00
Mend Renovate cb2cfa7e94 Update dependency androidx.compose:compose-bom to v2025 (#1651)
(cherry picked from commit d8a530266ffd7774df1af6c0dc5fc7e66fe2b20c)
2025-03-02 12:24:56 -05:00
Cuong-Tran 2c2f84bb29 Fix backup/restore of category related preferences (#1726)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit e1724d1aa0e3340e1404cfd80bd264831d86a879)

# Conflicts:
#	CHANGELOG.md
2025-03-02 12:24:48 -05:00
Cuong-Tran 7156b0dcce Reuse AppBar in manga screen (#1367)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 2cd52d5a1ff48b0f9cf17245c1bfa66f99b8c187)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaToolbar.kt
2025-03-02 12:24:07 -05:00
Jobobby04 f62671742c Fix build 2025-03-02 12:21:13 -05:00
AntsyLich 58be872bef Cleanup and tweak preference widgets (#1769)
(cherry picked from commit ebfbbf0741c04dc450a943d2cf77f48eed5c6dfa)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/Preference.kt
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
2025-03-02 12:21:03 -05:00
Cuong-Tran ce6b847c8b Fix App's preferences referencing deleted categories (#1734)
(cherry picked from commit eeb683069a3a0be7e769ac9273b5accc582e03ec)

# Conflicts:
#	CHANGELOG.md
#	app/build.gradle.kts
2025-03-02 11:57:47 -05:00
Roshan Varughese 9c22e7fcb7 Add button to favorite manga from history screen (#1733)
(cherry picked from commit 7e71a34256e79b03a8a8ea50334b1ccece4b7154)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/history/HistoryTab.kt
2025-03-02 11:56:46 -05:00
NGB-Was-Taken 452f36939a Apply "Downloaded only" filter to all entries regardless of favourite status (#1603)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 29ee53f4612b6ec9b399da9d29f18cfd0b1a2768)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:56:09 -05:00
Mend Renovate f0b821e2df Update aboutlib.version to v11.6.3 (#1737)
(cherry picked from commit 6a223f34a0430dba2917e2fe2b737540658e01e2)
2025-03-02 11:55:45 -05:00
BrutuZ cda87a5c07 Ignore hidden files/folders for Local Source chapter list (#1763)
(cherry picked from commit c97fe71e290604849299f1ebb9dfe1295188ca60)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:55:35 -05:00
Mend Renovate 10844339b8 Update aboutlib.version to v11.6.0 (#1728)
(cherry picked from commit 8e81a5e68b61a7db36cd3ef39ac3f319c4d6e0a1)
2025-03-02 11:53:48 -05:00
Mend Renovate 042785e188 Update plugin firebase-crashlytics to v3.0.3 (#1702)
(cherry picked from commit b08270d52310d30670bb3b81dfebb594759e2dd8)
2025-03-02 11:53:42 -05:00
AntsyLich 07740ae83c Add more editor configs and move ktlint config to it (#1731)
(cherry picked from commit 34d1e6fa278846dd8eb6ea82c936818d4610d3c2)

# Conflicts:
#	.editorconfig
#	buildSrc/src/main/kotlin/mihon.code.lint.gradle.kts
2025-03-02 11:53:21 -05:00
Mend Renovate 9d08fe05c1 Update dependency com.android.tools.build:gradle to v8.8.1 (#1723)
(cherry picked from commit a80965f7f18e51a8cd0b5029b34fe4fe9c04b494)
2025-03-02 11:51:17 -05:00
Mend Renovate 516114011f Update paging.version to v3.3.6 (#1717)
(cherry picked from commit 59ee61039b0e221ee6c00c052f89f32413eb502f)
2025-03-02 11:51:10 -05:00
Mend Renovate bb08522a32 Update dependency io.coil-kt.coil3:coil-bom to v3.1.0 (#1701)
(cherry picked from commit b7a96e69465e3fd63fbe901591e6fca6f9557334)
2025-03-02 11:51:04 -05:00
Mend Renovate 25949c3296 Update moko to v0.24.5 (#1694)
(cherry picked from commit 31a3f9e051f211af38c4a62b5a3bcfc711c93ee3)
2025-03-02 11:50:58 -05:00
AntsyLich 5720774bbf Rework slider UI
Fixes #1474

(cherry picked from commit e8c9cb2c2e4c24443368f0d653c5283f9671ffec)

# Conflicts:
#	presentation-core/src/main/java/tachiyomi/presentation/core/components/SettingsItems.kt
2025-03-02 11:50:51 -05:00
Mend Renovate 74c8b20a85 Update aboutlib.version to v11.5.0 (#1663)
(cherry picked from commit d592ab2e8712d13169942a7e7f53ef0c29a77a7b)
2025-03-02 11:50:17 -05:00
Mend Renovate 744b714c25 Update dependency gradle to v8.12.1 (#1662)
(cherry picked from commit 9d6ed93daaa91217fc82fb856e6d3d4eedd0092a)
2025-03-02 11:50:10 -05:00
Mend Renovate 73d57239f7 Update kotlin monorepo to v2.1.10 (#1671)
(cherry picked from commit 34efa8d9017f58001a93db4e53b4ca03a0ab2660)
2025-03-02 11:50:03 -05:00
MajorTanya 325a706840 Add Infinix system app to list of invalid browsers (#1684)
* Add Infinix system app to list of invalid browsers

`com.transsion.resolver` being picked by the system as a suitable
browser caused a Mihon user with an Infinix device to be unable to
open any links in browsers, including tracker login and opening a
WebView page in a real browser.

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

* Add docstring to DeviceUtil.invalidDefaultBrowsers

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit bfc8320aa4720dc3b908aab1b8a1ffb99d43193b)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:42:37 -05:00
MajorTanya c179b1812c Fix MAL tracker losing track of login expiration (#1682)
* Add missing @EncodeDefault annotation to MALOAuth

Similar to the situation with Bangumi, the missing annotation means
kotlinx.serialization would _provide_ the default value upon
instantiation but not serialise it to disk. This means the isExpired()
calculation would effectively rarely/never do its job correctly,
leading to Mihon sending expired tokens to MAL and causing problems
for everyone involved.

Overall, this change _could_ (should) lead to a drastic reduction in
MAL requests failing, leading to users having to relink their MAL
accounts.

Also switched createdAt to be in seconds instead of milliseconds as
all other trackers use seconds for timestamps (except for AniList,
which uses milliseconds but doesn't use a createdAt timestamp anyway).

* Add CHANGELOG.md entry

(cherry picked from commit 29ec7c125a3f1a1f39a90f8eba2d3e39b5af9797)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:42:08 -05:00
MajorTanya 1fa05703fa Fix Bangumi tracker losing track of login expiration (#1681)
* Fix Bangumi tracking losing track of login state

kotlinx.serialization does NOT serialize default values (like
createdAt in BGMOAuth.kt), so every time the Bangumi tracker
deserialized the tracker OAuth, createdAt was set to the time of the
read, not the time of issuance.

Separately, BangumiInterceptor did correctly fetch new OAuth
credentials upon detected expiry of the stored credentials and saved
them, but did not use them for the current request (the new
credentials were used for all subsequent requests only). This led to
401 errors from Bangumi because the expired access_token was provided.
 A subsequent request using the newly acquired access_token would end
 up being successful.

* Add CHANGELOG.md entry

(cherry picked from commit dce6aacf02d07f3f123b19b1b74cbbe18c28852b)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:40:49 -05:00
MajorTanya b34f807d33 Add zoned "Current time" to debug info and include year & timezone in logcat output (#1672)
* Add zoned date & time to debug info & logs

This should help distinguish log entries that happened recently and
may be related to crashes from older entries that occurred before now.

* Change logcat date and time output format

After some discussion, it was decided to adjust the logcat date and
time display to include the year and the timezone in the logcat
output. This results in a line start like this:

`2025-01-27 18:37:46.662 +0100`

which follows the following DateTimeFormatter pattern:

`yyyy-MM-dd HH:mm:ss.SSS Z`

* Add CHANGELOG.md entry

(cherry picked from commit 503d0be66772c37e08e69e5d022475245b706fd1)

# Conflicts:
#	CHANGELOG.md
2025-03-02 11:40:32 -05:00
renovate[bot] fda27e6eba Update dependency com.google.oauth-client:google-oauth-client to v1.38.0 (#1402)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-02 11:38:14 -05:00
Tim Schneeberger 217503eab0 feat(MangaDex): use tracker links to associate mangas automatically with trackers (#1387)
* feat: add searchById support to trackers (MAL, AniList, MangaUpdates only)

* feat: add new preference to toggle auto selection of tracker items using source metadata if available

* feat: add new preference to toggle auto selection of tracker items using source metadata if available

* feat: add automatic title selection using source metadata to TrackInfoDialog.kt

* style: apply spotless

* refactor: remove hardcoded MangaDexSearchMetadata cast and introduce common interface
2025-03-02 11:37:50 -05:00
lord-ne 8d062cecfd Use COMPLETE category when sync finishes (#1385) 2025-03-02 11:37:07 -05:00
BrutuZ 614839c023 Fix CDN subdomain for delegated source covers (#1384) 2025-03-02 11:36:41 -05:00
Tim Schneeberger 254980695b feat: batch processing for recommendations & sort by relevancy (#1383)
* refactor: use NoResultsException

* refactor: cleanup RecommendationPagingSources

* refactor: turn wake/wifi lock functions into reusable extensions

* feat: implement batch recommendation (initial version)

* fix: serialization issues

* fix: wrong source id

* refactor: increase performance using virtual paging

* refactor: update string

* refactor: handle 404 of MD source correctly

* style: add newline

* refactor: create universal throttle manager

* refactor: throttle requests

* chore: remove unused strings

* feat: rank recommendations by match count

* feat: add badges indicating match count to batch recommendations

* fix: handle rec search with no results

* fix: validate flags in pre-search bottom sheet

* feat: implement 'hide library entries' for recommendation search using custom SmartSearchEngine for library items

* style: run spotless

* fix: cancel button

* fix: racing condition causing loss of state
2025-03-02 11:36:07 -05:00
Weblate (bot) 28cca49635 Translations update from Hosted Weblate (#1379)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY

Co-authored-by: Corrado Belmonte <corrado.spam@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Nam Pai <namhg911@gmail.com>
Co-authored-by: Shiratori <kuromaruhatake@gmail.com>
Co-authored-by: Tim Schneeberger <tim.schneeberger@outlook.de>
Co-authored-by: quangpao <ddquangbao@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2025-03-02 11:32:25 -05:00
Jobobby04 c95d7fe30f Re-add Android SDK 2025-01-22 13:31:24 -05:00
Jobobby04 2b890c2057 Minor improvements 2025-01-22 12:58:26 -05:00
Jobobby04 456db52653 Minor cleanup 2025-01-21 18:21:44 -05:00
Weblate (bot) 0a5e9dce24 Translations update from Hosted Weblate (#1340)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ta/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Acelith <joel.jon@moix.me>
Co-authored-by: Andrés sigampa <fixiho3273@bawsny.com>
Co-authored-by: Barrel-Whisky-Fermentation <entomavasilissazeta790@gmail.com>
Co-authored-by: Bokutowo <stephaniejin47@gmail.com>
Co-authored-by: C0LiSii0N <paul.31@hotmail.com>
Co-authored-by: Cauã Oliveira <caua.oli.santos@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Homura Akemi <amber_c001@protonmail.com>
Co-authored-by: Igor Coimbra Carvalheira <igorccarvalheira111@gmail.com>
Co-authored-by: Illia Stoianov <Walrus_Morj@protonmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: KenjieDec <kenjiedec@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Mochammad Nopal Attasya <meleboy22@gmail.com>
Co-authored-by: NormalRandomPeople <normal.scribe833@silomails.com>
Co-authored-by: Paulo Victor <paulovictorbarrosdecarvalho@gmail.com>
Co-authored-by: Ruben Lopes <lopes.ruben@ua.pt>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: cannnAvar <bartucanavar@proton.me>
Co-authored-by: jobobby04 <jobobby04@gmail.com>
Co-authored-by: mirukupc <mirukupc.jp@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: தமிழ்நேரம் <anishprabu.t@gmail.com>
Co-authored-by: 清水汐音 <chenzhongjie19940725@gmail.com>
2025-01-21 17:56:55 -05:00
spicemace 9b6600d31f Mangadex fix alt title being removed by cleanDescription (#1378)
* Update MdUtil.kt

* Update ApiMangaParser.kt

* Update MdUtil.kt
2025-01-21 17:12:11 -05:00
Mend Renovate 5f19859589 Update dependency com.google.firebase:firebase-bom to v33.8.0 (#1652)
(cherry picked from commit 82fd89cee65f6663a6eddd09c73eaff23d3c2947)
2025-01-21 14:48:18 -05:00
Mend Renovate a189780e7f Update dependency androidx.recyclerview:recyclerview to v1.4.0 (#1650)
(cherry picked from commit 643f95f046e98d7403daedf06ff01d0c9708249d)
2025-01-21 14:48:10 -05:00
Mend Renovate 664fcfd787 Update dependency androidx.activity:activity-compose to v1.10.0 (#1649)
(cherry picked from commit 9c81f2486cd8db6dbdb68e6e273cc8587814b21d)
2025-01-21 14:48:02 -05:00
Mend Renovate 64e3e03a02 Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.0.2 (#1647)
(cherry picked from commit e59d2d381d2c105cae41918d30cc215ab3317551)
2025-01-21 14:47:56 -05:00
AntsyLich 3139aa5e51 Remove unnecessary filters for pseudolocales
(cherry picked from commit da90064c948c629ebaf6d6a97ca0b6f52cb570f1)
2025-01-21 14:47:46 -05:00
AntsyLich 2744a8bd96 Address some deprecations
(cherry picked from commit d53a3828b12daead9c898bea12c9a1497d07366f)
2025-01-21 14:47:39 -05:00
sdaqo 0ab7d18ad3 Add option to enable incognito mode per extension (#157)
* add per Extension Incognito Mode

* migrate incognito sources when extension is updated

* remove incognito sources when extension is uninstalled

* remove not used variable

* address change requests

address change requests

* Rebase and cleanup code

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit c283abefb03f79ce6652492db71cde410f828f78)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2025-01-21 14:47:32 -05:00
Mend Renovate 853288f71b Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.0.1 (#1630)
(cherry picked from commit 5a9367603beb82aac350c47c9ea2a6c343be0c1e)
2025-01-21 14:44:34 -05:00
Mend Renovate 4a2a81df80 Update dependency com.squareup.okio:okio to v3.10.2 (#1631)
(cherry picked from commit c01e9f3e92b9b2aa92aa50af5e3066affed419ad)
2025-01-21 14:44:27 -05:00
Mend Renovate 6827a0899c Update dependency com.android.tools.build:gradle to v8.8.0 (#1634)
(cherry picked from commit ae9753a1ea72b9e8d3271d56ed6cc202b8973ca2)
2025-01-21 14:44:20 -05:00
Mend Renovate dd1cbb07f7 Update dependency io.mockk:mockk to v1.13.16 (#1636)
(cherry picked from commit 1fe4d6cbd41f38676cb3cd858974ac105d272786)
2025-01-21 14:44:13 -05:00
Jobobby04 7f20006622 Use Adoptium distributed Java in workflows 2025-01-21 14:44:04 -05:00
Mend Renovate 8d25074a3e Update dependency com.diffplug.spotless:spotless-plugin-gradle to v7.0.0 (#1628)
(cherry picked from commit 3a3abc6854c8035e0d489750a04fba8400ef2c84)
2025-01-21 14:42:58 -05:00
Mend Renovate 73a265f5ad Update serialization.version to v1.8.0 (#1627)
(cherry picked from commit d9a550b9350a6fb46bac783833b54c4b199e719b)
2025-01-21 14:42:51 -05:00
Mend Renovate 02da349080 Update aboutlib.version to v11.4.0 (#1621)
(cherry picked from commit 1617f8eb49a210808326bc46b536b87d62095658)
2025-01-21 14:42:44 -05:00
Jobobby04 e218234f91 Tweak build workflow 2025-01-21 14:42:35 -05:00
MajorTanya 47b4be7fcf Fix MAL main_picture nullability breaking search if a result doesn't have a cover set (#1618)
* Fix MAL manga cover nullability

If a manga doesn't have a cover, MAL doesn't provide the
`main_picture` element in the API response at all.

* Add CHANGELOG.md entry

(cherry picked from commit d60802721b78870082af9445201338fbcfa0a780)

# Conflicts:
#	CHANGELOG.md
2025-01-21 14:38:08 -05:00
AntsyLich fea11eaa06 Revert "Revert "Add option to always use SSIV for image decoding""
This reverts commit 1909126921ac78309f7f7c7c2aa85606611531b8

(cherry picked from commit c5655e8803bc32d0931657f0b7bc6afeab70feaf)

# Conflicts:
#	CHANGELOG.md
2025-01-21 14:37:36 -05:00
Mend Renovate 99ef619603 Update dependency gradle to v8.12 (#1605)
(cherry picked from commit d3973f4ad88b2d61e49974b032a118a7f67b9a7b)
2025-01-21 14:37:08 -05:00
Mend Renovate 93a5e70bbe Update dependency androidx.compose:compose-bom to v2024.12.01 (#1564)
(cherry picked from commit bb230fd6a77651ea2b5b1b3f1e42124a98b63016)
2025-01-21 14:36:59 -05:00
Mend Renovate a3c1c63332 Update paging.version to v3.3.5 (#1563)
(cherry picked from commit e526fd44c618ab26fd4860a0b7b147efc89d5bf1)
2025-01-21 14:36:52 -05:00
Mend Renovate 4348862e46 Update dependency androidx.viewpager:viewpager to v1.1.0 (#1571)
(cherry picked from commit f61f039a453cf562fdb10e9eeac64b55b2d9eb31)
2025-01-21 14:36:42 -05:00
Mend Renovate 5a6aaf8dcf Update dependency org.junit.jupiter:junit-jupiter to v5.11.4 (#1580)
(cherry picked from commit 79eb02d8f066e7cd2465938c24a9649a9a61f48a)
2025-01-21 14:36:35 -05:00
Mend Renovate bc28f7a4e9 Update voyager to v1.0.1 (#1595)
(cherry picked from commit 814584d35b4ad79da941b21178f452dc2dd601f3)
2025-01-21 14:36:28 -05:00
Mend Renovate 27f6ed4338 Update dependency com.android.tools:desugar_jdk_libs to v2.1.4 (#1599)
(cherry picked from commit 87513073018d9a0a31c64b898f10a11bddc4772c)
2025-01-21 14:36:18 -05:00
Mend Renovate 4ec0a6d148 Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.10.1 (#1596)
(cherry picked from commit bcff2262b33004a4dec229c59c43cf27a04e72d3)
2025-01-21 14:36:11 -05:00
Mend Renovate 9e7a3c9e41 Update dependency io.mockk:mockk to v1.13.14 (#1601)
(cherry picked from commit 04454ecdbe49f0690c874b95becc3c164bb66f41)
2025-01-21 14:36:05 -05:00
Mend Renovate 8794b7f5de Update moko-resources to v0.24.4 (#1553)
(cherry picked from commit e86aeee9c417dea66d321fd4cbbad7ffdf41b106)
2025-01-21 14:35:49 -05:00
Mend Renovate 2f02aa07c7 Update dependency com.google.firebase:firebase-bom to v33.7.0 (#1545)
(cherry picked from commit be37f214d87c40f8876bd114cc96f55e0092ca90)
2025-01-21 14:35:40 -05:00
Mend Renovate 62f9c2b187 Update dependency com.android.tools.build:gradle to v8.7.3 (#1535)
(cherry picked from commit 1a833e88b1831fa4c8aacadeedc777adda256f36)
2025-01-21 14:35:33 -05:00
Mend Renovate 900ecfe372 Update dependency com.pinterest.ktlint:ktlint-cli to v1.5.0 (#1540)
(cherry picked from commit 4c84878adc541181ff37ebe23d1f8e7f7521d0d6)
2025-01-21 14:35:26 -05:00
Mend Renovate 72a19fc349 Update dependency org.jsoup:jsoup to v1.18.3 (#1533)
(cherry picked from commit 054198e78f80d6d3c9867a94317deb2d80950db9)
2025-01-21 14:35:13 -05:00
Mend Renovate 9e24276b59 Update kotlin monorepo to v2.1.0 (#1518)
(cherry picked from commit d522d81164d26d405517f7b6ad4d4882c86b54f2)
2025-01-21 14:35:01 -05:00
Tim Schneeberger 46dea6d598 feat: add global search shortcut to SmartSearch (#1377)
* feat: add global search shortcut to SmartSearch

* feat: add global search shortcut to SmartSearch

* feat: add back button to BrowseTabWrapper
2025-01-21 14:30:28 -05:00
Tim Schneeberger d80ad3f145 feat: unify recommendation screens and add more sources (#1376)
* feat(recommendations): add mangaupdates.com support

* feat(recommendations): display all tracker recommendation sources

* refactor(recommendations): apply spotless

* refactor: split RecommendationPagingSources

* feat(recommendations): unify MangaDex & community recommendations

* refactor: remove old screen

* fix: update comment

* style: fix formatting

* refactor: move onClick handlers

* fix: handle external recommendation links correctly

* fix: apply spotless

* feat: add comick recommendation source

* fix: mark recs from comick as not initialized to force fetching missing metadata

* Update app/src/main/java/exh/recs/BrowseRecommendsScreen.kt

---------

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2025-01-21 14:29:32 -05:00
renovate[bot] a7a3e5a2db Update koin to v4.0.2 (#1370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-21 14:25:27 -05:00
Luca Auer a32c7186e4 Maintain correct source order even when receiving new chapters from a sync service (#1360)
* Maintain correct source order even when receiving new chapters from sync service

* Add comma required by build service
2024-12-17 12:26:11 -05:00
Linguiniotta a25aff7fb0 Fix broken URI scheme (#1342) 2024-12-17 11:49:15 -05:00
renovate[bot] 7721d8b733 Update dependency com.google.oauth-client:google-oauth-client to v1.37.0 (#1369)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-17 11:48:41 -05:00
Cuong-Tran 75db0d09e5 Fix spelling (#1368) 2024-12-16 08:58:10 -05:00
NGB-Was-Taken fd120c5081 Get manga info from tracker (#1271)
* Barebones setup (only AniList works)

* Show tracker selection dialog when entry has more than one tracker

* MangaUpdates implementation

* Add logging and toast on error.

* MyAnimeList implementation

* Kitsu implementation

* Fix MAL authors and artists

* Decode AL description

* Throw NotImplementedError instead of returning null

* Use logcat from LogcatExtensions

* Replace strings with MR strings

* Missed a string

* Delete unused Author class.

* Add Bangumi & Shikimori support for info edit (#2)

This adds the necessary API calls and DTOs to allow for editing an
entry's data to the data from a tracker, specifically adding support
for Bangumi and Shikimori.

* Exclude enhanced trackers from tracker select dialog

* MdList implementation

* Remember getTracks and trackerManager

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>

---------

Co-authored-by: MajorTanya <39014446+MajorTanya@users.noreply.github.com>
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2024-12-08 15:25:26 -05:00
KenjieDec 34e9d9f146 Add support for .webp image extension (#1335) 2024-12-08 15:24:48 -05:00
Weblate (bot) b7f7187293 Translations update from Hosted Weblate (#1299)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Cauã Oliveira <caua.oli.santos@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Homura Akemi <amber_c001@protonmail.com>
Co-authored-by: Igor Coimbra Carvalheira <igorccarvalheira111@gmail.com>
Co-authored-by: Illia Stoianov <Walrus_Morj@protonmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: KenjieDec <kenjiedec@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Paulo Victor <paulovictorbarrosdecarvalho@gmail.com>
Co-authored-by: Ruben Lopes <lopes.ruben@ua.pt>
Co-authored-by: TheKingTermux <50316075+TheKingTermux@users.noreply.github.com>
Co-authored-by: cannnAvar <bartucanavar@proton.me>
Co-authored-by: jobobby04 <jobobby04@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2024-12-08 15:23:50 -05:00
Jobobby04 4abadea4f9 Spotless 2024-12-08 15:22:57 -05:00
Jobobby04 1b3d76398b Minor cleanup 2024-12-08 15:18:51 -05:00
Weblate (bot) 688fdecaf8 Translations update from Hosted Weblate (#1531)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/uk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Illia Stoianov <Walrus_Morj@protonmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
(cherry picked from commit b4ad9ae0634330eb4b3a9479cd522de48819a886)
2024-12-08 14:37:37 -05:00
MajorTanya 0bedee1778 Always use software bitmap on certain devices (#1543)
* Include Coil's broken hardware bitmap device list

Declares all listed devices as unable to use hardware bitmaps.

Might fix #1541.

* Hide Hardware Bitmap Threshold setting if unusable

This hides the setting from the UI if the user's device in on Coil's
list of devices with problematic hardware bitmap implementations.

Also moved HARDWARE_BITMAP_UNSUPPORTED into the ImageUtil as a
property for more ergonomic access across the project.

* Add missing negation

* Update CHANGELOG.md

* Update CHANGELOG.md

* Needs to be and not or

Also fix typo in CHANGELOG.md

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 7f2cfb5eb224896d6d0ffa6960f0a98c7325e240)

# Conflicts:
#	CHANGELOG.md
#	core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt
2024-12-08 14:23:57 -05:00
Weblate (bot) bb89f9f636 Translations update from Hosted Weblate (#1423)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/am/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bg/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ceb/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/da/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/eu/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ka/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/my/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sah/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Akhil Raj <89210430+akhi07rx@users.noreply.github.com>
Co-authored-by: AntsyLich <antsylich@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Horace Johnson <horacejohnson99@gmail.com>
Co-authored-by: Igor Coimbra Carvalheira <igorccarvalheira111@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Leandro Cândido <123888466+marshfellow42@users.noreply.github.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
(cherry picked from commit a807722838d1f10141b29721957cbac5a95f147d)
2024-12-08 14:22:44 -05:00
MajorTanya f8011981eb Add a Honor system app to list of invalid browsers (#1520)
Closes #1348.

Specifically adds com.hihonor.android.internal.app to the list of
invalid browsers. It's very similar to the existing entry for Huawei,
so it stands to reason it is the same/similar problem as with Huawei's
internal app.

(cherry picked from commit 3bd8d3ecb7023d1b01930ab0f91482c23e89c946)
2024-12-08 14:22:34 -05:00
Mend Renovate 7e17e52e07 Update dependency org.jsoup:jsoup to v1.18.2 (#1515)
(cherry picked from commit 8ea95cb27fa3c263cc9905c63cd8493ffb831ef5)
2024-12-08 14:22:27 -05:00
Mend Renovate b65990ad29 Update dependency io.coil-kt.coil3:coil-bom to v3.0.4 (#1510)
(cherry picked from commit e280fd63b67355b60a6f303a7d02539785d02856)
2024-12-08 14:22:21 -05:00
Mend Renovate d9560d40de Update dependency gradle to v8.11.1 (#1475)
(cherry picked from commit addb4ae9ad5f9294c70bce8b5eebd806115158b2)
2024-12-08 14:22:14 -05:00
AntsyLich 036ab3351d Improve hardware bitmap threshold option
Also `spotlessApply`

(cherry picked from commit d6dfd24548eaa05a8c3e478068fe2e08f2ee4473)
2024-12-08 14:22:06 -05:00
Cuong-Tran 769293355f Fix app update error notification disappearing (#1476)
(cherry picked from commit 88aff2c77fbaed52ab101ce75c2cbe72f1747579)
2024-12-08 14:21:57 -05:00
AntsyLich 850d81600e Slightly tweak Preference.PreferenceItem.CustomPreference
(cherry picked from commit 81effea01c33d4b47f6802a3d5e31fa39609a6fb)
2024-12-08 14:21:47 -05:00
AntsyLich ce96b53f10 Fix loading screen not appearing when changing query in browser screen
Fixes #1438
Closes #1441

(cherry picked from commit 9aef08c333397caa4b897514cf76966592d3849c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
2024-12-08 14:20:29 -05:00
AntsyLich b98dfd65b5 Add option to lower the threshold for hardware bitmaps
Closes #1436
Closes #1486

(cherry picked from commit dcddac5daaff3ec89c8507c35dc13d345ffdb6d7)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
2024-12-08 14:16:10 -05:00
AntsyLich 612e0a00bc Revert "Add option to always use SSIV for image decoding"
This reverts commit bb4d9fc81a043ac4f2d0105f19c09974ae2f7201.

(cherry picked from commit 1909126921ac78309f7f7c7c2aa85606611531b8)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt
2024-12-08 14:14:24 -05:00
AntsyLich d286cf3267 Switch to hardware bitmap in reader only if device can handle it
Closes #1460

(cherry picked from commit e6d96bd348ea5d18a005d6465222ad5f5123103e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderPageImageView.kt
2024-12-08 14:13:59 -05:00
Cuong-Tran 1a28c7fb35 Fix reader transition color scheme in auto background mode (#1487)
(cherry picked from commit 36d5ee0763be2b0bcc65f9d061961d86359fe6f6)
2024-12-08 14:10:36 -05:00
Mend Renovate 5909f90003 Update paging.version to v3.3.4 (#1481)
(cherry picked from commit 5a91d5c611faacacf5cf6fa135e93863c0332475)
2024-12-08 14:10:29 -05:00
Mend Renovate 48f7b701dc Update dependency androidx.viewpager:viewpager to v1.1.0-rc01 (#1480)
(cherry picked from commit e332590b1bbe3eaea76763db0761e9690ae684e2)
2024-12-08 14:10:23 -05:00
Mend Renovate b17530ccc3 Update dependency io.coil-kt.coil3:coil-bom to v3.0.3 (#1485)
(cherry picked from commit 39982c406351c93610dedda75ac5199d29b3d6a5)
2024-12-08 14:10:14 -05:00
Mend Renovate f844a48b67 Update dependency io.coil-kt.coil3:coil-bom to v3.0.2 (#1469)
(cherry picked from commit d1a970e3f3c9a2cfea2567a2e86245fc8a169c68)
2024-12-08 14:10:07 -05:00
Cuong-Tran 66929e097c Fix crash after removing last category while it's active in library (#1450)
(cherry picked from commit 9df21583dc1da6da4041709a6d059848c6c9bda0)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/components/LibraryTabs.kt
2024-12-08 14:10:00 -05:00
AntsyLich be30814d35 Update dependency androidx.work:work-runtime to v2.10.0
(cherry picked from commit 57e6e198b8101aa4ea60da89aea371f827b5f7e4)
2024-12-08 13:59:55 -05:00
Mend Renovate 5d56c1961d Update dependency com.android.tools:desugar_jdk_libs to v2.1.3 (#1453)
(cherry picked from commit 3a648e4fa50fa9c6cf8703b74062d67db237be1c)
2024-12-08 13:59:49 -05:00
Mend Renovate 4aa52a2576 Update dependency io.coil-kt.coil3:coil-bom to v3.0.1 (#1454)
(cherry picked from commit 6159bc36368910c024682ad5d0d2b298bc4fb17f)
2024-12-08 13:59:43 -05:00
Mend Renovate f7a1869066 Update dependency com.pinterest.ktlint:ktlint-cli to v1.4.1 (#1449)
(cherry picked from commit 3cfc2be104c2820eccbaa9d3a68b3df0ed37e39c)
2024-12-08 13:59:30 -05:00
Mend Renovate 2f1d76cbac Update dependency androidx.compose:compose-bom to v2024.10.01 (#1424)
(cherry picked from commit 9580a00aa674edd66c6a22ea127e6317f5d85498)
2024-12-08 13:59:25 -05:00
Mend Renovate 5c5e08b99b Update dependency androidx.core:core-ktx to v1.15.0 (#1417)
(cherry picked from commit cb2b0464d036496d7b029468a9a3efc2e95151d9)
2024-12-08 13:59:18 -05:00
Mend Renovate cc16d53ecc Update dependency com.android.tools.build:gradle to v8.7.2 (#1428)
(cherry picked from commit ef7992f9121828af9efa7a66ed1d2d731793d6b5)
2024-12-08 13:59:12 -05:00
Mend Renovate 28fa3855c2 Update dependency io.coil-kt.coil3:coil-bom to v3.0.0 (#1444)
(cherry picked from commit a5349a881b650c15de57ba39e4e121a26918f913)
2024-12-08 13:59:00 -05:00
Mend Renovate 5a47a58e1e Update xml.serialization.version to v0.90.3 (#1446)
(cherry picked from commit 2ca2cec02b818d85c73885fadc23f8480e62a0af)
2024-12-08 13:58:53 -05:00
Jobobby04 c86714ef59 Fix some deprecations 2024-12-08 13:58:44 -05:00
AntsyLich 75fe57b851 Cleanup some code
(cherry picked from commit 2f4bb7cadb0297492cfb21393e75ca276e0539d7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
2024-12-08 13:58:32 -05:00
Jobobby04 b9fffc45cc Fix idle status set 2024-12-08 13:47:54 -05:00
Jobobby04 de6cd169d0 Return newpage joineditems check 2024-12-08 13:37:29 -05:00
Jobobby04 95e8a02e33 Forgot import 2024-12-08 13:36:19 -05:00
Jobobby04 c720f0ac5c Increase new updates count when updates found 2024-12-08 13:35:58 -05:00
Jobobby04 76af3b59f0 Improve favorites sync statuses 2024-12-08 13:35:36 -05:00
Jobobby04 3f8cce8a32 Update tag lists 2024-12-08 13:31:38 -05:00
Jobobby04 26cfb4811f Fix a possible crash with auto-zoom 2024-11-07 22:21:39 -05:00
Jobobby04 e5a6d1b456 Fix a crash with migration list screen 2024-11-07 22:21:18 -05:00
Jobobby04 f0b621dfe5 Fix multiple issues with the E-Hentai updater 2024-11-07 22:21:02 -05:00
NGB-Was-Taken d88f570f65 Do not sync automatically when not connected to a network. (#1312) 2024-11-03 23:42:39 -05:00
Jobobby04 b430e31da4 Fix app onStart sync 2024-11-03 22:44:31 -05:00
Jobobby04 271f2d37bb Fix crashes from Exh Updater 2024-11-03 22:30:47 -05:00
AntsyLich c2e36b4c5c Add option to always use SSIV for image decoding
(cherry picked from commit bb4d9fc81a043ac4f2d0105f19c09974ae2f7201)

# Conflicts:
#	CHANGELOG.md
2024-11-03 22:01:55 -05:00
Weblate (bot) cb25deb5ac Translations update from Hosted Weblate (#1111)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/sa/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/as/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/bn/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/cv/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/kk/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/lt/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nb_NO/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/nl/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ro/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sc/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sq/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/th/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/tr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Akhil Raj <89210430+akhi07rx@users.noreply.github.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: AntsyLich <antsylich@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Chiro-kun <chirokun863@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: Eren Eroğlu <ereneroglum@yahoo.com>
Co-authored-by: Fadhil Muhammad <alpanumerik1@gmail.com>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Fordas <fordas15@gmail.com>
Co-authored-by: Frosted <frosted@users.noreply.hosted.weblate.org>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: HDYOU <308485965@qq.com>
Co-authored-by: Homura Akemi <amber_c001@protonmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Itsmechinmoy <itsmechinmoy@users.noreply.hosted.weblate.org>
Co-authored-by: Kryptox <info.kryptox@gmail.com>
Co-authored-by: Leandro Cândido <123888466+marshfellow42@users.noreply.github.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Marco Espinoza <maviesco@gmail.com>
Co-authored-by: Milihraim <kirill06678@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: N. Hao <nguyenviethao2002@gmail.com>
Co-authored-by: NGB-Was-Taken <myalternate34@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Noah Kenzie Rodriguez-Beus <noahbeus@protonmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: SBS1313 <simonsaade005@gmail.com>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Siebrenvde <siebren@siebrenvde.dev>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Valerio Marini <marinivalerio97@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: altinat <al@altqx.com>
Co-authored-by: altinat <altinat@duck.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: orkan gökçe alaz aşina <examplehuman@outlook.com>
Co-authored-by: phlostically <phlostically@mailinator.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: 赤星悠太 <yuta1219aka@gmail.com>
(cherry picked from commit 79e711efc20855f42cb544697edc124963506414)

# Conflicts:
#	i18n/src/commonMain/moko-resources/nl/strings.xml
#	i18n/src/commonMain/moko-resources/vi/strings.xml
#	i18n/src/commonMain/moko-resources/zh-rTW/strings.xml
2024-11-03 22:01:14 -05:00
AntsyLich a6c6cf77bb Address some build warnings and cleanup (#1412)
(cherry picked from commit a1c60897916f418726107fec80ad79b2a4b8d500)
2024-11-03 21:59:24 -05:00
AntsyLich e3dae57e0b Fix long strip images not loading in some old devices
Fixes #1398

(cherry picked from commit 06efc3b25c5af51f42448af27a269ee459d9093d)

# Conflicts:
#	CHANGELOG.md
2024-11-03 21:59:17 -05:00
AntsyLich 226321f334 Fix a rare crash when invoking "Mark previous as read" action
Closes #1421

(cherry picked from commit f508d10ad13560d7316df8642bc93fe66c05b9a8)

# Conflicts:
#	CHANGELOG.md
2024-11-03 21:58:50 -05:00
AntsyLich 2187731d70 Auto format extension repo URLs
Closes #1392
Closes #1393

(cherry picked from commit 22d8aad598bea8f00f2831779e45a6645392ca0f)

# Conflicts:
#	CHANGELOG.md
2024-11-03 21:58:28 -05:00
AntsyLich fd32f2e879 Bump default user agent
(cherry picked from commit 76dcf903403d565056f44c66d965c1ea8affffc3)

# Conflicts:
#	CHANGELOG.md
2024-11-03 21:58:07 -05:00
Mend Renovate 5a094850d1 Update dependency io.coil-kt.coil3:coil-bom to v3.0.0-rc02 (#1401)
(cherry picked from commit f33a6d25209fa9a1291f3dae222fc0ff8d95dba9)
2024-11-03 21:57:47 -05:00
Mend Renovate e74053e989 Update dependency androidx.constraintlayout:constraintlayout to v2.2.0 (#1416)
(cherry picked from commit 2914d166fe0ad5d6bb126fd5fe89d8ca3074787b)
2024-11-03 21:57:39 -05:00
Mend Renovate 798db44908 Update lifecycle.version to v2.8.7 (#1415)
(cherry picked from commit 328ec8c752f276a6e75f68102a257880e4b18753)
2024-11-03 21:57:32 -05:00
MajorTanya 7715b5bdd0 Some improvements to Bangumi tracker search (#1396)
In short:
- fetch & show actual summary
- fallback to "name" if "name_cn" is empty
- request larger responseGroup to get & display the summary & rating
- add type filter query param to make Bangumi filter, not us

Previously, we only displayed the "name" in the summary area and used
"name_cn" as the entry name. However, "name_cn" (Chinese name) can be
an empty string at times, resulting in an awkward looking search
result list where some, many, or even all the results have no title
displayed and only show the "name" (Japanese name) in the summary
area. This has been solved by using "name" as a fallback value should
"name_cn" be empty.

If a Chinese name is available, the original name is prepended to the
summary with the addition "作品原名:" (meaning "original series title").

By using the "responseGroup=large" query parameter, we can request
the required data we need to display the actual summary for an entry
and the entry's average rating.
The "name" is prepended to the summary contents, if any exist, so it
is still accessible for series identification if a "name_cn" exists
too and was used for the result title.

Adding the "type=1" filter query parameter means Bangumi will only
return entries of type 1 ("book") instead of all types and Mihon
needing to filter, resulting in potentially missed entry matches.

(cherry picked from commit 78f9a84b14e0ece988f80d61011f63c0f7e92a67)

# Conflicts:
#	CHANGELOG.md
2024-11-03 21:57:28 -05:00
Mend Renovate 084e11f21d Update dependency androidx.annotation:annotation to v1.9.1 (#1413)
(cherry picked from commit eedece5adfbb95c882d4d59a5020f7e27c634c13)
2024-11-03 21:57:05 -05:00
Mend Renovate 01792c0618 Update dependency androidx.viewpager:viewpager to v1.1.0-beta01 (#1414)
(cherry picked from commit 9d6ddb5d91bd062876bdb108ca3ce278359551e5)
2024-11-03 21:56:57 -05:00
AntsyLich 0b93ceaa8f Switch to spotless 7.0.0 Beta 4
(cherry picked from commit b8b053b1d720a6de5c3d4d8a683eed7bc8cdcc5f)
2024-11-03 21:56:44 -05:00
MajorTanya bfdbe18509 Fix sporadically recurring spotless CI failure (#1407)
Somehow this specific issue keeps getting flagged by unrelated PRs'
CI runs (but only sometimes? Somehow? Other times the CI run would
succeed with no spotless issues.)

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit ed9e13a365ba1b55cec21c26b93b1c62d29485c8)
2024-11-03 21:56:35 -05:00
AntsyLich e3245d0610 Here lies "currentTab was used multiple times"
Fixes #282

(cherry picked from commit 371c1432e218f6dcf129f05405dceb2cd351c647)

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/home/HomeScreen.kt
2024-11-03 21:56:22 -05:00
Jobobby04 c2df6ee54a Fix InterceptActivity crash 2024-11-03 21:03:22 -05:00
Jobobby04 ffc1e2d97b SpotlessApply 2024-10-27 23:08:42 -04:00
Jobobby04 d0c8b0c98a Fix tests 2024-10-27 22:56:04 -04:00
Jobobby04 f206ab8b32 Release 1.11.0 2024-10-27 22:32:00 -04:00
870 changed files with 36081 additions and 13113 deletions
+31 -4
View File
@@ -1,16 +1,43 @@
[*.{kt,kts}]
max_line_length = 120
indent_size = 4
root = true
[*]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{xml,sq,sqm,aidl}]
indent_size = 4
# noinspection EditorConfigKeyCorrectness
[*.{kt,kts}]
indent_size = 4
max_line_length = 120
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
ktlint_code_style = intellij_idea
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_class-signature = disabled
ktlint_standard_comment-wrapping = disabled
ktlint_standard_discouraged-comment-location = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_type-argument-comment = disabled
ktlint_standard_type-parameter-comment = disabled
ktlint_standard_blank-line-between-when-conditions = disabled
# SY
ktlint_standard_filename = disabled
ktlint_standard_argument-list-wrapping = disabled
ktlint_standard_function-naming = disabled
ktlint_standard_property-naming = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_comment-wrapping = disabled
ktlint_standard_max-line-length = disabled
ktlint_standard_value-argument-comment = disabled
ktlint_standard_value-parameter-comment = disabled
+3
View File
@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: ❌ Help with Extensions
url: https://mihon.app/docs/faq/browse/extensions
about: For extension-related questions/issues
- name: 🖥️ Mihon website
url: https://mihon.app/
about: Guides, troubleshooting, and answers to common questions
+9 -9
View File
@@ -43,9 +43,9 @@ body:
attributes:
label: Crash logs
description: |
If you're experiencing crashes, share the crash logs from **More → Settings → Advanced** then press **Dump crash logs**.
If you're experiencing crashes, if possible, go to the app's **More → Settings → Advanced** page, press **Dump crash logs** and share the crash logs here.
placeholder: |
You can paste the crash logs in plain text or upload it as an attachment.
You can upload the crash log file as an attachment, or paste the crash logs in plain text if needed.
- type: input
id: tachiyomisy-version
@@ -53,7 +53,7 @@ body:
label: TachiyomiSY version
description: You can find your TachiyomiSY version in **More → About**.
placeholder: |
Example: "1.10.5"
Example: "1.12.0"
validations:
required: true
@@ -63,7 +63,7 @@ body:
label: Android version
description: You can find this somewhere in your Android settings.
placeholder: |
Example: "Android 11"
Example: "Android 14"
validations:
required: true
@@ -73,7 +73,7 @@ body:
label: Device
description: List your device and model.
placeholder: |
Example: "Google Pixel 5"
Example: "Google Pixel 8"
validations:
required: true
@@ -94,11 +94,11 @@ body:
required: true
- label: I have written a short but informative title.
required: true
- label: I have gone through the [FAQ](https://mihon.app/docs/faq/general) and [troubleshooting guide](https:/mihon.app/docs/guides/troubleshooting/).
- label: I have gone through the [FAQ](https://mihon.app/docs/faq/general) and [troubleshooting guide](https://mihon.app/docs/guides/troubleshooting/).
required: true
- label: I have updated the app to version **[1.10.5](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
- label: I have updated the app to version **[1.12.0](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
required: true
- label: I have updated all installed extensions.
- label: I have filled out all of the requested information in this form, including specific version numbers.
required: true
- label: I will fill out all of the requested information in this form.
- label: I understand that **TachiyomiSY does not have or fix any extensions**, and I **will not receive help** for any issues related to sources or extensions.
required: true
+1 -1
View File
@@ -31,7 +31,7 @@ body:
required: true
- label: I have written a short but informative title.
required: true
- label: I have updated the app to version **[1.10.5](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
- label: I have updated the app to version **[1.12.0](https://github.com/jobobby04/tachiyomisy/releases/latest)**.
required: true
- label: I will fill out all of the requested information in this form.
required: true
+5 -17
View File
@@ -6,40 +6,28 @@ concurrency:
cancel-in-progress: true
jobs:
check_wrapper:
name: Validate Gradle Wrapper
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
build:
name: Build app
needs: check_wrapper
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: 17
distribution: adopt
distribution: temurin
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
- name: Build app
run: ./gradlew spotlessCheck assembleDevDebug
- name: Upload APK
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: TachiyomiSY-${{ github.sha }}.apk
path: app/build/outputs/apk/dev/debug/app-dev-debug.apk
+24 -42
View File
@@ -15,25 +15,22 @@ jobs:
steps:
- name: Clone repo
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
uses: actions/checkout@v6
- name: Setup Android SDK
run: |
${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager "build-tools;29.0.3"
- name: Set up JDK
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: 17
distribution: adopt
distribution: temurin
- name: Set up gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@v5
# SY <--
# SY -->
- name: Write google-services.json
uses: DamianReeves/write-file-action@v1.3
with:
@@ -47,10 +44,16 @@ jobs:
path: app/src/main/assets/client_secrets.json
contents: ${{ secrets.CLIENT_SECRETS_TEXT }}
write-mode: overwrite
# SY -->
# SY <--
- name: Build app and run unit tests
run: ./gradlew spotlessCheck assembleStandardRelease testStandardReleaseUnitTest --stacktrace
- name: Check code format
run: ./gradlew spotlessCheck
- name: Build app
run: ./gradlew assembleStandardRelease
- name: Run unit tests
run: ./gradlew testReleaseUnitTest testStandardReleaseUnitTest
- name: Sign APK
uses: r0adkll/sign-android-release@v1
@@ -60,30 +63,18 @@ jobs:
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
BUILD_TOOLS_VERSION: '35.0.1'
- name: Clean up build artifacts
run: |
set -e
mv app/build/outputs/apk/standard/release/app-standard-universal-release-unsigned-signed.apk TachiyomiSY.apk
sha=`sha256sum TachiyomiSY.apk | awk '{ print $1 }'`
echo "APK_UNIVERSAL_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-arm64-v8a-release-unsigned-signed.apk TachiyomiSY-arm64-v8a.apk
sha=`sha256sum TachiyomiSY-arm64-v8a.apk | awk '{ print $1 }'`
echo "APK_ARM64_V8A_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-armeabi-v7a-release-unsigned-signed.apk TachiyomiSY-armeabi-v7a.apk
sha=`sha256sum TachiyomiSY-armeabi-v7a.apk | awk '{ print $1 }'`
echo "APK_ARMEABI_V7A_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-x86-release-unsigned-signed.apk TachiyomiSY-x86.apk
sha=`sha256sum TachiyomiSY-x86.apk | awk '{ print $1 }'`
echo "APK_X86_SHA=$sha" >> $GITHUB_ENV
cp app/build/outputs/apk/standard/release/app-standard-x86_64-release-unsigned-signed.apk TachiyomiSY-x86_64.apk
sha=`sha256sum TachiyomiSY-x86_64.apk | awk '{ print $1 }'`
echo "APK_X86_64_SHA=$sha" >> $GITHUB_ENV
mv app/build/outputs/apk/standard/release/app-standard-arm64-v8a-release-unsigned-signed.apk TachiyomiSY-arm64-v8a.apk
mv app/build/outputs/apk/standard/release/app-standard-armeabi-v7a-release-unsigned-signed.apk TachiyomiSY-armeabi-v7a.apk
mv app/build/outputs/apk/standard/release/app-standard-x86-release-unsigned-signed.apk TachiyomiSY-x86.apk
mv app/build/outputs/apk/standard/release/app-standard-x86_64-release-unsigned-signed.apk TachiyomiSY-x86_64.apk
- name: Create release
uses: softprops/action-gh-release@v2
@@ -91,19 +82,10 @@ jobs:
tag_name: ${{ github.run_number }}
name: TachiyomiSY
body: |
---
### Checksums
| Variant | SHA-256 |
| ------- | ------- |
| Universal | ${{ env.APK_UNIVERSAL_SHA }} |
| arm64-v8a | ${{ env.APK_ARM64_V8A_SHA }} |
| armeabi-v7a | ${{ env.APK_ARMEABI_V7A_SHA }} |
| x86 | ${{ env.APK_X86_SHA }} |
| x86_64 | ${{ env.APK_X86_64_SHA }} |
## If you are unsure which version to choose then go with TachiyomiSY.apk
<!-->
> [!TIP]
>
> ### If you are unsure which version to download then go with `TachiyomiSY.apk`
files: |
TachiyomiSY.apk
TachiyomiSY-arm64-v8a.apk
+12 -3
View File
@@ -12,10 +12,16 @@ jobs:
steps:
- name: Clone repo
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: 17
distribution: temurin
- name: Set up gradle
uses: gradle/actions/setup-gradle@v5
- name: Create Tag
run: |
@@ -28,3 +34,6 @@ jobs:
-H 'Accept: application/vnd.github.everest-preview+json' \
-u ${{ secrets.ACCESS_TOKEN }} \
--data '{"event_type": "ping", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'" }}'
- name: Run unit tests
run: ./gradlew testDebugUnitTest testDevDebugUnitTest
+1 -1
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Moderate issues
uses: tachiyomiorg/issue-moderator-action@v2.6.0
uses: tachiyomiorg/issue-moderator-action@v2.6.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
duplicate-label: Duplicate
-19
View File
@@ -1,19 +0,0 @@
name: Lock threads
on:
# Daily
schedule:
- cron: '0 0 * * *'
# Manual trigger
workflow_dispatch:
inputs:
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-inactive-days: '2'
pr-inactive-days: '2'
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
steps:
- name: Check PR and Add Label
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const prAuthor = context.payload.pull_request.user.login;
+1 -1
View File
@@ -60,7 +60,7 @@ Additional features for some extensions, features include custom description, op
* Mangadex
* NHentai
* Puruin
* Tsumino
* LANraragi
## Download
Get the app from our [releases page](https://github.com/jobobby04/tachiyomisy/releases/latest).
+136 -121
View File
@@ -1,15 +1,19 @@
import mihon.buildlogic.getBuildTime
import mihon.buildlogic.getCommitCount
import mihon.buildlogic.getGitSha
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import mihon.gradle.getBuildTime
import mihon.gradle.getLatestCommitCount
import mihon.gradle.getLatestCommitSha
import mihon.gradle.tasks.ReplaceShortcutsPlaceholderTask
plugins {
id("mihon.android.application")
id("mihon.android.application.compose")
alias(mihonx.plugins.android.application)
alias(mihonx.plugins.compose)
alias(mihonx.plugins.spotless)
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
// id("com.github.zellius.shortcut-helper")
alias(libs.plugins.aboutLibraries)
alias(libs.plugins.kotlin.serialization)
id("com.github.ben-manes.versions")
}
@@ -20,42 +24,26 @@ if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
}
}
// shortcutHelper.setFilePath("./shortcuts.xml")
val supportedAbis = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
android {
namespace = "eu.kanade.tachiyomi"
defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy"
versionCode = 69
versionName = "1.10.5"
versionCode = 77
versionName = "1.12.0"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime()}\"")
buildConfigField("String", "COMMIT_COUNT", "\"${getLatestCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getLatestCommitSha()}\"")
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime(useLatestCommitTime = false)}\"")
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
ndk {
abiFilters += supportedAbis
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
splits {
abi {
isEnable = true
reset()
include(*supportedAbis.toTypedArray())
isUniversalApk = true
}
}
buildTypes {
named("debug") {
versionNameSuffix = "-${getCommitCount()}"
versionNameSuffix = "-${getLatestCommitCount()}"
applicationIdSuffix = ".debug"
isPseudoLocalesEnabled = true
}
@@ -70,6 +58,8 @@ android {
isMinifyEnabled = true
isShrinkResources = true
setProguardFiles(listOf(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"))
buildConfigField("String", "BUILD_TIME", "\"${getBuildTime(useLatestCommitTime = true)}\"")
}
create("benchmark") {
initWith(getByName("release"))
@@ -87,6 +77,15 @@ android {
getByName("benchmark").res.srcDirs("src/debug/res")
}
splits {
abi {
isEnable = true
isUniversalApk = true
reset()
include("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
}
}
flavorDimensions.add("default")
productFlavors {
@@ -98,27 +97,36 @@ android {
dimension = "default"
}
create("dev") {
// Include pseudolocales: https://developer.android.com/guide/topics/resources/pseudolocales
resourceConfigurations.addAll(listOf("en", "en_XA", "ar_XB", "xxhdpi"))
dimension = "default"
}
}
packaging {
resources.excludes.addAll(
listOf(
jniLibs {
keepDebugSymbols += listOf(
"libandroidx.graphics.path",
"libarchive-jni",
"libconscrypt_jni",
"libimagedecoder",
"libquickjs",
"libsqlite3x",
)
.map { "**/$it.so" }
}
resources {
excludes += setOf(
"kotlin-tooling-metadata.json",
"META-INF/DEPENDENCIES",
"LICENSE.txt",
"META-INF/LICENSE",
"META-INF/**/*.properties",
"META-INF/**/LICENSE.txt",
"META-INF/*.properties",
"META-INF/**/*.properties",
"META-INF/README.md",
"META-INF/NOTICE",
"META-INF/*.version",
),
)
"META-INF/DEPENDENCIES",
"META-INF/LICENSE",
"META-INF/NOTICE",
"META-INF/README.md",
)
}
}
dependenciesInfo {
@@ -128,9 +136,9 @@ android {
buildFeatures {
viewBinding = true
buildConfig = true
aidl = true
// Disable some unused things
aidl = false
renderScript = false
shaders = false
}
@@ -141,6 +149,26 @@ android {
}
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll(
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3ExpressiveApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
"-Xannotation-default-target=param-property",
)
}
}
dependencies {
implementation(projects.i18n)
// SY -->
@@ -156,95 +184,95 @@ dependencies {
implementation(projects.presentationWidget)
// Compose
implementation(compose.activity)
implementation(compose.foundation)
implementation(compose.material3.core)
implementation(compose.material.icons)
implementation(compose.animation)
implementation(compose.animation.graphics)
debugImplementation(compose.ui.tooling)
implementation(compose.ui.tooling.preview)
implementation(compose.ui.util)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.materialIcons)
implementation(libs.androidx.compose.animation)
implementation(libs.androidx.compose.animationGraphics)
debugImplementation(libs.androidx.compose.uiTooling)
implementation(libs.androidx.compose.uiToolingPreview)
implementation(libs.androidx.compose.uiUtil)
implementation(androidx.interpolator)
implementation(libs.androidx.interpolator)
implementation(androidx.paging.runtime)
implementation(androidx.paging.compose)
implementation(libs.androidx.paging.runtime)
implementation(libs.androidx.paging.compose)
implementation(libs.bundles.sqlite)
implementation(libs.androidx.sqlite.bundled)
// SY -->
implementation(sylibs.sqlcipher)
// SY <--
implementation(kotlinx.reflect)
implementation(kotlinx.immutables)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.collections.immutable)
implementation(platform(kotlinx.coroutines.bom))
implementation(kotlinx.bundles.coroutines)
implementation(libs.bundles.kotlinx.coroutines)
// AndroidX libraries
implementation(androidx.annotation)
implementation(androidx.appcompat)
implementation(androidx.biometricktx)
implementation(androidx.constraintlayout)
implementation(androidx.corektx)
implementation(androidx.splashscreen)
implementation(androidx.recyclerview)
implementation(androidx.viewpager)
implementation(androidx.profileinstaller)
implementation(libs.androidx.annotation)
implementation(libs.androidx.appCompat)
implementation(libs.androidx.biometric)
implementation(libs.androidx.constraintLayout)
implementation(libs.androidx.core)
implementation(libs.androidx.coreSplashScreen)
implementation(libs.androidx.recyclerView)
implementation(libs.androidx.viewPager)
implementation(libs.androidx.profileInstaller)
implementation(androidx.bundles.lifecycle)
implementation(libs.bundles.androidx.lifecycle)
// Job scheduling
implementation(androidx.workmanager)
implementation(libs.androidx.work)
// RxJava
implementation(libs.rxjava)
implementation(libs.rxJava)
// Networking
implementation(libs.bundles.okhttp)
implementation(libs.okio)
implementation(libs.conscrypt.android) // TLS 1.3 support for Android < 10
implementation(libs.conscrypt) // TLS 1.3 support for Android < 10
// Data serialization (JSON, protobuf, xml)
implementation(kotlinx.bundles.serialization)
implementation(libs.bundles.serialization)
// HTML parser
implementation(libs.jsoup)
// Disk
implementation(libs.disklrucache)
implementation(libs.diskLruCache)
implementation(libs.unifile)
// Preferences
implementation(libs.preferencektx)
implementation(libs.androidx.preference)
// Dependency injection
implementation(libs.injekt.core)
implementation(libs.injekt)
// Image loading
implementation(platform(libs.coil.bom))
implementation(libs.bundles.coil)
implementation(libs.subsamplingscaleimageview) {
implementation(libs.subsamplingScaleImageView) {
exclude(module = "image-decoder")
}
implementation(libs.image.decoder)
// UI libraries
implementation(libs.material)
implementation(libs.flexible.adapter.core)
implementation(libs.photoview)
implementation(libs.directionalviewpager) {
implementation(libs.flexibleAdapter)
implementation(libs.photoView)
implementation(libs.directionalViewPager) {
exclude(group = "androidx.viewpager", module = "viewpager")
}
implementation(libs.insetter)
implementation(libs.bundles.richtext)
implementation(libs.composeRichEditor)
implementation(libs.aboutLibraries.compose)
implementation(libs.bundles.voyager)
implementation(libs.compose.materialmotion)
implementation(libs.composeMaterialMotion)
implementation(libs.swipe)
implementation(libs.compose.webview)
implementation(libs.compose.grid)
implementation(libs.composeWebview)
implementation(libs.composeGrid)
implementation(libs.reorderable)
implementation(libs.bundles.markdown)
implementation(libs.materialKolor)
// Logging
implementation(libs.logcat)
@@ -257,19 +285,20 @@ dependencies {
// Shizuku
implementation(libs.bundles.shizuku)
// String similarity
implementation(libs.stringSimilarity)
// Tests
testImplementation(libs.bundles.test)
testRuntimeOnly(libs.junit.platform.launcher)
// For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation(libs.leakcanary.android)
implementation(libs.leakcanary.plumber)
// debugImplementation(libs.leakCanary.android)
implementation(libs.leakCanary.plumber)
testImplementation(kotlinx.coroutines.test)
testImplementation(libs.kotlinx.coroutines.test)
// SY -->
// Text distance (EH)
implementation(sylibs.simularity)
// Firebase (EH)
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
@@ -289,17 +318,25 @@ dependencies {
// Koin
implementation(sylibs.koin.core)
implementation(sylibs.koin.android)
// ZXing Android Embedded
implementation(sylibs.zxing.android.embedded)
}
androidComponents {
beforeVariants { variantBuilder ->
// Disables standardBenchmark
if (variantBuilder.buildType == "benchmark") {
variantBuilder.enable = variantBuilder.productFlavors.containsAll(
listOf("default" to "dev"),
)
onVariants { variant ->
val resSource = variant.sources.res ?: return@onVariants
val variantName = variant.name.replaceFirstChar { it.uppercase() }
val replaceShortcutsPlaceholderTask = tasks.register<ReplaceShortcutsPlaceholderTask>(
"replace${variantName}ShortcutPlaceholder",
) {
applicationId.set(variant.applicationId)
shortcutsFile.set(projectDir.resolve("src/main/shortcuts.xml"))
}
resSource.addGeneratedSourceDirectory(replaceShortcutsPlaceholderTask) { it.outputDir }
}
onVariants(selector().withFlavor("default" to "standard")) {
// Only excluding in standard flavor because this breaks
// Layout Inspector's Compose tree
@@ -307,30 +344,8 @@ androidComponents {
}
}
tasks {
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> {
compilerOptions.freeCompilerArgs.addAll(
"-Xcontext-receivers",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
"-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
)
}
}
buildscript {
dependencies {
classpath(kotlinx.gradle)
classpath(libs.kotlin.gradle)
}
}
+2
View File
@@ -299,3 +299,5 @@
-dontwarn org.ietf.jgss.GSSManager
-dontwarn org.ietf.jgss.GSSName
-dontwarn org.ietf.jgss.Oid
-dontwarn com.google.re2j.Matcher
-dontwarn com.google.re2j.Pattern
+5 -1
View File
@@ -359,7 +359,7 @@
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="pururin.io" />
<data android:host="pururin.me" />
<data android:pathPattern="/gallery/..*" />
</intent-filter>
@@ -413,6 +413,10 @@
android:scheme="tachiyomisy" />
</intent-filter>
</activity>
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
tools:remove="screenOrientation" />
</application>
<uses-sdk tools:overrideLibrary="rikka.shizuku.api"
@@ -0,0 +1,7 @@
package mihon.app.shizuku;
interface IShellInterface {
void install(in AssetFileDescriptor apk) = 1;
void destroy() = 16777114;
}
@@ -1,5 +1,6 @@
package eu.kanade.core.util
import androidx.compose.ui.util.fastFilter
import androidx.compose.ui.util.fastForEach
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@@ -45,21 +46,6 @@ fun <E> HashSet<E>.addOrRemove(value: E, shouldAdd: Boolean) {
}
}
/**
* Returns a list containing only elements matching the given [predicate].
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@OptIn(ExperimentalContracts::class)
inline fun <T> List<T>.fastFilter(predicate: (T) -> Boolean): List<T> {
contract { callsInPlace(predicate) }
val destination = ArrayList<T>()
fastForEach { if (predicate(it)) destination.add(it) }
return destination
}
/**
* Returns a list containing all elements not matching the given [predicate].
*
@@ -70,27 +56,7 @@ inline fun <T> List<T>.fastFilter(predicate: (T) -> Boolean): List<T> {
@OptIn(ExperimentalContracts::class)
inline fun <T> List<T>.fastFilterNot(predicate: (T) -> Boolean): List<T> {
contract { callsInPlace(predicate) }
val destination = ArrayList<T>()
fastForEach { if (!predicate(it)) destination.add(it) }
return destination
}
/**
* Returns a list containing only the non-null results of applying the
* given [transform] function to each element in the original collection.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@OptIn(ExperimentalContracts::class)
inline fun <T, R> List<T>.fastMapNotNull(transform: (T) -> R?): List<R> {
contract { callsInPlace(transform) }
val destination = ArrayList<R>()
fastForEach { element ->
transform(element)?.let(destination::add)
}
return destination
return fastFilter { !predicate(it) }
}
/**
@@ -131,26 +97,3 @@ inline fun <T> List<T>.fastCountNot(predicate: (T) -> Boolean): Int {
fastForEach { if (predicate(it)) --count }
return count
}
/**
* Returns a list containing only elements from the given collection
* having distinct keys returned by the given [selector] function.
*
* Among elements of the given collection with equal keys, only the first one will be present in the resulting list.
* The elements in the resulting list are in the same order as they were in the source collection.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@OptIn(ExperimentalContracts::class)
inline fun <T, K> List<T>.fastDistinctBy(selector: (T) -> K): List<T> {
contract { callsInPlace(selector) }
val set = HashSet<K>()
val list = ArrayList<T>()
fastForEach {
val key = selector(it)
if (set.add(key)) list.add(it)
}
return list
}
@@ -13,9 +13,11 @@ import eu.kanade.domain.manga.interactor.SetExcludedScanlators
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.source.interactor.GetEnabledSources
import eu.kanade.domain.source.interactor.GetIncognitoState
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.domain.source.interactor.ToggleIncognito
import eu.kanade.domain.source.interactor.ToggleLanguage
import eu.kanade.domain.source.interactor.ToggleSource
import eu.kanade.domain.source.interactor.ToggleSourcePin
@@ -36,6 +38,7 @@ import mihon.domain.extensionrepo.interactor.ReplaceExtensionRepo
import mihon.domain.extensionrepo.interactor.UpdateExtensionRepo
import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
import mihon.domain.extensionrepo.service.ExtensionRepoService
import mihon.domain.migration.usecases.MigrateMangaUseCase
import mihon.domain.upcoming.interactor.GetUpcomingManga
import tachiyomi.data.category.CategoryRepositoryImpl
import tachiyomi.data.chapter.ChapterRepositoryImpl
@@ -57,6 +60,7 @@ import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.category.interactor.SetSortModeForCategory
import tachiyomi.domain.category.interactor.UpdateCategory
import tachiyomi.domain.category.repository.CategoryRepository
import tachiyomi.domain.chapter.interactor.GetBookmarkedChaptersByMangaId
import tachiyomi.domain.chapter.interactor.GetChapter
import tachiyomi.domain.chapter.interactor.GetChapterByUrlAndMangaId
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
@@ -80,6 +84,7 @@ import tachiyomi.domain.manga.interactor.GetMangaWithChapters
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
import tachiyomi.domain.manga.interactor.ResetViewerFlags
import tachiyomi.domain.manga.interactor.SetMangaChapterFlags
import tachiyomi.domain.manga.interactor.UpdateMangaNotes
import tachiyomi.domain.manga.repository.MangaRepository
import tachiyomi.domain.release.interactor.GetApplicationRelease
import tachiyomi.domain.release.service.ReleaseService
@@ -108,7 +113,7 @@ class DomainModule : InjektModule {
addFactory { RenameCategory(get()) }
addFactory { ReorderCategory(get()) }
addFactory { UpdateCategory(get()) }
addFactory { DeleteCategory(get()) }
addFactory { DeleteCategory(get(), get(), get()) }
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
addFactory { GetDuplicateLibraryManga(get()) }
@@ -126,9 +131,15 @@ class DomainModule : InjektModule {
addFactory { SetMangaViewerFlags(get()) }
addFactory { NetworkToLocalManga(get()) }
addFactory { UpdateManga(get(), get()) }
addFactory { UpdateMangaNotes(get()) }
addFactory { SetMangaCategories(get()) }
addFactory { GetExcludedScanlators(get()) }
addFactory { SetExcludedScanlators(get()) }
addFactory {
MigrateMangaUseCase(
get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(),
)
}
addSingletonFactory<ReleaseService> { ReleaseServiceImpl(get(), get()) }
addFactory { GetApplicationRelease(get(), get()) }
@@ -146,11 +157,12 @@ class DomainModule : InjektModule {
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
addFactory { GetChapter(get()) }
addFactory { GetChaptersByMangaId(get()) }
addFactory { GetBookmarkedChaptersByMangaId(get(), get(), get()) }
addFactory { GetChapterByUrlAndMangaId(get()) }
addFactory { UpdateChapter(get()) }
addFactory { SetReadStatus(get(), get(), get(), get(), get()) }
addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get()) }
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
addFactory { GetAvailableScanlators(get()) }
addFactory { FilterChaptersForDownload(get(), get(), get(), get()) }
@@ -190,5 +202,7 @@ class DomainModule : InjektModule {
addFactory { DeleteExtensionRepo(get()) }
addFactory { ReplaceExtensionRepo(get()) }
addFactory { UpdateExtensionRepo(get(), get()) }
addFactory { ToggleIncognito(get()) }
addFactory { GetIncognitoState(get(), get(), get()) }
}
}
@@ -28,7 +28,6 @@ import tachiyomi.data.source.SavedSearchRepositoryImpl
import tachiyomi.domain.chapter.interactor.DeleteChapters
import tachiyomi.domain.chapter.interactor.GetChapterByUrl
import tachiyomi.domain.chapter.interactor.GetMergedChaptersByMangaId
import tachiyomi.domain.history.interactor.GetHistoryByMangaId
import tachiyomi.domain.manga.interactor.DeleteByMergeId
import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries
import tachiyomi.domain.manga.interactor.DeleteMangaById
@@ -88,7 +87,6 @@ class SYDomainModule : InjektModule {
addFactory { DeleteChapters(get()) }
addFactory { DeleteMangaById(get()) }
addFactory { FilterSerializer() }
addFactory { GetHistoryByMangaId(get()) }
addFactory { GetChapterByUrl(get()) }
addFactory { GetSourceCategories(get()) }
addFactory { CreateSourceCategory(get()) }
@@ -2,25 +2,29 @@ package eu.kanade.domain.base
import android.content.Context
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.util.system.GLUtil
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.i18n.MR
class BasePreferences(
val context: Context,
private val preferenceStore: PreferenceStore,
preferenceStore: PreferenceStore,
) {
fun downloadedOnly() = preferenceStore.getBoolean(
val downloadedOnly: Preference<Boolean> = preferenceStore.getBoolean(
Preference.appStateKey("pref_downloaded_only"),
false,
)
fun incognitoMode() = preferenceStore.getBoolean(Preference.appStateKey("incognito_mode"), false)
val incognitoMode: Preference<Boolean> = preferenceStore.getBoolean(Preference.appStateKey("incognito_mode"), false)
fun extensionInstaller() = ExtensionInstallerPreference(context, preferenceStore)
val extensionInstaller: ExtensionInstallerPreference = ExtensionInstallerPreference(context, preferenceStore)
fun shownOnboardingFlow() = preferenceStore.getBoolean(Preference.appStateKey("onboarding_complete"), false)
val shownOnboardingFlow: Preference<Boolean> = preferenceStore.getBoolean(
Preference.appStateKey("onboarding_complete"),
false,
)
enum class ExtensionInstaller(val titleRes: StringResource, val requiresSystemPermission: Boolean) {
LEGACY(MR.strings.ext_installer_legacy, true),
@@ -29,5 +33,17 @@ class BasePreferences(
PRIVATE(MR.strings.ext_installer_private, false),
}
fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "")
val displayProfile: Preference<String> = preferenceStore.getString("pref_display_profile_key", "")
val hardwareBitmapThreshold: Preference<Int> = preferenceStore.getInt(
"pref_hardware_bitmap_threshold",
GLUtil.SAFE_TEXTURE_LIMIT,
)
val alwaysDecodeLongStripWithSSIV: Preference<Boolean> = preferenceStore.getBoolean(
"pref_always_decode_long_strip_with_ssiv",
false,
)
val installationId: Preference<String> = preferenceStore.getString(Preference.appStateKey("installation_id"), "")
}
@@ -51,7 +51,7 @@ class SetReadStatus(
return@withNonCancellableContext Result.InternalError(e)
}
if (read && downloadPreferences.removeAfterMarkedAsRead().get()) {
if (read && downloadPreferences.removeAfterMarkedAsRead.get()) {
chaptersToUpdate
.groupBy { it.mangaId }
.forEach { (mangaId, chapters) ->
@@ -20,6 +20,7 @@ import tachiyomi.domain.chapter.model.NoChaptersException
import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.chapter.repository.ChapterRepository
import tachiyomi.domain.chapter.service.ChapterRecognition
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.model.Manga
import tachiyomi.source.local.isLocal
import java.lang.Long.max
@@ -35,6 +36,7 @@ class SyncChaptersWithSource(
private val updateChapter: UpdateChapter,
private val getChaptersByMangaId: GetChaptersByMangaId,
private val getExcludedScanlators: GetExcludedScanlators,
private val libraryPreferences: LibraryPreferences,
) {
/**
@@ -117,6 +119,7 @@ class SyncChaptersWithSource(
downloadManager.isChapterDownloaded(
dbChapter.name,
dbChapter.scanlator,
dbChapter.url,
/* SY --> */ manga.ogTitle /* SY <-- */,
manga.source,
)
@@ -124,12 +127,14 @@ class SyncChaptersWithSource(
if (shouldRenameChapter) {
downloadManager.renameChapter(source, manga, dbChapter, chapter)
}
var toChangeChapter = dbChapter.copy(
name = chapter.name,
chapterNumber = chapter.chapterNumber,
scanlator = chapter.scanlator,
sourceOrder = chapter.sourceOrder,
)
if (chapter.dateUpload != 0L) {
toChangeChapter = toChangeChapter.copy(dateUpload = chapter.dateUpload)
}
@@ -150,12 +155,18 @@ class SyncChaptersWithSource(
return emptyList()
}
val reAdded = mutableListOf<Chapter>()
val changedOrDuplicateReadUrls = mutableSetOf<String>()
val deletedChapterNumbers = TreeSet<Double>()
val deletedReadChapterNumbers = TreeSet<Double>()
val deletedBookmarkedChapterNumbers = TreeSet<Double>()
val readChapterNumbers = dbChapters
.asSequence()
.filter { it.read && it.isRecognizedNumber }
.map { it.chapterNumber }
.toSet()
removedChapters.forEach { chapter ->
if (chapter.read) deletedReadChapterNumbers.add(chapter.chapterNumber)
if (chapter.bookmark) deletedBookmarkedChapterNumbers.add(chapter.chapterNumber)
@@ -165,12 +176,20 @@ class SyncChaptersWithSource(
val deletedChapterNumberDateFetchMap = removedChapters.sortedByDescending { it.dateFetch }
.associate { it.chapterNumber to it.dateFetch }
val markDuplicateAsRead = libraryPreferences.markDuplicateReadChapterAsRead.get()
.contains(LibraryPreferences.MARK_DUPLICATE_CHAPTER_READ_NEW)
// Date fetch is set in such a way that the upper ones will have bigger value than the lower ones
// Sources MUST return the chapters from most to less recent, which is common.
var itemCount = newChapters.size
var updatedToAdd = newChapters.map { toAddItem ->
var chapter = toAddItem.copy(dateFetch = nowMillis + itemCount--)
if (chapter.chapterNumber in readChapterNumbers && markDuplicateAsRead) {
changedOrDuplicateReadUrls.add(chapter.url)
chapter = chapter.copy(read = true)
}
if (!chapter.isRecognizedNumber || chapter.chapterNumber !in deletedChapterNumbers) return@map chapter
chapter = chapter.copy(
@@ -183,19 +202,19 @@ class SyncChaptersWithSource(
chapter = chapter.copy(dateFetch = it)
}
reAdded.add(chapter)
changedOrDuplicateReadUrls.add(chapter.url)
chapter
}
// --> EXH (carry over reading progress)
if (manga.isEhBasedManga()) {
val finalAdded = updatedToAdd.subtract(reAdded)
val finalAdded = updatedToAdd.filterNot { it.url in changedOrDuplicateReadUrls }
if (finalAdded.isNotEmpty()) {
val max = dbChapters.maxOfOrNull { it.lastPageRead }
if (max != null && max > 0) {
updatedToAdd = updatedToAdd.map {
if (it !in reAdded) {
if (it.url !in changedOrDuplicateReadUrls) {
it.copy(lastPageRead = max)
} else {
it
@@ -225,12 +244,8 @@ class SyncChaptersWithSource(
// Note that last_update actually represents last time the chapter list changed at all
updateManga.awaitUpdateLastUpdate(manga.id)
val reAddedUrls = reAdded.map { it.url }.toHashSet()
val excludedScanlators = getExcludedScanlators.await(manga.id).toHashSet()
return updatedToAdd.filterNot {
it.url in reAddedUrls || it.scanlator in excludedScanlators
}
return updatedToAdd.filterNot { it.url in changedOrDuplicateReadUrls || it.scanlator in excludedScanlators }
}
}
@@ -34,6 +34,7 @@ fun List<Chapter>.applyFilters(
val downloaded = downloadManager.isChapterDownloaded(
chapter.name,
chapter.scanlator,
chapter.url,
/* SY --> */ manga.ogTitle /* SY <-- */,
manga.source,
)
@@ -12,7 +12,7 @@ class GetExtensionLanguages(
) {
fun subscribe(): Flow<List<String>> {
return combine(
preferences.enabledLanguages().changes(),
preferences.enabledLanguages.changes(),
extensionManager.availableExtensionsFlow,
) { enabledLanguage, availableExtensions ->
availableExtensions
@@ -15,7 +15,7 @@ class GetExtensionSources(
val isMultiLangSingleSource =
isMultiSource && extension.sources.map { it.name }.distinct().size == 1
return preferences.disabledSources().changes().map { disabledSources ->
return preferences.disabledSources.changes().map { disabledSources ->
fun Source.isEnabled() = id.toString() !in disabledSources
extension.sources
@@ -13,10 +13,10 @@ class GetExtensionsByType(
) {
fun subscribe(): Flow<Extensions> {
val showNsfwSources = preferences.showNsfwSource().get()
val showNsfwSources = preferences.showNsfwSource.get()
return combine(
preferences.enabledLanguages().changes(),
preferences.enabledLanguages.changes(),
extensionManager.installedExtensionsFlow,
extensionManager.untrustedExtensionsFlow,
extensionManager.availableExtensionsFlow,
@@ -14,11 +14,11 @@ class TrustExtension(
suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean {
val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet()
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}"
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get()
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions.get()
}
fun trust(pkgName: String, versionCode: Long, signatureHash: String) {
preferences.trustedExtensions().getAndSet { exts ->
preferences.trustedExtensions.getAndSet { exts ->
// Remove previously trusted versions
val removed = exts.filterNot { it.startsWith("$pkgName:") }.toMutableSet()
@@ -27,6 +27,6 @@ class TrustExtension(
}
fun revokeAll() {
preferences.trustedExtensions().delete()
preferences.trustedExtensions.delete()
}
}
@@ -15,9 +15,9 @@ class CreateSortTag(
return Result.TagExists
}
val size = preferences.sortTagsForLibrary().get().size
val size = preferences.sortTagsForLibrary.get().size
preferences.sortTagsForLibrary() += encodeTag(size, tag)
preferences.sortTagsForLibrary += encodeTag(size, tag)
return Result.Success
}
@@ -8,7 +8,7 @@ class DeleteSortTag(
) {
fun await(tag: String) {
preferences.sortTagsForLibrary().set(
preferences.sortTagsForLibrary.set(
(getSortTag.await() - tag).mapIndexed { index, s ->
CreateSortTag.encodeTag(index, s)
}.toSet(),
@@ -23,7 +23,7 @@ class GetPagePreviews(
return try {
val pagePreviews = try {
pagePreviewCache.getPageListFromCache(manga, chapterIds, page)
} catch (e: Exception) {
} catch (_: Exception) {
source.getPagePreviewList(manga.toSManga(), chapters.map { it.toSChapter() }, page).also {
pagePreviewCache.putPageListToCache(manga, chapterIds, it)
}
@@ -7,14 +7,14 @@ import tachiyomi.domain.library.service.LibraryPreferences
class GetSortTag(private val preferences: LibraryPreferences) {
fun subscribe(): Flow<List<String>> {
return preferences.sortTagsForLibrary().changes()
return preferences.sortTagsForLibrary.changes()
.map(::mapSortTags)
}
fun await() = getSortTags(preferences).let(::mapSortTags)
companion object {
fun getSortTags(preferences: LibraryPreferences) = preferences.sortTagsForLibrary().get()
fun getSortTags(preferences: LibraryPreferences) = preferences.sortTagsForLibrary.get()
fun mapSortTags(tags: Set<String>) = tags.mapNotNull {
val index = it.indexOf('|')
@@ -23,7 +23,7 @@ class ReorderSortTag(
val reorderedTag = reorderedTags.removeAt(currentIndex)
reorderedTags.add(newPosition, reorderedTag)
preferences.sortTagsForLibrary().set(
preferences.sortTagsForLibrary.set(
reorderedTags.mapIndexed { index, s ->
CreateSortTag.encodeTag(index, s)
}.toSet(),
@@ -4,6 +4,7 @@ import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.model.SManga
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.interactor.FetchInterval
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaUpdate
@@ -32,9 +33,8 @@ class UpdateManga(
remoteManga: SManga,
manualFetch: Boolean,
coverCache: CoverCache = Injekt.get(),
// SY -->
libraryPreferences: LibraryPreferences = Injekt.get(),
downloadManager: DownloadManager = Injekt.get(),
// SY <--
): Boolean {
val remoteTitle = try {
remoteManga.title
@@ -42,14 +42,13 @@ class UpdateManga(
""
}
// SY -->
val title = if (remoteTitle.isNotBlank() && localManga.ogTitle != remoteTitle) {
downloadManager.renameMangaDir(localManga.ogTitle, remoteTitle, localManga.source)
remoteTitle
} else {
null
}
// SY <--
// if the manga isn't a favorite (or 'update titles' preference is enabled), set its title from source and update in db
val title =
if (remoteTitle.isNotEmpty() && (!localManga.favorite || libraryPreferences.updateMangaTitles.get())) {
remoteTitle
} else {
null
}
val coverLastModified =
when {
@@ -69,7 +68,7 @@ class UpdateManga(
val thumbnailUrl = remoteManga.thumbnail_url?.takeIf { it.isNotEmpty() }
return mangaRepository.update(
val success = mangaRepository.update(
MangaUpdate(
id = localManga.id,
title = title,
@@ -84,6 +83,10 @@ class UpdateManga(
initialized = true,
),
)
if (success && title != null) {
downloadManager.renameManga(localManga, title)
}
return success
}
suspend fun awaitUpdateFetchInterval(
@@ -23,7 +23,7 @@ val Manga.readerOrientation: Long
val Manga.downloadedFilter: TriState
get() {
if (forceDownloaded()) return TriState.ENABLED_IS
if (Injekt.get<BasePreferences>().downloadedOnly.get()) return TriState.ENABLED_IS
return when (downloadedFilterRaw) {
Manga.CHAPTER_SHOW_DOWNLOADED -> TriState.ENABLED_IS
Manga.CHAPTER_SHOW_NOT_DOWNLOADED -> TriState.ENABLED_NOT
@@ -35,18 +35,17 @@ fun Manga.chaptersFiltered(): Boolean {
downloadedFilter != TriState.DISABLED ||
bookmarkedFilter != TriState.DISABLED
}
fun Manga.forceDownloaded(): Boolean {
return favorite && Injekt.get<BasePreferences>().downloadedOnly().get()
}
fun Manga.toSManga(): SManga = SManga.create().also {
it.url = url
it.title = title
it.artist = artist
it.author = author
it.description = description
it.genre = genre.orEmpty().joinToString()
it.status = status.toInt()
// SY -->
it.title = ogTitle
it.artist = ogArtist
it.author = ogAuthor
it.description = ogDescription
it.genre = ogGenre.orEmpty().joinToString()
it.status = ogStatus.toInt()
// SY <--
it.thumbnail_url = thumbnailUrl
it.initialized = initialized
}
@@ -79,24 +78,6 @@ fun Manga.copyFrom(other: SManga): Manga {
)
}
fun SManga.toDomainManga(sourceId: Long): Manga {
return Manga.create().copy(
url = url,
// SY -->
ogTitle = title,
ogArtist = artist,
ogAuthor = author,
ogThumbnailUrl = thumbnail_url,
ogDescription = description,
ogGenre = getGenres(),
ogStatus = status.toLong(),
// SY <--
updateStrategy = update_strategy,
initialized = initialized,
source = sourceId,
)
}
fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
return coverCache.getCustomCoverFile(id).exists()
}
@@ -11,7 +11,7 @@ class CreateSourceCategory(private val preferences: SourcePreferences) {
}
// Create category.
preferences.sourcesTabCategories() += category
preferences.sourcesTabCategories += category
return Result.Success
}
@@ -7,9 +7,9 @@ import tachiyomi.core.common.preference.minusAssign
class DeleteSourceCategory(private val preferences: SourcePreferences) {
fun await(category: String) {
preferences.sourcesTabSourcesInCategories().getAndSet { sourcesInCategories ->
preferences.sourcesTabSourcesInCategories.getAndSet { sourcesInCategories ->
sourcesInCategories.filterNot { it.substringAfter("|") == category }.toSet()
}
preferences.sourcesTabCategories() -= category
preferences.sourcesTabCategories -= category
}
}
@@ -18,17 +18,17 @@ class GetEnabledSources(
fun subscribe(): Flow<List<Source>> {
return combine(
preferences.pinnedSources().changes(),
preferences.pinnedSources.changes(),
combine(
preferences.enabledLanguages().changes(),
preferences.disabledSources().changes(),
preferences.lastUsedSource().changes(),
preferences.enabledLanguages.changes(),
preferences.disabledSources.changes(),
preferences.lastUsedSource.changes(),
) { a, b, c -> Triple(a, b, c) },
// SY -->
combine(
preferences.dataSaverExcludedSources().changes(),
preferences.sourcesTabSourcesInCategories().changes(),
preferences.sourcesTabCategoriesFilter().changes(),
preferences.dataSaverExcludedSources.changes(),
preferences.sourcesTabSourcesInCategories.changes(),
preferences.sourcesTabCategoriesFilter.changes(),
) { a, b, c -> Triple(a, b, c) },
// SY <--
repository.getSources(),
@@ -7,7 +7,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import tachiyomi.core.common.util.lang.withIOContext
@@ -0,0 +1,35 @@
package eu.kanade.domain.source.interactor
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.extension.ExtensionManager
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
class GetIncognitoState(
private val basePreferences: BasePreferences,
private val sourcePreferences: SourcePreferences,
private val extensionManager: ExtensionManager,
) {
fun await(sourceId: Long?): Boolean {
if (basePreferences.incognitoMode.get()) return true
if (sourceId == null) return false
val extensionPackage = extensionManager.getExtensionPackage(sourceId) ?: return false
return extensionPackage in sourcePreferences.incognitoExtensions.get()
}
fun subscribe(sourceId: Long?): Flow<Boolean> {
if (sourceId == null) return basePreferences.incognitoMode.changes()
return combine(
basePreferences.incognitoMode.changes(),
sourcePreferences.incognitoExtensions.changes(),
extensionManager.getExtensionPackageAsFlow(sourceId),
) { incognito, incognitoExtensions, extensionPackage ->
incognito || (extensionPackage in incognitoExtensions)
}
.distinctUntilChanged()
}
}
@@ -16,8 +16,8 @@ class GetLanguagesWithSources(
fun subscribe(): Flow<SortedMap<String, List<Source>>> {
return combine(
preferences.enabledLanguages().changes(),
preferences.disabledSources().changes(),
preferences.enabledLanguages.changes(),
preferences.disabledSources.changes(),
repository.getOnlineSources(),
) { enabledLanguage, disabledSource, onlineSources ->
val sortedSources = onlineSources.filterNot { it.id in BlacklistedSources.HIDDEN_SOURCES }.sortedWith(
@@ -9,7 +9,7 @@ class GetShowLatest(
) {
fun subscribe(hasSmartSearchConfig: Boolean): Flow<Boolean> {
return preferences.useNewSourceNavigation().changes()
return preferences.useNewSourceNavigation.changes()
.map {
!hasSmartSearchConfig && !it
}
@@ -9,6 +9,6 @@ class GetSourceCategories(
) {
fun subscribe(): Flow<List<String>> {
return preferences.sourcesTabCategories().changes().map { it.sortedWith(String.CASE_INSENSITIVE_ORDER) }
return preferences.sourcesTabCategories.changes().map { it.sortedWith(String.CASE_INSENSITIVE_ORDER) }
}
}
@@ -16,8 +16,8 @@ class GetSourcesWithFavoriteCount(
fun subscribe(): Flow<List<Pair<Source, Long>>> {
return combine(
preferences.migrationSortingDirection().changes(),
preferences.migrationSortingMode().changes(),
preferences.migrationSortingDirection.changes(),
preferences.migrationSortingMode.changes(),
repository.getSourcesWithFavoriteCount(),
) { direction, mode, list ->
list
@@ -14,7 +14,7 @@ class RenameSourceCategory(
CreateSourceCategory.Result.Success -> {}
}
preferences.sourcesTabSourcesInCategories().getAndSet { sourcesInCategories ->
preferences.sourcesTabSourcesInCategories.getAndSet { sourcesInCategories ->
sourcesInCategories.map {
val index = it.indexOf('|')
if (index != -1 && it.substring(index + 1) == categoryOld) {
@@ -24,7 +24,7 @@ class RenameSourceCategory(
}
}.toSet()
}
preferences.sourcesTabCategories().getAndSet {
preferences.sourcesTabCategories.getAndSet {
it.minus(categoryOld).plus(categoryNew)
}
@@ -7,8 +7,8 @@ class SetMigrateSorting(
) {
fun await(mode: Mode, direction: Direction) {
preferences.migrationSortingMode().set(mode)
preferences.migrationSortingDirection().set(direction)
preferences.migrationSortingMode.set(mode)
preferences.migrationSortingDirection.set(direction)
}
enum class Mode {
@@ -10,7 +10,7 @@ class SetSourceCategories(
fun await(source: Source, sourceCategories: List<String>) {
val sourceIdString = source.id.toString()
preferences.sourcesTabSourcesInCategories().getAndSet { sourcesInCategories ->
preferences.sourcesTabSourcesInCategories.getAndSet { sourcesInCategories ->
val currentSourceCategories = sourcesInCategories.filterNot {
it.substringBefore('|') == sourceIdString
}
@@ -9,7 +9,7 @@ class ToggleExcludeFromDataSaver(
) {
fun await(source: Source) {
preferences.dataSaverExcludedSources().getAndSet {
preferences.dataSaverExcludedSources.getAndSet {
if (source.id.toString() in it) {
it - source.id.toString()
} else {
@@ -0,0 +1,14 @@
package eu.kanade.domain.source.interactor
import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.common.preference.getAndSet
class ToggleIncognito(
private val preferences: SourcePreferences,
) {
fun await(extensions: String, enable: Boolean) {
preferences.incognitoExtensions.getAndSet {
if (enable) it.plus(extensions) else it.minus(extensions)
}
}
}
@@ -8,8 +8,8 @@ class ToggleLanguage(
) {
fun await(language: String) {
val isEnabled = language in preferences.enabledLanguages().get()
preferences.enabledLanguages().getAndSet { enabled ->
val isEnabled = language in preferences.enabledLanguages.get()
preferences.enabledLanguages.getAndSet { enabled ->
if (isEnabled) enabled.minus(language) else enabled.plus(language)
}
}
@@ -13,19 +13,19 @@ class ToggleSource(
}
fun await(sourceId: Long, enable: Boolean = isEnabled(sourceId)) {
preferences.disabledSources().getAndSet { disabled ->
preferences.disabledSources.getAndSet { disabled ->
if (enable) disabled.minus("$sourceId") else disabled.plus("$sourceId")
}
}
fun await(sourceIds: List<Long>, enable: Boolean) {
val transformedSourceIds = sourceIds.map { it.toString() }
preferences.disabledSources().getAndSet { disabled ->
preferences.disabledSources.getAndSet { disabled ->
if (enable) disabled.minus(transformedSourceIds) else disabled.plus(transformedSourceIds)
}
}
private fun isEnabled(sourceId: Long): Boolean {
return sourceId.toString() in preferences.disabledSources().get()
return sourceId.toString() in preferences.disabledSources.get()
}
}
@@ -9,8 +9,8 @@ class ToggleSourcePin(
) {
fun await(source: Source) {
val isPinned = source.id.toString() in preferences.pinnedSources().get()
preferences.pinnedSources().getAndSet { pinned ->
val isPinned = source.id.toString() in preferences.pinnedSources.get()
preferences.pinnedSources.getAndSet { pinned ->
if (isPinned) pinned.minus("${source.id}") else pinned.plus("${source.id}")
}
}
@@ -2,89 +2,133 @@ package eu.kanade.domain.source.service
import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.tachiyomi.util.system.LocaleHelper
import mihon.domain.migration.models.MigrationFlag
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.common.preference.getEnum
import tachiyomi.core.common.preference.getLongArray
import tachiyomi.domain.library.model.LibraryDisplayMode
class SourcePreferences(
private val preferenceStore: PreferenceStore,
preferenceStore: PreferenceStore,
) {
fun sourceDisplayMode() = preferenceStore.getObject(
val sourceDisplayMode: Preference<LibraryDisplayMode> = preferenceStore.getObjectFromString(
"pref_display_mode_catalogue",
LibraryDisplayMode.default,
LibraryDisplayMode.Serializer::serialize,
LibraryDisplayMode.Serializer::deserialize,
)
fun enabledLanguages() = preferenceStore.getStringSet("source_languages", LocaleHelper.getDefaultEnabledLanguages())
val enabledLanguages: Preference<Set<String>> = preferenceStore.getStringSet(
"source_languages",
LocaleHelper.getDefaultEnabledLanguages(),
)
fun disabledSources() = preferenceStore.getStringSet("hidden_catalogues", emptySet())
val disabledSources: Preference<Set<String>> = preferenceStore.getStringSet("hidden_catalogues", emptySet())
fun pinnedSources() = preferenceStore.getStringSet("pinned_catalogues", emptySet())
val incognitoExtensions: Preference<Set<String>> = preferenceStore.getStringSet("incognito_extensions", emptySet())
fun lastUsedSource() = preferenceStore.getLong(
val pinnedSources: Preference<Set<String>> = preferenceStore.getStringSet("pinned_catalogues", emptySet())
val lastUsedSource: Preference<Long> = preferenceStore.getLong(
Preference.appStateKey("last_catalogue_source"),
-1,
)
fun showNsfwSource() = preferenceStore.getBoolean("show_nsfw_source", true)
val showNsfwSource: Preference<Boolean> = preferenceStore.getBoolean("show_nsfw_source", true)
fun migrationSortingMode() = preferenceStore.getEnum("pref_migration_sorting", SetMigrateSorting.Mode.ALPHABETICAL)
val migrationSortingMode: Preference<SetMigrateSorting.Mode> = preferenceStore.getEnum(
"pref_migration_sorting",
SetMigrateSorting.Mode.ALPHABETICAL,
)
fun migrationSortingDirection() = preferenceStore.getEnum(
val migrationSortingDirection: Preference<SetMigrateSorting.Direction> = preferenceStore.getEnum(
"pref_migration_direction",
SetMigrateSorting.Direction.ASCENDING,
)
fun hideInLibraryItems() = preferenceStore.getBoolean("browse_hide_in_library_items", false)
val hideInLibraryItems: Preference<Boolean> = preferenceStore.getBoolean("browse_hide_in_library_items", false)
fun extensionRepos() = preferenceStore.getStringSet("extension_repos", emptySet())
val extensionRepos: Preference<Set<String>> = preferenceStore.getStringSet("extension_repos", emptySet())
fun extensionUpdatesCount() = preferenceStore.getInt("ext_updates_count", 0)
val extensionUpdatesCount: Preference<Int> = preferenceStore.getInt("ext_updates_count", 0)
fun trustedExtensions() = preferenceStore.getStringSet(
val trustedExtensions: Preference<Set<String>> = preferenceStore.getStringSet(
Preference.appStateKey("trusted_extensions"),
emptySet(),
)
fun globalSearchFilterState() = preferenceStore.getBoolean(
val globalSearchFilterState: Preference<Boolean> = preferenceStore.getBoolean(
Preference.appStateKey("has_filters_toggle_state"),
false,
)
// SY -->
fun enableSourceBlacklist() = preferenceStore.getBoolean("eh_enable_source_blacklist", true)
val enableSourceBlacklist: Preference<Boolean> = preferenceStore.getBoolean("eh_enable_source_blacklist", true)
fun sourcesTabCategories() = preferenceStore.getStringSet("sources_tab_categories", mutableSetOf())
val sourcesTabCategories: Preference<Set<String>> = preferenceStore.getStringSet("sources_tab_categories", mutableSetOf())
fun sourcesTabCategoriesFilter() = preferenceStore.getBoolean("sources_tab_categories_filter", false)
val sourcesTabCategoriesFilter: Preference<Boolean> = preferenceStore.getBoolean("sources_tab_categories_filter", false)
fun sourcesTabSourcesInCategories() = preferenceStore.getStringSet("sources_tab_source_categories", mutableSetOf())
val sourcesTabSourcesInCategories: Preference<Set<String>> = preferenceStore.getStringSet("sources_tab_source_categories", mutableSetOf())
fun dataSaver() = preferenceStore.getEnum("data_saver", DataSaver.NONE)
val dataSaver: Preference<DataSaver> = preferenceStore.getEnum("data_saver", DataSaver.NONE)
fun dataSaverIgnoreJpeg() = preferenceStore.getBoolean("ignore_jpeg", false)
val dataSaverIgnoreJpeg: Preference<Boolean> = preferenceStore.getBoolean("ignore_jpeg", false)
fun dataSaverIgnoreGif() = preferenceStore.getBoolean("ignore_gif", true)
val dataSaverIgnoreGif: Preference<Boolean> = preferenceStore.getBoolean("ignore_gif", true)
fun dataSaverImageQuality() = preferenceStore.getInt("data_saver_image_quality", 80)
val dataSaverImageQuality: Preference<Int> = preferenceStore.getInt("data_saver_image_quality", 80)
fun dataSaverImageFormatJpeg() = preferenceStore.getBoolean("data_saver_image_format_jpeg", false)
val dataSaverImageFormatJpeg: Preference<Boolean> = preferenceStore.getBoolean("data_saver_image_format_jpeg", false)
fun dataSaverServer() = preferenceStore.getString("data_saver_server", "")
val dataSaverServer: Preference<String> = preferenceStore.getString("data_saver_server", "")
fun dataSaverColorBW() = preferenceStore.getBoolean("data_saver_color_bw", false)
val dataSaverColorBW: Preference<Boolean> = preferenceStore.getBoolean("data_saver_color_bw", false)
fun dataSaverExcludedSources() = preferenceStore.getStringSet("data_saver_excluded", emptySet())
val dataSaverExcludedSources: Preference<Set<String>> = preferenceStore.getStringSet("data_saver_excluded", emptySet())
fun dataSaverDownloader() = preferenceStore.getBoolean("data_saver_downloader", true)
val dataSaverDownloader: Preference<Boolean> = preferenceStore.getBoolean("data_saver_downloader", true)
enum class DataSaver {
NONE,
BANDWIDTH_HERO,
WSRV_NL,
}
val allowLocalSourceHiddenFolders: Preference<Boolean> = preferenceStore.getBoolean("allow_local_source_hidden_folders", false)
val preferredMangaDexId: Preference<String> = preferenceStore.getString("preferred_mangaDex_id", "0")
val mangadexSyncToLibraryIndexes: Preference<Set<String>> = preferenceStore.getStringSet(
"pref_mangadex_sync_to_library_indexes",
emptySet(),
)
val recommendationSearchFlags: Preference<Int> = preferenceStore.getInt("rec_search_flags", Int.MAX_VALUE)
// SY <--
val migrationSources: Preference<List<Long>> = preferenceStore.getLongArray("migration_sources", emptyList())
val migrationFlags: Preference<Set<MigrationFlag>> = preferenceStore.getObjectFromInt(
key = "migration_flags",
defaultValue = MigrationFlag.entries.toSet(),
serializer = { MigrationFlag.toBit(it) },
deserializer = { value: Int -> MigrationFlag.fromBit(value) },
)
val migrationDeepSearchMode: Preference<Boolean> = preferenceStore.getBoolean("migration_deep_search", false)
val migrationPrioritizeByChapters: Preference<Boolean> = preferenceStore.getBoolean(
"migration_prioritize_by_chapters",
false,
)
val migrationHideUnmatched: Preference<Boolean> = preferenceStore.getBoolean("migration_hide_unmatched", false)
val migrationHideWithoutUpdates: Preference<Boolean> = preferenceStore.getBoolean(
"migration_hide_without_updates",
false,
)
}
@@ -9,21 +9,21 @@ import java.util.UUID
class SyncPreferences(
private val preferenceStore: PreferenceStore,
) {
fun clientHost() = preferenceStore.getString("sync_client_host", "https://sync.tachiyomi.org")
fun clientAPIKey() = preferenceStore.getString("sync_client_api_key", "")
fun lastSyncTimestamp() = preferenceStore.getLong(Preference.appStateKey("last_sync_timestamp"), 0L)
val clientHost: Preference<String> = preferenceStore.getString("sync_client_host", "https://sync.tachiyomi.org")
val clientAPIKey: Preference<String> = preferenceStore.getString("sync_client_api_key", "")
val lastSyncTimestamp: Preference<Long> = preferenceStore.getLong(Preference.appStateKey("last_sync_timestamp"), 0L)
fun lastSyncEtag() = preferenceStore.getString("sync_etag", "")
val lastSyncEtag: Preference<String> = preferenceStore.getString("sync_etag", "")
fun syncInterval() = preferenceStore.getInt("sync_interval", 0)
fun syncService() = preferenceStore.getInt("sync_service", 0)
val syncInterval: Preference<Int> = preferenceStore.getInt("sync_interval", 0)
val syncService: Preference<Int> = preferenceStore.getInt("sync_service", 0)
fun googleDriveAccessToken() = preferenceStore.getString(
val googleDriveAccessToken: Preference<String> = preferenceStore.getString(
Preference.appStateKey("google_drive_access_token"),
"",
)
fun googleDriveRefreshToken() = preferenceStore.getString(
val googleDriveRefreshToken: Preference<String> = preferenceStore.getString(
Preference.appStateKey("google_drive_refresh_token"),
"",
)
@@ -42,7 +42,7 @@ class SyncPreferences(
}
fun isSyncEnabled(): Boolean {
return syncService().get() != 0
return syncService.get() != 0
}
fun getSyncSettings(): SyncSettings {
@@ -10,6 +10,7 @@ fun Track.copyPersonalFrom(other: Track): Track {
status = other.status,
startDate = other.startDate,
finishDate = other.finishDate,
private = other.private,
)
}
@@ -26,6 +27,7 @@ fun Track.toDbTrack(): DbTrack = DbTrack.create(trackerId).also {
it.tracking_url = remoteUrl
it.started_reading_date = startDate
it.finished_reading_date = finishDate
it.private = private
}
fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? {
@@ -44,5 +46,6 @@ fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? {
remoteUrl = tracking_url,
startDate = started_reading_date,
finishDate = finished_reading_date,
private = private,
)
}
@@ -34,12 +34,19 @@ class TrackPreferences(
fun trackToken(tracker: Tracker) = preferenceStore.getString(Preference.privateKey("track_token_${tracker.id}"), "")
fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
val anilistScoreType: Preference<String> = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
val autoUpdateTrack: Preference<Boolean> = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
fun autoUpdateTrackOnMarkRead() = preferenceStore.getEnum(
val autoUpdateTrackOnMarkRead: Preference<AutoTrackState> = preferenceStore.getEnum(
"pref_auto_update_manga_on_mark_read",
AutoTrackState.ALWAYS,
)
// SY -->
val resolveUsingSourceMetadata: Preference<Boolean> = preferenceStore.getBoolean(
"pref_resolve_using_source_metadata_key",
true,
)
// SY <--
}
@@ -6,6 +6,7 @@ import eu.kanade.domain.ui.model.TabletUiMode
import eu.kanade.domain.ui.model.ThemeMode
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.common.preference.getEnum
import java.time.format.DateTimeFormatter
@@ -13,10 +14,10 @@ import java.time.format.FormatStyle
import java.util.Locale
class UiPreferences(
private val preferenceStore: PreferenceStore,
preferenceStore: PreferenceStore,
) {
fun themeMode() = preferenceStore.getEnum(
val themeMode = preferenceStore.getEnum(
"pref_theme_mode_key",
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ThemeMode.SYSTEM
@@ -25,7 +26,7 @@ class UiPreferences(
},
)
fun appTheme() = preferenceStore.getEnum(
val appTheme: Preference<AppTheme> = preferenceStore.getEnum(
"pref_app_theme",
if (DeviceUtil.isDynamicColorAvailable) {
AppTheme.MONET
@@ -34,35 +35,37 @@ class UiPreferences(
},
)
fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
val themeDarkAmoled: Preference<Boolean> = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
fun relativeTime() = preferenceStore.getBoolean("relative_time_v2", true)
val relativeTime: Preference<Boolean> = preferenceStore.getBoolean("relative_time_v2", true)
fun dateFormat() = preferenceStore.getString("app_date_format", "")
val dateFormat: Preference<String> = preferenceStore.getString("app_date_format", "")
fun tabletUiMode() = preferenceStore.getEnum("tablet_ui_mode", TabletUiMode.AUTOMATIC)
val tabletUiMode: Preference<TabletUiMode> = preferenceStore.getEnum("tablet_ui_mode", TabletUiMode.AUTOMATIC)
val imagesInDescription: Preference<Boolean> = preferenceStore.getBoolean("pref_render_images_description", true)
// SY -->
fun expandFilters() = preferenceStore.getBoolean("eh_expand_filters", false)
val expandFilters: Preference<Boolean> = preferenceStore.getBoolean("eh_expand_filters", false)
fun hideFeedTab() = preferenceStore.getBoolean("hide_latest_tab", false)
val hideFeedTab: Preference<Boolean> = preferenceStore.getBoolean("hide_latest_tab", false)
fun feedTabInFront() = preferenceStore.getBoolean("latest_tab_position", false)
val feedTabInFront: Preference<Boolean> = preferenceStore.getBoolean("latest_tab_position", false)
fun recommendsInOverflow() = preferenceStore.getBoolean("recommends_in_overflow", false)
val recommendsInOverflow: Preference<Boolean> = preferenceStore.getBoolean("recommends_in_overflow", false)
fun mergeInOverflow() = preferenceStore.getBoolean("merge_in_overflow", true)
val mergeInOverflow: Preference<Boolean> = preferenceStore.getBoolean("merge_in_overflow", true)
fun previewsRowCount() = preferenceStore.getInt("pref_previews_row_count", 4)
val previewsRowCount: Preference<Int> = preferenceStore.getInt("pref_previews_row_count", 4)
fun useNewSourceNavigation() = preferenceStore.getBoolean("use_new_source_navigation", true)
val useNewSourceNavigation: Preference<Boolean> = preferenceStore.getBoolean("use_new_source_navigation", true)
fun bottomBarLabels() = preferenceStore.getBoolean("pref_show_bottom_bar_labels", true)
val bottomBarLabels: Preference<Boolean> = preferenceStore.getBoolean("pref_show_bottom_bar_labels", true)
fun showNavUpdates() = preferenceStore.getBoolean("pref_show_updates_button", true)
val showNavUpdates: Preference<Boolean> = preferenceStore.getBoolean("pref_show_updates_button", true)
fun showNavHistory() = preferenceStore.getBoolean("pref_show_history_button", true)
val showNavHistory: Preference<Boolean> = preferenceStore.getBoolean("pref_show_history_button", true)
// SY <--
@@ -1,25 +1,23 @@
package eu.kanade.domain.ui.model
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import tachiyomi.i18n.MR
enum class AppTheme(val titleRes: StringResource?) {
DEFAULT(MR.strings.label_default),
MONET(MR.strings.theme_monet),
CATPPUCCIN(MR.strings.theme_catppuccin),
GREEN_APPLE(MR.strings.theme_greenapple),
LAVENDER(MR.strings.theme_lavender),
MIDNIGHT_DUSK(MR.strings.theme_midnightdusk),
// TODO: re-enable for preview
NORD(MR.strings.theme_nord.takeIf { isDevFlavor || isPreviewBuildType }),
NORD(MR.strings.theme_nord),
STRAWBERRY_DAIQUIRI(MR.strings.theme_strawberrydaiquiri),
TAKO(MR.strings.theme_tako),
TEALTURQUOISE(MR.strings.theme_tealturquoise),
TIDAL_WAVE(MR.strings.theme_tidalwave),
YINYANG(MR.strings.theme_yinyang),
YOTSUBA(MR.strings.theme_yotsuba),
MONOCHROME(MR.strings.theme_monochrome),
// Deprecated
DARK_BLUE(null),
@@ -82,10 +82,18 @@ fun BrowseSourceContent(
}
}
if (mangaList.itemCount <= 0 && errorState != null && errorState is LoadState.Error) {
if (mangaList.itemCount == 0 && mangaList.loadState.refresh is LoadState.Loading) {
LoadingScreen(Modifier.padding(contentPadding))
return
}
if (mangaList.itemCount == 0) {
EmptyScreen(
modifier = Modifier.padding(contentPadding),
message = getErrorMessage(errorState),
message = when (errorState) {
is LoadState.Error -> getErrorMessage(errorState)
else -> stringResource(MR.strings.no_results_found)
},
actions = if (source is LocalSource /* SY --> */ && onLocalSourceHelpClick != null /* SY <-- */) {
persistentListOf(
EmptyScreenAction(
@@ -104,7 +112,7 @@ fun BrowseSourceContent(
// SY -->
if (onWebViewClick != null) {
EmptyScreenAction(
MR.strings.action_open_in_web_view,
stringRes = MR.strings.action_open_in_web_view,
icon = Icons.Outlined.Public,
onClick = onWebViewClick,
)
@@ -113,7 +121,7 @@ fun BrowseSourceContent(
},
if (onHelpClick != null) {
EmptyScreenAction(
MR.strings.label_help,
stringRes = MR.strings.label_help,
icon = Icons.AutoMirrored.Outlined.HelpOutline,
onClick = onHelpClick,
)
@@ -128,13 +136,6 @@ fun BrowseSourceContent(
return
}
if (mangaList.itemCount == 0 && mangaList.loadState.refresh is LoadState.Loading) {
LoadingScreen(
modifier = Modifier.padding(contentPadding),
)
return
}
// SY -->
if (source?.isEhBasedSource() == true && ehentaiBrowseDisplayMode) {
BrowseSourceEHentaiList(
@@ -11,7 +11,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun BrowseTabWrapper(tab: TabContent) {
fun BrowseTabWrapper(tab: TabContent, onBackPressed: (() -> Unit)? = null) {
val snackbarHostState = remember { SnackbarHostState() }
Scaffold(
topBar = { scrollBehavior ->
@@ -20,6 +20,7 @@ fun BrowseTabWrapper(tab: TabContent) {
actions = {
AppBarActions(tab.actions)
},
navigateUp = onBackPressed,
scrollBehavior = scrollBehavior,
)
},
@@ -35,8 +35,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@@ -48,6 +50,7 @@ import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TrailingWidgetBuffer
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel
@@ -73,6 +76,7 @@ fun ExtensionDetailsScreen(
onClickClearCookies: () -> Unit,
onClickUninstall: () -> Unit,
onClickSource: (sourceId: Long) -> Unit,
onClickIncognito: (Boolean) -> Unit,
) {
val uriHandler = LocalUriHandler.current
val url = remember(state.extension) {
@@ -141,9 +145,11 @@ fun ExtensionDetailsScreen(
contentPadding = paddingValues,
extension = state.extension,
sources = state.sources,
incognitoMode = state.isIncognito,
onClickSourcePreferences = onClickSourcePreferences,
onClickUninstall = onClickUninstall,
onClickSource = onClickSource,
onClickIncognito = onClickIncognito,
)
}
}
@@ -153,9 +159,11 @@ private fun ExtensionDetails(
contentPadding: PaddingValues,
extension: Extension.Installed,
sources: ImmutableList<ExtensionSourceItem>,
incognitoMode: Boolean,
onClickSourcePreferences: (sourceId: Long) -> Unit,
onClickUninstall: () -> Unit,
onClickSource: (sourceId: Long) -> Unit,
onClickIncognito: (Boolean) -> Unit,
) {
val context = LocalContext.current
var showNsfwWarning by remember { mutableStateOf(false) }
@@ -179,6 +187,7 @@ private fun ExtensionDetails(
item {
DetailsHeader(
extension = extension,
extIncognitoMode = incognitoMode,
onClickUninstall = onClickUninstall,
onClickAppInfo = {
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
@@ -190,6 +199,7 @@ private fun ExtensionDetails(
onClickAgeRating = {
showNsfwWarning = true
},
onExtIncognitoChange = onClickIncognito,
)
}
@@ -217,9 +227,11 @@ private fun ExtensionDetails(
@Composable
private fun DetailsHeader(
extension: Extension,
extIncognitoMode: Boolean,
onClickAgeRating: () -> Unit,
onClickUninstall: () -> Unit,
onClickAppInfo: (() -> Unit)?,
onExtIncognitoChange: (Boolean) -> Unit,
) {
val context = LocalContext.current
@@ -227,9 +239,8 @@ private fun DetailsHeader(
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = MaterialTheme.padding.medium)
.padding(
start = MaterialTheme.padding.medium,
end = MaterialTheme.padding.medium,
top = MaterialTheme.padding.medium,
bottom = MaterialTheme.padding.small,
)
@@ -321,12 +332,9 @@ private fun DetailsHeader(
}
Row(
modifier = Modifier.padding(
start = MaterialTheme.padding.medium,
end = MaterialTheme.padding.medium,
top = MaterialTheme.padding.small,
bottom = MaterialTheme.padding.medium,
),
modifier = Modifier
.padding(horizontal = MaterialTheme.padding.medium)
.padding(top = MaterialTheme.padding.small),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
) {
OutlinedButton(
@@ -349,6 +357,24 @@ private fun DetailsHeader(
}
}
TextPreferenceWidget(
modifier = Modifier.padding(horizontal = MaterialTheme.padding.small),
title = stringResource(MR.strings.pref_incognito_mode),
subtitle = stringResource(MR.strings.pref_incognito_mode_extension_summary),
icon = ImageVector.vectorResource(R.drawable.ic_glasses_24dp),
widget = {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Switch(
checked = extIncognitoMode,
onCheckedChange = onExtIncognitoChange,
modifier = Modifier.padding(start = TrailingWidgetBuffer),
)
}
},
)
HorizontalDivider()
}
}
@@ -351,13 +351,17 @@ private fun ExtensionItemContent(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
) {
ProvideTextStyle(value = MaterialTheme.typography.bodySmall) {
var hasAlreadyShownAnElement by remember { mutableStateOf(false) }
if (extension is Extension.Installed && extension.lang.isNotEmpty()) {
hasAlreadyShownAnElement = true
Text(
text = LocaleHelper.getSourceDisplayName(extension.lang, LocalContext.current),
)
}
if (extension.versionName.isNotEmpty()) {
if (hasAlreadyShownAnElement) DotSeparatorNoSpaceText()
hasAlreadyShownAnElement = true
Text(
text = extension.versionName,
)
@@ -373,6 +377,8 @@ private fun ExtensionItemContent(
else -> null
}
if (warning != null) {
if (hasAlreadyShownAnElement) DotSeparatorNoSpaceText()
hasAlreadyShownAnElement = true
Text(
text = stringResource(warning).uppercase(),
color = MaterialTheme.colorScheme.error,
@@ -380,6 +386,12 @@ private fun ExtensionItemContent(
overflow = TextOverflow.Ellipsis,
)
}
if (extension is Extension.Installed && !extension.isShared) {
if (hasAlreadyShownAnElement) DotSeparatorNoSpaceText()
Text(
text = stringResource(MR.strings.ext_installer_private),
)
}
if (!installStep.isCompleted()) {
DotSeparatorNoSpaceText()
@@ -41,6 +41,7 @@ fun GlobalSearchScreen(
navigateUp = navigateUp,
onChangeSearchQuery = onChangeSearchQuery,
onSearch = onSearch,
hideSourceFilter = false,
sourceFilter = state.sourceFilter,
onChangeSearchFilter = onChangeSearchFilter,
onlyShowHasResults = state.onlyShowHasResults,
@@ -1,84 +0,0 @@
package eu.kanade.presentation.browse
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.manga.components.BaseMangaListItem
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaScreenModel
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.FastScrollLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.screens.EmptyScreen
@Composable
fun MigrateMangaScreen(
navigateUp: () -> Unit,
title: String?,
state: MigrateMangaScreenModel.State,
onClickItem: (Manga) -> Unit,
onClickCover: (Manga) -> Unit,
) {
Scaffold(
topBar = { scrollBehavior ->
AppBar(
title = title,
navigateUp = navigateUp,
scrollBehavior = scrollBehavior,
)
},
) { contentPadding ->
if (state.isEmpty) {
EmptyScreen(
stringRes = MR.strings.empty_screen,
modifier = Modifier.padding(contentPadding),
)
return@Scaffold
}
MigrateMangaContent(
contentPadding = contentPadding,
state = state,
onClickItem = onClickItem,
onClickCover = onClickCover,
)
}
}
@Composable
private fun MigrateMangaContent(
contentPadding: PaddingValues,
state: MigrateMangaScreenModel.State,
onClickItem: (Manga) -> Unit,
onClickCover: (Manga) -> Unit,
) {
FastScrollLazyColumn(
contentPadding = contentPadding,
) {
items(state.titles) { manga ->
MigrateMangaItem(
manga = manga,
onClickItem = onClickItem,
onClickCover = onClickCover,
)
}
}
}
@Composable
private fun MigrateMangaItem(
manga: Manga,
onClickItem: (Manga) -> Unit,
onClickCover: (Manga) -> Unit,
modifier: Modifier = Modifier,
) {
BaseMangaListItem(
modifier = modifier,
manga = manga,
onClickItem = { onClickItem(manga) },
onClickCover = { onClickCover(manga) },
)
}
@@ -32,6 +32,7 @@ fun MigrateSearchScreen(
navigateUp = navigateUp,
onChangeSearchQuery = onChangeSearchQuery,
onSearch = onSearch,
hideSourceFilter = true,
sourceFilter = state.sourceFilter,
onChangeSearchFilter = onChangeSearchFilter,
onlyShowHasResults = state.onlyShowHasResults,
@@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowForward
import androidx.compose.material.icons.outlined.ArrowForward
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.CopyAll
import androidx.compose.material.icons.outlined.Done
@@ -19,6 +19,7 @@ import eu.kanade.presentation.library.components.MangaComfortableGridItem
import eu.kanade.tachiyomi.R
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.RaisedSearchMetadata
import exh.metadata.metadata.RankedSearchMetadata
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaCover
@@ -119,6 +120,14 @@ private fun BrowseSourceComfortableGridItem(
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
} else if (metadata is RankedSearchMetadata) {
metadata.rank?.let {
Badge(
text = "+$it",
color = MaterialTheme.colorScheme.tertiary,
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
}
},
// SY <--
@@ -19,6 +19,7 @@ import eu.kanade.presentation.library.components.MangaCompactGridItem
import eu.kanade.tachiyomi.R
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.RaisedSearchMetadata
import exh.metadata.metadata.RankedSearchMetadata
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaCover
@@ -119,6 +120,14 @@ private fun BrowseSourceCompactGridItem(
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
} else if (metadata is RankedSearchMetadata) {
metadata.rank?.let {
Badge(
text = "+$it",
color = MaterialTheme.colorScheme.tertiary,
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
}
},
// SY <--
@@ -30,8 +30,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import com.gowtham.ratingbar.RatingBar
import com.gowtham.ratingbar.RatingBarConfig
import com.gowtham.ratingbar.ComposeStars
import com.gowtham.ratingbar.RatingBarStyle
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.manga.components.MangaCover
import exh.metadata.MetadataUtil
@@ -222,17 +222,18 @@ fun BrowseSourceEHentaiListItem(
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
horizontalAlignment = Alignment.Start,
) {
RatingBar(
ComposeStars(
value = rating,
onValueChange = {},
onRatingChanged = {},
config = RatingBarConfig().apply {
isIndicator(true)
numStars(5)
size(18.dp)
activeColor(Color(0xFF005ED7))
inactiveColor(Color(0xE1E2ECFF))
},
numOfStars = 5,
size = 18.dp,
spaceBetween = 2.dp,
hideInactiveStars = false,
style = RatingBarStyle.Fill(
activeColor = Color(0xFF005ED7),
inActiveColor = Color(0xE1E2ECFF),
),
painterEmpty = null,
painterFilled = null,
)
val color = genre?.first?.color
val res = genre?.second
@@ -3,12 +3,12 @@ package eu.kanade.presentation.browse.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material3.Icon
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.i18n.stringResource
@Composable
@@ -17,7 +17,7 @@ fun BrowseSourceFloatingActionButton(
onFabClick: () -> Unit,
modifier: Modifier = Modifier,
) {
ExtendedFloatingActionButton(
SmallExtendedFloatingActionButton(
modifier = modifier,
text = {
Text(
@@ -16,6 +16,7 @@ import eu.kanade.presentation.library.components.MangaListItem
import eu.kanade.tachiyomi.R
import exh.metadata.metadata.MangaDexSearchMetadata
import exh.metadata.metadata.RaisedSearchMetadata
import exh.metadata.metadata.RankedSearchMetadata
import kotlinx.coroutines.flow.StateFlow
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaCover
@@ -110,6 +111,14 @@ private fun BrowseSourceListItem(
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
} else if (metadata is RankedSearchMetadata) {
metadata.rank?.let {
Badge(
text = "+$it",
color = MaterialTheme.colorScheme.tertiary,
textColor = MaterialTheme.colorScheme.onTertiary,
)
}
}
// SY <--
},
@@ -4,7 +4,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ViewList
import androidx.compose.material.icons.automirrored.outlined.Help
import androidx.compose.material.icons.filled.ViewModule
import androidx.compose.material.icons.outlined.Help
import androidx.compose.material.icons.outlined.Public
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarScrollBehavior
@@ -40,6 +40,7 @@ fun GlobalSearchToolbar(
navigateUp: () -> Unit,
onChangeSearchQuery: (String?) -> Unit,
onSearch: (String) -> Unit,
hideSourceFilter: Boolean,
sourceFilter: SourceFilter,
onChangeSearchFilter: (SourceFilter) -> Unit,
onlyShowHasResults: Boolean,
@@ -73,38 +74,40 @@ fun GlobalSearchToolbar(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
// TODO: make this UX better; it only applies when triggering a new search
FilterChip(
selected = sourceFilter == SourceFilter.PinnedOnly,
onClick = { onChangeSearchFilter(SourceFilter.PinnedOnly) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.PushPin,
contentDescription = null,
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(MR.strings.pinned_sources))
},
)
FilterChip(
selected = sourceFilter == SourceFilter.All,
onClick = { onChangeSearchFilter(SourceFilter.All) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.DoneAll,
contentDescription = null,
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(MR.strings.all))
},
)
if (!hideSourceFilter) {
FilterChip(
selected = sourceFilter == SourceFilter.PinnedOnly,
onClick = { onChangeSearchFilter(SourceFilter.PinnedOnly) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.PushPin,
contentDescription = null,
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(MR.strings.pinned_sources))
},
)
FilterChip(
selected = sourceFilter == SourceFilter.All,
onClick = { onChangeSearchFilter(SourceFilter.All) },
leadingIcon = {
Icon(
imageVector = Icons.Outlined.DoneAll,
contentDescription = null,
modifier = Modifier
.size(FilterChipDefaults.IconSize),
)
},
label = {
Text(text = stringResource(MR.strings.all))
},
)
VerticalDivider()
VerticalDivider()
}
FilterChip(
selected = onlyShowHasResults,
@@ -2,23 +2,25 @@ package eu.kanade.presentation.category
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.SortByAlpha
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Modifier
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
import eu.kanade.presentation.category.components.CategoryListItem
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.tachiyomi.ui.category.CategoryScreenState
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import sh.calvin.reorderable.ReorderableItem
import sh.calvin.reorderable.rememberReorderableLazyListState
import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
@@ -32,11 +34,9 @@ import tachiyomi.presentation.core.util.plus
fun CategoryScreen(
state: CategoryScreenState.Success,
onClickCreate: () -> Unit,
onClickSortAlphabetically: () -> Unit,
onClickRename: (Category) -> Unit,
onClickDelete: (Category) -> Unit,
onClickMoveUp: (Category) -> Unit,
onClickMoveDown: (Category) -> Unit,
onChangeOrder: (Category, Int) -> Unit,
navigateUp: () -> Unit,
) {
val lazyListState = rememberLazyListState()
@@ -45,17 +45,6 @@ fun CategoryScreen(
AppBar(
title = stringResource(MR.strings.action_edit_categories),
navigateUp = navigateUp,
actions = {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(MR.strings.action_sort),
icon = Icons.Outlined.SortByAlpha,
onClick = onClickSortAlphabetically,
),
),
)
},
scrollBehavior = scrollBehavior,
)
},
@@ -77,12 +66,10 @@ fun CategoryScreen(
CategoryContent(
categories = state.categories,
lazyListState = lazyListState,
paddingValues = paddingValues + topSmallPaddingValues +
PaddingValues(horizontal = MaterialTheme.padding.medium),
paddingValues = paddingValues,
onClickRename = onClickRename,
onClickDelete = onClickDelete,
onMoveUp = onClickMoveUp,
onMoveDown = onClickMoveDown,
onChangeOrder = onChangeOrder,
)
}
}
@@ -94,28 +81,44 @@ private fun CategoryContent(
paddingValues: PaddingValues,
onClickRename: (Category) -> Unit,
onClickDelete: (Category) -> Unit,
onMoveUp: (Category) -> Unit,
onMoveDown: (Category) -> Unit,
onChangeOrder: (Category, Int) -> Unit,
) {
val categoriesState = remember { categories.toMutableStateList() }
val reorderableState = rememberReorderableLazyListState(lazyListState, paddingValues) { from, to ->
val item = categoriesState.removeAt(from.index)
categoriesState.add(to.index, item)
onChangeOrder(item, to.index)
}
LaunchedEffect(categories) {
if (!reorderableState.isAnyItemDragging) {
categoriesState.clear()
categoriesState.addAll(categories)
}
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
state = lazyListState,
contentPadding = paddingValues,
contentPadding = paddingValues +
topSmallPaddingValues +
PaddingValues(horizontal = MaterialTheme.padding.medium),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
itemsIndexed(
items = categories,
key = { _, category -> "category-${category.id}" },
) { index, category ->
CategoryListItem(
modifier = Modifier.animateItem(),
category = category,
canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex,
onMoveUp = onMoveUp,
onMoveDown = onMoveDown,
onRename = { onClickRename(category) },
onDelete = { onClickDelete(category) },
)
items(
items = categoriesState,
key = { category -> category.key },
) { category ->
ReorderableItem(reorderableState, category.key) {
CategoryListItem(
modifier = Modifier.animateItem(),
category = category,
onRename = { onClickRename(category) },
onDelete = { onClickDelete(category) },
)
}
}
}
}
private val Category.key inline get() = "category-$id"
@@ -219,35 +219,6 @@ fun CategoryDeleteDialog(
)
}
@Composable
fun CategorySortAlphabeticallyDialog(
onDismissRequest: () -> Unit,
onSort: () -> Unit,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
confirmButton = {
TextButton(onClick = {
onSort()
onDismissRequest()
}) {
Text(text = stringResource(MR.strings.action_ok))
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(MR.strings.action_cancel))
}
},
title = {
Text(text = stringResource(MR.strings.action_sort_category))
},
text = {
Text(text = stringResource(MR.strings.sort_category_confirmation))
},
)
}
@Composable
fun ChangeCategoryDialog(
initialSelection: ImmutableList<CheckboxState<Category>>,
@@ -4,11 +4,11 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material3.Icon
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.shouldExpandFAB
@@ -18,7 +18,7 @@ fun CategoryFloatingActionButton(
onCreate: () -> Unit,
modifier: Modifier = Modifier,
) {
ExtendedFloatingActionButton(
SmallExtendedFloatingActionButton(
text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
onClick = onCreate,
@@ -2,14 +2,11 @@ package eu.kanade.presentation.category.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DragHandle
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
@@ -19,57 +16,42 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import sh.calvin.reorderable.ReorderableCollectionItemScope
import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun CategoryListItem(
fun ReorderableCollectionItemScope.CategoryListItem(
category: Category,
canMoveUp: Boolean,
canMoveDown: Boolean,
onMoveUp: (Category) -> Unit,
onMoveDown: (Category) -> Unit,
onRename: () -> Unit,
onDelete: () -> Unit,
modifier: Modifier = Modifier,
) {
ElevatedCard(
modifier = modifier,
) {
ElevatedCard(modifier = modifier) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { onRename() }
.clickable(onClick = onRename)
.padding(vertical = MaterialTheme.padding.small)
.padding(
start = MaterialTheme.padding.medium,
top = MaterialTheme.padding.medium,
start = MaterialTheme.padding.small,
end = MaterialTheme.padding.medium,
),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(imageVector = Icons.AutoMirrored.Outlined.Label, contentDescription = null)
Icon(
imageVector = Icons.Outlined.DragHandle,
contentDescription = null,
modifier = Modifier
.padding(MaterialTheme.padding.medium)
.draggableHandle(),
)
Text(
text = category.name,
modifier = Modifier
.padding(start = MaterialTheme.padding.medium),
modifier = Modifier.weight(1f),
)
}
Row {
IconButton(
onClick = { onMoveUp(category) },
enabled = canMoveUp,
) {
Icon(imageVector = Icons.Outlined.ArrowDropUp, contentDescription = null)
}
IconButton(
onClick = { onMoveDown(category) },
enabled = canMoveDown,
) {
Icon(imageVector = Icons.Outlined.ArrowDropDown, contentDescription = null)
}
Spacer(modifier = Modifier.weight(1f))
IconButton(onClick = onRename) {
Icon(
imageVector = Icons.Outlined.Edit,
@@ -77,7 +59,10 @@ fun CategoryListItem(
)
}
IconButton(onClick = onDelete) {
Icon(imageVector = Icons.Outlined.Delete, contentDescription = stringResource(MR.strings.action_delete))
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = stringResource(MR.strings.action_delete),
)
}
}
}
@@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -9,7 +9,6 @@ import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material.icons.outlined.ArrowDropUp
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -9,7 +9,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Label
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -1,6 +1,5 @@
package eu.kanade.presentation.components
import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
@@ -28,8 +27,8 @@ fun NavigatorAdaptiveSheet(
screen = screen,
content = { sheetNavigator ->
AdaptiveSheet(
enableSwipeDismiss = enableSwipeDismiss(sheetNavigator),
onDismissRequest = onDismissRequest,
enableSwipeDismiss = enableSwipeDismiss(sheetNavigator),
) {
ScreenTransition(
navigator = sheetNavigator,
@@ -38,11 +37,6 @@ fun NavigatorAdaptiveSheet(
fadeOut(animationSpec = tween(90))
},
)
BackHandler(
enabled = sheetNavigator.size > 1,
onBack = sheetNavigator::pop,
)
}
// Make sure screens are disposed no matter what
@@ -79,10 +73,10 @@ fun AdaptiveSheet(
properties = dialogProperties,
) {
AdaptiveSheetImpl(
modifier = modifier,
isTabletUi = isTabletUi,
enableSwipeDismiss = enableSwipeDismiss,
onDismissRequest = onDismissRequest,
modifier = modifier,
) {
content()
}
@@ -21,8 +21,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.TooltipDefaults.rememberTooltipPositionProvider
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
@@ -36,6 +37,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
@@ -194,13 +196,14 @@ fun AppBarActions(
actions.filterIsInstance<AppBar.Action>().map {
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(it.title)
}
},
state = rememberTooltipState(),
focusable = false,
) {
IconButton(
onClick = it.onClick,
@@ -218,13 +221,14 @@ fun AppBarActions(
val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
if (overflowActions.isNotEmpty()) {
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(stringResource(MR.strings.action_menu_overflow_description))
}
},
state = rememberTooltipState(),
focusable = false,
) {
IconButton(
onClick = { showMenu = !showMenu },
@@ -289,6 +293,7 @@ fun SearchToolbar(
onSearch(searchQuery)
focusManager.clearFocus()
keyboardController?.hide()
focusManager.moveFocus(FocusDirection.Next)
}
BasicTextField(
@@ -345,13 +350,14 @@ fun SearchToolbar(
// Don't show search action
} else if (searchQuery == null) {
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(stringResource(MR.strings.action_search))
}
},
state = rememberTooltipState(),
focusable = false,
) {
IconButton(
onClick = onClick,
@@ -364,13 +370,14 @@ fun SearchToolbar(
}
} else if (searchQuery.isNotEmpty()) {
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
positionProvider = rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(stringResource(MR.strings.action_reset))
}
},
state = rememberTooltipState(),
focusable = false,
) {
IconButton(
onClick = {
@@ -22,7 +22,7 @@ fun relativeDateText(
Instant.ofEpochMilli(dateEpochMillis),
ZoneId.systemDefault(),
)
.takeIf { dateEpochMillis > 0L },
.takeIf { dateEpochMillis != 0L },
)
}
@@ -33,8 +33,8 @@ fun relativeDateText(
val context = LocalContext.current
val preferences = remember { Injekt.get<UiPreferences>() }
val relativeTime = remember { preferences.relativeTime().get() }
val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat().get()) }
val relativeTime = remember { preferences.relativeTime.get() }
val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat.get()) }
return localDate?.toRelativeString(
context = context,
@@ -4,6 +4,7 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.DpOffset
import eu.kanade.presentation.manga.DownloadAction
import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR
@@ -12,10 +13,44 @@ import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun DownloadDropdownMenu(
modifier: Modifier = Modifier,
expanded: Boolean,
onDismissRequest: () -> Unit,
onDownloadClicked: (DownloadAction) -> Unit,
modifier: Modifier = Modifier,
offset: DpOffset? = null,
) {
if (offset != null) {
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
modifier = modifier,
offset = offset,
content = {
DownloadDropdownMenuItems(
onDismissRequest = onDismissRequest,
onDownloadClicked = onDownloadClicked,
)
},
)
} else {
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
modifier = modifier,
content = {
DownloadDropdownMenuItems(
onDismissRequest = onDismissRequest,
onDownloadClicked = onDownloadClicked,
)
},
)
}
}
@Composable
private fun DownloadDropdownMenuItems(
onDismissRequest: () -> Unit,
onDownloadClicked: (DownloadAction) -> Unit,
) {
val options = persistentListOf(
DownloadAction.NEXT_1_CHAPTER to pluralStringResource(MR.plurals.download_amount, 1, 1),
@@ -23,21 +58,16 @@ fun DownloadDropdownMenu(
DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 10, 10),
DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 25, 25),
DownloadAction.UNREAD_CHAPTERS to stringResource(MR.strings.download_unread),
DownloadAction.BOOKMARKED_CHAPTERS to stringResource(MR.strings.download_bookmarked),
)
DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
modifier = modifier,
) {
options.map { (downloadAction, string) ->
DropdownMenuItem(
text = { Text(text = string) },
onClick = {
onDownloadClicked(downloadAction)
onDismissRequest()
},
)
}
options.map { (downloadAction, string) ->
DropdownMenuItem(
text = { Text(text = string) },
onClick = {
onDownloadClicked(downloadAction)
onDismissRequest()
},
)
}
}
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PrimaryTabRow
@@ -14,7 +15,6 @@ import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Tab
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
@@ -33,20 +33,13 @@ import tachiyomi.presentation.core.i18n.stringResource
fun TabbedScreen(
titleRes: StringResource,
tabs: ImmutableList<TabContent>,
startIndex: Int? = null,
state: PagerState = rememberPagerState { tabs.size },
searchQuery: String? = null,
onChangeSearchQuery: (String?) -> Unit = {},
) {
val scope = rememberCoroutineScope()
val state = rememberPagerState { tabs.size }
val snackbarHostState = remember { SnackbarHostState() }
LaunchedEffect(startIndex) {
if (startIndex != null) {
state.scrollToPage(startIndex)
}
}
Scaffold(
topBar = {
val tab = tabs[state.currentPage]
@@ -39,6 +39,7 @@ fun HistoryScreen(
onSearchQueryChange: (String?) -> Unit,
onClickCover: (mangaId: Long) -> Unit,
onClickResume: (mangaId: Long, chapterId: Long) -> Unit,
onClickFavorite: (mangaId: Long) -> Unit,
onDialogChange: (HistoryScreenModel.Dialog?) -> Unit,
) {
Scaffold(
@@ -85,6 +86,7 @@ fun HistoryScreen(
onClickCover = { history -> onClickCover(history.mangaId) },
onClickResume = { history -> onClickResume(history.mangaId, history.chapterId) },
onClickDelete = { item -> onDialogChange(HistoryScreenModel.Dialog.Delete(item)) },
onClickFavorite = { history -> onClickFavorite(history.mangaId) },
)
}
}
@@ -98,6 +100,7 @@ private fun HistoryScreenContent(
onClickCover: (HistoryWithRelations) -> Unit,
onClickResume: (HistoryWithRelations) -> Unit,
onClickDelete: (HistoryWithRelations) -> Unit,
onClickFavorite: (HistoryWithRelations) -> Unit,
) {
FastScrollLazyColumn(
contentPadding = contentPadding,
@@ -127,6 +130,7 @@ private fun HistoryScreenContent(
onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) },
onClickDelete = { onClickDelete(value) },
onClickFavorite = { onClickFavorite(value) },
)
}
}
@@ -153,6 +157,7 @@ internal fun HistoryScreenPreviews(
onClickCover = {},
onClickResume = { _, _ -> run {} },
onDialogChange = {},
onClickFavorite = {},
)
}
}
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -39,6 +40,7 @@ fun HistoryItem(
onClickCover: () -> Unit,
onClickResume: () -> Unit,
onClickDelete: () -> Unit,
onClickFavorite: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
@@ -82,6 +84,16 @@ fun HistoryItem(
)
}
if (!history.coverData.isMangaFavorite) {
IconButton(onClick = onClickFavorite) {
Icon(
imageVector = Icons.Outlined.FavoriteBorder,
contentDescription = stringResource(MR.strings.add_to_library),
tint = MaterialTheme.colorScheme.onSurface,
)
}
}
IconButton(onClick = onClickDelete) {
Icon(
imageVector = Icons.Outlined.Delete,
@@ -105,6 +117,7 @@ private fun HistoryItemPreviews(
onClickCover = {},
onClickResume = {},
onClickDelete = {},
onClickFavorite = {},
)
}
}
@@ -9,6 +9,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.FilterChip
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -99,9 +100,9 @@ fun LibrarySettingsDialog(
private fun ColumnScope.FilterPage(
screenModel: LibrarySettingsScreenModel,
) {
val filterDownloaded by screenModel.libraryPreferences.filterDownloaded().collectAsState()
val downloadedOnly by screenModel.preferences.downloadedOnly().collectAsState()
val autoUpdateMangaRestrictions by screenModel.libraryPreferences.autoUpdateMangaRestrictions().collectAsState()
val filterDownloaded by screenModel.libraryPreferences.filterDownloaded.collectAsState()
val downloadedOnly by screenModel.preferences.downloadedOnly.collectAsState()
val autoUpdateMangaRestrictions by screenModel.libraryPreferences.autoUpdateMangaRestrictions.collectAsState()
TriStateItem(
label = stringResource(MR.strings.label_downloaded),
@@ -113,25 +114,25 @@ private fun ColumnScope.FilterPage(
enabled = !downloadedOnly,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterDownloaded) },
)
val filterUnread by screenModel.libraryPreferences.filterUnread().collectAsState()
val filterUnread by screenModel.libraryPreferences.filterUnread.collectAsState()
TriStateItem(
label = stringResource(MR.strings.action_filter_unread),
state = filterUnread,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterUnread) },
)
val filterStarted by screenModel.libraryPreferences.filterStarted().collectAsState()
val filterStarted by screenModel.libraryPreferences.filterStarted.collectAsState()
TriStateItem(
label = stringResource(MR.strings.label_started),
state = filterStarted,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterStarted) },
)
val filterBookmarked by screenModel.libraryPreferences.filterBookmarked().collectAsState()
val filterBookmarked by screenModel.libraryPreferences.filterBookmarked.collectAsState()
TriStateItem(
label = stringResource(MR.strings.action_filter_bookmarked),
state = filterBookmarked,
onClick = { screenModel.toggleFilter(LibraryPreferences::filterBookmarked) },
)
val filterCompleted by screenModel.libraryPreferences.filterCompleted().collectAsState()
val filterCompleted by screenModel.libraryPreferences.filterCompleted.collectAsState()
TriStateItem(
label = stringResource(MR.strings.completed),
state = filterCompleted,
@@ -142,7 +143,7 @@ private fun ColumnScope.FilterPage(
(isDevFlavor || isPreviewBuildType) &&
LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in autoUpdateMangaRestrictions
) {
val filterIntervalCustom by screenModel.libraryPreferences.filterIntervalCustom().collectAsState()
val filterIntervalCustom by screenModel.libraryPreferences.filterIntervalCustom.collectAsState()
TriStateItem(
label = stringResource(MR.strings.action_filter_interval_custom),
state = filterIntervalCustom,
@@ -150,7 +151,7 @@ private fun ColumnScope.FilterPage(
)
}
// SY -->
val filterLewd by screenModel.libraryPreferences.filterLewd().collectAsState()
val filterLewd by screenModel.libraryPreferences.filterLewd.collectAsState()
TriStateItem(
label = stringResource(SYMR.strings.lewd),
state = filterLewd,
@@ -193,7 +194,7 @@ private fun ColumnScope.SortPage(
) {
val trackers by screenModel.trackersFlow.collectAsState()
// SY -->
val globalSortMode by screenModel.libraryPreferences.sortingMode().collectAsState()
val globalSortMode by screenModel.libraryPreferences.sortingMode.collectAsState()
val sortingMode = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
category.sort.type
} else {
@@ -205,9 +206,9 @@ private fun ColumnScope.SortPage(
!globalSortMode.isAscending
}
val hasSortTags by remember {
screenModel.libraryPreferences.sortTagsForLibrary().changes()
screenModel.libraryPreferences.sortTagsForLibrary.changes()
.map { it.isNotEmpty() }
}.collectAsState(initial = screenModel.libraryPreferences.sortTagsForLibrary().get().isNotEmpty())
}.collectAsState(initial = screenModel.libraryPreferences.sortTagsForLibrary.get().isNotEmpty())
// SY <--
val options = remember(trackers.isEmpty()/* SY --> */, hasSortTags/* SY <-- */) {
@@ -286,7 +287,7 @@ private val displayModes = listOf(
private fun ColumnScope.DisplayPage(
screenModel: LibrarySettingsScreenModel,
) {
val displayMode by screenModel.libraryPreferences.displayMode().collectAsState()
val displayMode by screenModel.libraryPreferences.displayMode.collectAsState()
SettingsChipRow(MR.strings.action_display_mode) {
displayModes.map { (titleRes, mode) ->
FilterChip(
@@ -301,52 +302,57 @@ private fun ColumnScope.DisplayPage(
val configuration = LocalConfiguration.current
val columnPreference = remember {
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
screenModel.libraryPreferences.landscapeColumns()
screenModel.libraryPreferences.landscapeColumns
} else {
screenModel.libraryPreferences.portraitColumns()
screenModel.libraryPreferences.portraitColumns
}
}
val columns by columnPreference.collectAsState()
SliderItem(
label = stringResource(MR.strings.pref_library_columns),
max = 10,
value = columns,
valueText = if (columns > 0) {
stringResource(MR.strings.pref_library_columns_per_row, columns)
valueRange = 0..10,
label = stringResource(MR.strings.pref_library_columns),
valueString = if (columns > 0) {
columns.toString()
} else {
stringResource(MR.strings.label_default)
stringResource(MR.strings.label_auto)
},
onChange = columnPreference::set,
pillColor = MaterialTheme.colorScheme.surfaceContainerHighest,
)
}
HeadingItem(MR.strings.overlay_header)
CheckboxItem(
label = stringResource(MR.strings.action_display_download_badge),
pref = screenModel.libraryPreferences.downloadBadge(),
pref = screenModel.libraryPreferences.downloadBadge,
)
CheckboxItem(
label = stringResource(MR.strings.action_display_unread_badge),
pref = screenModel.libraryPreferences.unreadBadge,
)
CheckboxItem(
label = stringResource(MR.strings.action_display_local_badge),
pref = screenModel.libraryPreferences.localBadge(),
pref = screenModel.libraryPreferences.localBadge,
)
CheckboxItem(
label = stringResource(MR.strings.action_display_language_badge),
pref = screenModel.libraryPreferences.languageBadge(),
pref = screenModel.libraryPreferences.languageBadge,
)
CheckboxItem(
label = stringResource(MR.strings.action_display_show_continue_reading_button),
pref = screenModel.libraryPreferences.showContinueReadingButton(),
pref = screenModel.libraryPreferences.showContinueReadingButton,
)
HeadingItem(MR.strings.tabs_header)
CheckboxItem(
label = stringResource(MR.strings.action_display_show_tabs),
pref = screenModel.libraryPreferences.categoryTabs(),
pref = screenModel.libraryPreferences.categoryTabs,
)
CheckboxItem(
label = stringResource(MR.strings.action_display_show_number_of_items),
pref = screenModel.libraryPreferences.categoryNumberOfItems(),
pref = screenModel.libraryPreferences.categoryNumberOfItems,
)
}
@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.util.fastAny
import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.model.MangaCover
@@ -15,7 +14,7 @@ internal fun LibraryComfortableGrid(
items: List<LibraryItem>,
columns: Int,
contentPadding: PaddingValues,
selection: List<LibraryManga>,
selection: Set<Long>,
onClick: (LibraryManga) -> Unit,
onLongClick: (LibraryManga) -> Unit,
onClickContinueReading: ((LibraryManga) -> Unit)?,
@@ -35,7 +34,7 @@ internal fun LibraryComfortableGrid(
) { libraryItem ->
val manga = libraryItem.libraryManga.manga
MangaComfortableGridItem(
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
isSelected = manga.id in selection,
title = manga.title,
coverData = MangaCover(
mangaId = manga.id,
@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.util.fastAny
import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.model.MangaCover
@@ -16,7 +15,7 @@ internal fun LibraryCompactGrid(
showTitle: Boolean,
columns: Int,
contentPadding: PaddingValues,
selection: List<LibraryManga>,
selection: Set<Long>,
onClick: (LibraryManga) -> Unit,
onLongClick: (LibraryManga) -> Unit,
onClickContinueReading: ((LibraryManga) -> Unit)?,
@@ -36,7 +35,7 @@ internal fun LibraryCompactGrid(
) { libraryItem ->
val manga = libraryItem.libraryManga.manga
MangaCompactGridItem(
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
isSelected = manga.id in selection,
title = manga.title.takeIf { showTitle },
coverData = MangaCover(
mangaId = manga.id,
@@ -29,22 +29,22 @@ import kotlin.time.Duration.Companion.seconds
fun LibraryContent(
categories: List<Category>,
searchQuery: String?,
selection: List<LibraryManga>,
selection: Set<Long>,
contentPadding: PaddingValues,
currentPage: () -> Int,
currentPage: Int,
hasActiveFilters: Boolean,
showPageTabs: Boolean,
onChangeCurrentPage: (Int) -> Unit,
onMangaClicked: (Long) -> Unit,
onClickManga: (Long) -> Unit,
onContinueReadingClicked: ((LibraryManga) -> Unit)?,
onToggleSelection: (LibraryManga) -> Unit,
onToggleRangeSelection: (LibraryManga) -> Unit,
onRefresh: (Category?) -> Boolean,
onToggleSelection: (Category, LibraryManga) -> Unit,
onToggleRangeSelection: (Category, LibraryManga) -> Unit,
onRefresh: () -> Boolean,
onGlobalSearchClicked: () -> Unit,
getNumberOfMangaForCategory: (Category) -> Int?,
getItemCountForCategory: (Category) -> Int?,
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
getLibraryForPage: (Int) -> List<LibraryItem>,
getItemsForCategory: (Category) -> List<LibraryItem>,
) {
Column(
modifier = Modifier.padding(
@@ -53,15 +53,14 @@ fun LibraryContent(
end = contentPadding.calculateEndPadding(LocalLayoutDirection.current),
),
) {
// SY -->
val coercedCurrentPage = remember(categories) { currentPage().coerceIn(0, categories.lastIndex) }
val pagerState = rememberPagerState(coercedCurrentPage) { categories.size }
val coercedCurrentPage = remember(categories, currentPage) { currentPage.coerceIn(0, categories.lastIndex) }
// SY <--
val pagerState = rememberPagerState(coercedCurrentPage) { categories.size }
val scope = rememberCoroutineScope()
var isRefreshing by remember(pagerState.currentPage) { mutableStateOf(false) }
if (showPageTabs && categories.size > 1) {
if (showPageTabs && categories.isNotEmpty() && (categories.size > 1 || !categories.first().isSystemCategory)) {
LaunchedEffect(categories) {
if (categories.size <= pagerState.currentPage) {
pagerState.scrollToPage(categories.size - 1)
@@ -70,23 +69,20 @@ fun LibraryContent(
LibraryTabs(
categories = categories,
pagerState = pagerState,
getNumberOfMangaForCategory = getNumberOfMangaForCategory,
) { scope.launch { pagerState.animateScrollToPage(it) } }
}
val notSelectionMode = selection.isEmpty()
val onClickManga = { manga: LibraryManga ->
if (notSelectionMode) {
onMangaClicked(manga.manga.id)
} else {
onToggleSelection(manga)
}
getItemCountForCategory = getItemCountForCategory,
onTabItemClick = {
scope.launch {
pagerState.animateScrollToPage(it)
}
},
)
}
PullRefresh(
refreshing = isRefreshing,
enabled = selection.isEmpty(),
onRefresh = {
val started = onRefresh(categories.getOrNull(currentPage()) ?: return@PullRefresh)
val started = onRefresh()
if (!started) return@PullRefresh
scope.launch {
// Fake refresh status but hide it after a second as it's a long running task
@@ -95,19 +91,25 @@ fun LibraryContent(
isRefreshing = false
}
},
enabled = notSelectionMode,
) {
LibraryPager(
state = pagerState,
contentPadding = PaddingValues(bottom = contentPadding.calculateBottomPadding()),
hasActiveFilters = hasActiveFilters,
selectedManga = selection,
selection = selection,
searchQuery = searchQuery,
onGlobalSearchClicked = onGlobalSearchClicked,
getCategoryForPage = { page -> categories[page] },
getDisplayMode = getDisplayMode,
getColumnsForOrientation = getColumnsForOrientation,
getLibraryForPage = getLibraryForPage,
onClickManga = onClickManga,
getItemsForCategory = getItemsForCategory,
onClickManga = { category, manga ->
if (selection.isNotEmpty()) {
onToggleSelection(category, manga)
} else {
onClickManga(manga.manga.id)
}
},
onLongClickManga = onToggleRangeSelection,
onClickContinueReading = onContinueReadingClicked,
)
@@ -7,7 +7,6 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastAny
import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.domain.manga.model.MangaCover
@@ -18,7 +17,7 @@ import tachiyomi.presentation.core.util.plus
internal fun LibraryList(
items: List<LibraryItem>,
contentPadding: PaddingValues,
selection: List<LibraryManga>,
selection: Set<Long>,
onClick: (LibraryManga) -> Unit,
onLongClick: (LibraryManga) -> Unit,
onClickContinueReading: ((LibraryManga) -> Unit)?,
@@ -45,7 +44,7 @@ internal fun LibraryList(
) { libraryItem ->
val manga = libraryItem.libraryManga.manga
MangaListItem(
isSelected = selection.fastAny { it.id == libraryItem.libraryManga.id },
isSelected = manga.id in selection,
title = manga.title,
coverData = MangaCover(
mangaId = manga.id,
@@ -20,6 +20,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
import eu.kanade.core.preference.PreferenceMutableState
import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.i18n.MR
@@ -31,14 +32,15 @@ fun LibraryPager(
state: PagerState,
contentPadding: PaddingValues,
hasActiveFilters: Boolean,
selectedManga: List<LibraryManga>,
selection: Set<Long>,
searchQuery: String?,
onGlobalSearchClicked: () -> Unit,
getCategoryForPage: (Int) -> Category,
getDisplayMode: (Int) -> PreferenceMutableState<LibraryDisplayMode>,
getColumnsForOrientation: (Boolean) -> PreferenceMutableState<Int>,
getLibraryForPage: (Int) -> List<LibraryItem>,
onClickManga: (LibraryManga) -> Unit,
onLongClickManga: (LibraryManga) -> Unit,
getItemsForCategory: (Category) -> List<LibraryItem>,
onClickManga: (Category, LibraryManga) -> Unit,
onLongClickManga: (Category, LibraryManga) -> Unit,
onClickContinueReading: ((LibraryManga) -> Unit)?,
) {
HorizontalPager(
@@ -50,9 +52,10 @@ fun LibraryPager(
// To make sure only one offscreen page is being composed
return@HorizontalPager
}
val library = getLibraryForPage(page)
val category = getCategoryForPage(page)
val items = getItemsForCategory(category)
if (library.isEmpty()) {
if (items.isEmpty()) {
LibraryPagerEmptyScreen(
searchQuery = searchQuery,
hasActiveFilters = hasActiveFilters,
@@ -72,12 +75,15 @@ fun LibraryPager(
remember { mutableIntStateOf(0) }
}
val onClickManga: (LibraryManga) -> Unit = { onClickManga(category, it) }
val onLongClickManga: (LibraryManga) -> Unit = { onLongClickManga(category, it) }
when (displayMode) {
LibraryDisplayMode.List -> {
LibraryList(
items = library,
items = items,
contentPadding = contentPadding,
selection = selectedManga,
selection = selection,
onClick = onClickManga,
onLongClick = onLongClickManga,
onClickContinueReading = onClickContinueReading,
@@ -87,11 +93,11 @@ fun LibraryPager(
}
LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> {
LibraryCompactGrid(
items = library,
items = items,
showTitle = displayMode is LibraryDisplayMode.CompactGrid,
columns = columns,
contentPadding = contentPadding,
selection = selectedManga,
selection = selection,
onClick = onClickManga,
onLongClick = onLongClickManga,
onClickContinueReading = onClickContinueReading,
@@ -101,10 +107,10 @@ fun LibraryPager(
}
LibraryDisplayMode.ComfortableGrid -> {
LibraryComfortableGrid(
items = library,
items = items,
columns = columns,
contentPadding = contentPadding,
selection = selectedManga,
selection = selection,
onClick = onClickManga,
onLongClick = onLongClickManga,
onClickContinueReading = onClickContinueReading,
@@ -18,15 +18,11 @@ import tachiyomi.presentation.core.components.material.TabText
internal fun LibraryTabs(
categories: List<Category>,
pagerState: PagerState,
getNumberOfMangaForCategory: (Category) -> Int?,
getItemCountForCategory: (Category) -> Int?,
onTabItemClick: (Int) -> Unit,
) {
// SY -->
val currentPageIndex = pagerState.currentPage.coerceAtMost(categories.lastIndex)
// SY <--
Column(
modifier = Modifier.zIndex(1f),
) {
Column(modifier = Modifier.zIndex(2f)) {
PrimaryScrollableTabRow(
selectedTabIndex = currentPageIndex,
edgePadding = 0.dp,
@@ -41,7 +37,7 @@ internal fun LibraryTabs(
text = {
TabText(
text = category.visualName,
badgeCount = getNumberOfMangaForCategory(category),
badgeCount = getItemCountForCategory(category),
)
},
unselectedContentColor = MaterialTheme.colorScheme.onSurface,
@@ -15,7 +15,6 @@ import androidx.compose.ui.window.DialogProperties
import exh.favorites.FavoritesSyncStatus
import kotlinx.coroutines.delay
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import kotlin.time.Duration.Companion.seconds
@@ -23,7 +22,6 @@ import kotlin.time.Duration.Companion.seconds
data class SyncFavoritesProgressProperties(
val title: String,
val text: String,
val canDismiss: Boolean,
val positiveButtonText: String? = null,
val positiveButton: (() -> Unit)? = null,
val negativeButtonText: String? = null,
@@ -34,18 +32,23 @@ data class SyncFavoritesProgressProperties(
fun SyncFavoritesProgressDialog(
status: FavoritesSyncStatus,
setStatusIdle: () -> Unit,
openManga: (Manga) -> Unit,
openManga: (Long) -> Unit,
) {
val context = LocalContext.current
val properties by produceState<SyncFavoritesProgressProperties?>(initialValue = null, status) {
when (status) {
is FavoritesSyncStatus.BadLibraryState.MangaInMultipleCategories -> value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_sync_error),
text = context.stringResource(SYMR.strings.favorites_sync_bad_library_state, status.message),
canDismiss = false,
text = context.stringResource(
SYMR.strings.favorites_sync_bad_library_state,
context.stringResource(
SYMR.strings.favorites_sync_gallery_in_multiple_categories, status.mangaTitle,
status.categories.joinToString(),
),
),
positiveButtonText = context.stringResource(SYMR.strings.show_gallery),
positiveButton = {
openManga(status.manga)
openManga(status.mangaId)
setStatusIdle()
},
negativeButtonText = context.stringResource(MR.strings.action_ok),
@@ -53,31 +56,122 @@ fun SyncFavoritesProgressDialog(
)
is FavoritesSyncStatus.CompleteWithErrors -> value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_sync_done_errors),
text = context.stringResource(SYMR.strings.favorites_sync_done_errors_message, status.message),
canDismiss = false,
positiveButtonText = context.stringResource(MR.strings.action_ok),
positiveButton = setStatusIdle,
)
is FavoritesSyncStatus.Error -> value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_sync_error),
text = context.stringResource(SYMR.strings.favorites_sync_error_string, status.message),
canDismiss = false,
text = context.stringResource(
SYMR.strings.favorites_sync_done_errors_message,
status.messages.joinToString(separator = "\n") {
when (it) {
is FavoritesSyncStatus.SyncError.GallerySyncError.GalleryAddFail ->
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
context.stringResource(
SYMR.strings.favorites_sync_failed_to_add_to_local_error, it.title, it.reason,
)
is FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail ->
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
context.stringResource(
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, it.url,
)
is FavoritesSyncStatus.SyncError.GallerySyncError.UnableToAddGalleryToRemote ->
context.stringResource(SYMR.strings.favorites_sync_unable_to_add_to_remote, it.title, it.gid)
FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote ->
context.stringResource(SYMR.strings.favorites_sync_unable_to_delete)
}
},
),
positiveButtonText = context.stringResource(MR.strings.action_ok),
positiveButton = setStatusIdle,
)
is FavoritesSyncStatus.Idle -> value = null
is FavoritesSyncStatus.Initializing, is FavoritesSyncStatus.Processing -> {
is FavoritesSyncStatus.Initializing -> {
value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_syncing),
text = status.message,
canDismiss = false,
text = context.stringResource(SYMR.strings.favorites_sync_initializing),
)
if (status is FavoritesSyncStatus.Processing && status.title != null) {
}
is FavoritesSyncStatus.SyncError -> value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_sync_error),
text = context.stringResource(
SYMR.strings.favorites_sync_error_string,
when (status) {
FavoritesSyncStatus.SyncError.NotLoggedInSyncError -> context.stringResource(SYMR.strings.please_login)
FavoritesSyncStatus.SyncError.FailedToFetchFavorites ->
context.stringResource(SYMR.strings.favorites_sync_failed_to_featch)
is FavoritesSyncStatus.SyncError.UnknownSyncError ->
context.stringResource(SYMR.strings.favorites_sync_unknown_error, status.message)
is FavoritesSyncStatus.SyncError.GallerySyncError.GalleryAddFail ->
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
context.stringResource(
SYMR.strings.favorites_sync_failed_to_add_to_local_error, status.title, status.reason,
)
is FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail ->
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
context.stringResource(
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, status.title, status.url,
)
is FavoritesSyncStatus.SyncError.GallerySyncError.UnableToAddGalleryToRemote ->
context.stringResource(SYMR.strings.favorites_sync_unable_to_add_to_remote, status.title, status.gid)
FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote ->
context.stringResource(SYMR.strings.favorites_sync_unable_to_delete)
},
),
positiveButtonText = context.stringResource(MR.strings.action_ok),
positiveButton = setStatusIdle,
)
is FavoritesSyncStatus.Processing -> {
val properties = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_syncing),
text = when (status) {
FavoritesSyncStatus.Processing.VerifyingLibrary ->
context.stringResource(SYMR.strings.favorites_sync_verifying_library)
FavoritesSyncStatus.Processing.DownloadingFavorites ->
context.stringResource(SYMR.strings.favorites_sync_downloading)
FavoritesSyncStatus.Processing.CalculatingRemoteChanges ->
context.stringResource(SYMR.strings.favorites_sync_calculating_remote_changes)
FavoritesSyncStatus.Processing.CalculatingLocalChanges ->
context.stringResource(SYMR.strings.favorites_sync_calculating_local_changes)
FavoritesSyncStatus.Processing.SyncingCategoryNames ->
context.stringResource(SYMR.strings.favorites_sync_syncing_category_names)
is FavoritesSyncStatus.Processing.RemovingRemoteGalleries ->
context.stringResource(SYMR.strings.favorites_sync_removing_galleries, status.galleryCount)
is FavoritesSyncStatus.Processing.AddingGalleryToRemote ->
if (status.isThrottling) {
context.stringResource(
SYMR.strings.favorites_sync_processing_throttle,
context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, status.index, status.total),
)
} else {
context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, status.index, status.total)
}
is FavoritesSyncStatus.Processing.RemovingGalleryFromLocal ->
context.stringResource(SYMR.strings.favorites_sync_remove_from_local, status.index, status.total)
is FavoritesSyncStatus.Processing.AddingGalleryToLocal ->
if (status.isThrottling) {
context.stringResource(
SYMR.strings.favorites_sync_processing_throttle,
context.stringResource(SYMR.strings.favorites_sync_add_to_local, status.index, status.total),
)
} else {
context.stringResource(SYMR.strings.favorites_sync_add_to_local, status.index, status.total)
}
FavoritesSyncStatus.Processing.CleaningUp ->
context.stringResource(SYMR.strings.favorites_sync_cleaning_up)
},
)
value = properties
if (
status is FavoritesSyncStatus.Processing.AddingGalleryToRemote ||
status is FavoritesSyncStatus.Processing.AddingGalleryToLocal
) {
delay(5.seconds)
value = SyncFavoritesProgressProperties(
title = context.stringResource(SYMR.strings.favorites_syncing),
text = status.delayedMessage ?: status.message,
canDismiss = false,
value = properties.copy(
text = when (status) {
is FavoritesSyncStatus.Processing.AddingGalleryToRemote ->
properties.text + "\n\n" + status.title
is FavoritesSyncStatus.Processing.AddingGalleryToLocal ->
properties.text + "\n\n" + status.title
else -> properties.text
},
)
}
}
@@ -112,8 +206,8 @@ fun SyncFavoritesProgressDialog(
}
},
properties = DialogProperties(
dismissOnClickOutside = dialog.canDismiss,
dismissOnBackPress = dialog.canDismiss,
dismissOnClickOutside = false,
dismissOnBackPress = false,
),
)
}
@@ -21,13 +21,14 @@ import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.manga.model.downloadedFilter
import eu.kanade.domain.manga.model.forceDownloaded
import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings
import kotlinx.collections.immutable.persistentListOf
@@ -40,6 +41,8 @@ import tachiyomi.presentation.core.components.SortItem
import tachiyomi.presentation.core.components.TriStateItem
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.theme.active
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@Composable
fun ChapterSettingsDialog(
@@ -63,6 +66,8 @@ fun ChapterSettingsDialog(
)
}
val downloadedOnly = remember { Injekt.get<BasePreferences>().downloadedOnly.get() }
TabbedDialog(
onDismissRequest = onDismissRequest,
tabTitles = persistentListOf(
@@ -97,7 +102,7 @@ fun ChapterSettingsDialog(
FilterPage(
downloadFilter = manga?.downloadedFilter ?: TriState.DISABLED,
onDownloadFilterChanged = onDownloadFilterChanged
.takeUnless { manga?.forceDownloaded() == true },
.takeUnless { downloadedOnly },
unreadFilter = manga?.unreadFilter ?: TriState.DISABLED,
onUnreadFilterChanged = onUnreadFilterChanged,
bookmarkedFilter = manga?.bookmarkedFilter ?: TriState.DISABLED,
@@ -1,44 +1,95 @@
package eu.kanade.presentation.manga
import androidx.compose.foundation.clickable
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Brush
import androidx.compose.material.icons.filled.PersonOutline
import androidx.compose.material.icons.filled.Warning
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Book
import androidx.compose.material.icons.outlined.SwapVert
import androidx.compose.material.icons.outlined.AttachMoney
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Done
import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.Pause
import androidx.compose.material.icons.outlined.Schedule
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextMeasurer
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.util.fastMaxOfOrNull
import coil3.request.ImageRequest
import coil3.request.crossfade
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.more.settings.LocalPreferenceMinHeight
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.SManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaWithChapterCount
import tachiyomi.domain.source.model.StubSource
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.Badge
import tachiyomi.presentation.core.components.BadgeGroup
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@Composable
fun DuplicateMangaDialog(
duplicates: List<MangaWithChapterCount>,
onDismissRequest: () -> Unit,
onConfirm: () -> Unit,
onOpenManga: () -> Unit,
onMigrate: () -> Unit,
onOpenManga: (manga: Manga) -> Unit,
onMigrate: (manga: Manga) -> Unit,
modifier: Modifier = Modifier,
) {
val sourceManager = remember { Injekt.get<SourceManager>() }
val minHeight = LocalPreferenceMinHeight.current
val horizontalPadding = PaddingValues(horizontal = TabbedDialogPaddings.Horizontal)
val horizontalPaddingModifier = Modifier.padding(horizontalPadding)
AdaptiveSheet(
modifier = modifier,
@@ -46,81 +97,310 @@ fun DuplicateMangaDialog(
) {
Column(
modifier = Modifier
.padding(
vertical = TabbedDialogPaddings.Vertical,
horizontal = TabbedDialogPaddings.Horizontal,
)
.padding(vertical = TabbedDialogPaddings.Vertical)
.verticalScroll(rememberScrollState())
.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.medium),
) {
Text(
modifier = Modifier.padding(TitlePadding),
text = stringResource(MR.strings.are_you_sure),
text = stringResource(MR.strings.possible_duplicates_title),
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier
.then(horizontalPaddingModifier)
.padding(top = MaterialTheme.padding.small),
)
Text(
text = stringResource(MR.strings.confirm_add_duplicate_manga),
text = stringResource(MR.strings.possible_duplicates_summary),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.then(horizontalPaddingModifier),
)
Spacer(Modifier.height(PaddingSize))
TextPreferenceWidget(
title = stringResource(MR.strings.action_show_manga),
icon = Icons.Outlined.Book,
onPreferenceClick = {
onDismissRequest()
onOpenManga()
},
)
HorizontalDivider()
TextPreferenceWidget(
title = stringResource(MR.strings.action_migrate_duplicate),
icon = Icons.Outlined.SwapVert,
onPreferenceClick = {
onDismissRequest()
onMigrate()
},
)
HorizontalDivider()
TextPreferenceWidget(
title = stringResource(MR.strings.action_add_anyway),
icon = Icons.Outlined.Add,
onPreferenceClick = {
onDismissRequest()
onConfirm()
},
)
Row(
modifier = Modifier
.sizeIn(minHeight = minHeight)
.clickable { onDismissRequest.invoke() }
.padding(ButtonPadding)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
LazyRow(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
modifier = Modifier.height(getMaximumMangaCardHeight(duplicates)),
contentPadding = horizontalPadding,
) {
OutlinedButton(onClick = onDismissRequest, modifier = Modifier.fillMaxWidth()) {
Text(
modifier = Modifier
.padding(vertical = 8.dp),
text = stringResource(MR.strings.action_cancel),
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.titleLarge,
fontSize = 16.sp,
items(
items = duplicates,
key = { it.manga.id },
) {
DuplicateMangaListItem(
duplicate = it,
getSource = { sourceManager.getOrStub(it.manga.source) },
onMigrate = { onMigrate(it.manga) },
onDismissRequest = onDismissRequest,
onOpenManga = { onOpenManga(it.manga) },
)
}
}
Column(modifier = horizontalPaddingModifier) {
HorizontalDivider()
TextPreferenceWidget(
title = stringResource(MR.strings.action_add_anyway),
icon = Icons.Outlined.Add,
onPreferenceClick = {
onDismissRequest()
onConfirm()
},
modifier = Modifier.clip(CircleShape),
)
}
OutlinedButton(
onClick = onDismissRequest,
modifier = Modifier
.then(horizontalPaddingModifier)
.padding(bottom = MaterialTheme.padding.medium)
.heightIn(min = minHeight)
.fillMaxWidth(),
) {
Text(
modifier = Modifier.padding(vertical = MaterialTheme.padding.extraSmall),
text = stringResource(MR.strings.action_cancel),
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.bodyLarge,
)
}
}
}
}
private val PaddingSize = 16.dp
@Composable
private fun DuplicateMangaListItem(
duplicate: MangaWithChapterCount,
getSource: () -> Source,
onDismissRequest: () -> Unit,
onOpenManga: () -> Unit,
onMigrate: () -> Unit,
) {
val source = getSource()
val manga = duplicate.manga
Column(
modifier = Modifier
.width(MangaCardWidth)
.clip(MaterialTheme.shapes.medium)
.background(MaterialTheme.colorScheme.surface)
.combinedClickable(
onLongClick = { onOpenManga() },
onClick = {
onDismissRequest()
onMigrate()
},
)
.padding(MaterialTheme.padding.small),
) {
Box {
MangaCover.Book(
data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
modifier = Modifier.fillMaxWidth(),
)
BadgeGroup(
modifier = Modifier
.padding(4.dp)
.align(Alignment.TopStart),
) {
Badge(
color = MaterialTheme.colorScheme.secondary,
textColor = MaterialTheme.colorScheme.onSecondary,
text = pluralStringResource(
MR.plurals.manga_num_chapters,
duplicate.chapterCount.toInt(),
duplicate.chapterCount,
),
)
}
}
private val ButtonPadding = PaddingValues(top = 16.dp, bottom = 16.dp)
private val TitlePadding = PaddingValues(bottom = 16.dp, top = 8.dp)
Spacer(modifier = Modifier.height(MaterialTheme.padding.extraSmall))
Text(
text = manga.title,
style = MaterialTheme.typography.titleSmall,
overflow = TextOverflow.Ellipsis,
maxLines = 2,
)
if (!manga.author.isNullOrBlank()) {
MangaDetailRow(
text = manga.author!!,
iconImageVector = Icons.Filled.PersonOutline,
maxLines = 2,
)
}
if (!manga.artist.isNullOrBlank() && manga.author != manga.artist) {
MangaDetailRow(
text = manga.artist!!,
iconImageVector = Icons.Filled.Brush,
maxLines = 2,
)
}
MangaDetailRow(
text = when (manga.status) {
SManga.ONGOING.toLong() -> stringResource(MR.strings.ongoing)
SManga.COMPLETED.toLong() -> stringResource(MR.strings.completed)
SManga.LICENSED.toLong() -> stringResource(MR.strings.licensed)
SManga.PUBLISHING_FINISHED.toLong() -> stringResource(MR.strings.publishing_finished)
SManga.CANCELLED.toLong() -> stringResource(MR.strings.cancelled)
SManga.ON_HIATUS.toLong() -> stringResource(MR.strings.on_hiatus)
else -> stringResource(MR.strings.unknown)
},
iconImageVector = when (manga.status) {
SManga.ONGOING.toLong() -> Icons.Outlined.Schedule
SManga.COMPLETED.toLong() -> Icons.Outlined.DoneAll
SManga.LICENSED.toLong() -> Icons.Outlined.AttachMoney
SManga.PUBLISHING_FINISHED.toLong() -> Icons.Outlined.Done
SManga.CANCELLED.toLong() -> Icons.Outlined.Close
SManga.ON_HIATUS.toLong() -> Icons.Outlined.Pause
else -> Icons.Outlined.Block
},
)
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
if (source is StubSource) {
Icon(
imageVector = Icons.Filled.Warning,
contentDescription = null,
modifier = Modifier.size(16.dp),
tint = MaterialTheme.colorScheme.error,
)
}
Text(
text = source.name,
style = MaterialTheme.typography.labelSmall,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
)
}
}
}
@Composable
private fun MangaDetailRow(
text: String,
iconImageVector: ImageVector,
maxLines: Int = 1,
) {
Row(
modifier = Modifier
.secondaryItemAlpha()
.padding(top = MaterialTheme.padding.extraSmall),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = iconImageVector,
contentDescription = null,
modifier = Modifier.size(MangaDetailsIconWidth),
)
Text(
text = text,
style = MaterialTheme.typography.bodySmall,
overflow = TextOverflow.Ellipsis,
maxLines = maxLines,
)
}
}
@Composable
private fun getMaximumMangaCardHeight(duplicates: List<MangaWithChapterCount>): Dp {
val density = LocalDensity.current
val typography = MaterialTheme.typography
val textMeasurer = rememberTextMeasurer()
val smallPadding = with(density) { MaterialTheme.padding.small.roundToPx() }
val extraSmallPadding = with(density) { MaterialTheme.padding.extraSmall.roundToPx() }
val width = with(density) { MangaCardWidth.roundToPx() - (2 * smallPadding) }
val iconWidth = with(density) { MangaDetailsIconWidth.roundToPx() }
val coverHeight = width / MangaCover.Book.ratio
val constraints = Constraints(maxWidth = width)
val detailsConstraints = Constraints(maxWidth = width - iconWidth - extraSmallPadding)
return remember(
duplicates,
density,
typography,
textMeasurer,
smallPadding,
extraSmallPadding,
coverHeight,
constraints,
detailsConstraints,
) {
duplicates.fastMaxOfOrNull {
calculateMangaCardHeight(
manga = it.manga,
density = density,
typography = typography,
textMeasurer = textMeasurer,
smallPadding = smallPadding,
extraSmallPadding = extraSmallPadding,
coverHeight = coverHeight,
constraints = constraints,
detailsConstraints = detailsConstraints,
)
}
?: 0.dp
}
}
private fun calculateMangaCardHeight(
manga: Manga,
density: Density,
typography: Typography,
textMeasurer: TextMeasurer,
smallPadding: Int,
extraSmallPadding: Int,
coverHeight: Float,
constraints: Constraints,
detailsConstraints: Constraints,
): Dp {
val titleHeight = textMeasurer.measureHeight(manga.title, typography.titleSmall, 2, constraints)
val authorHeight = if (!manga.author.isNullOrBlank()) {
textMeasurer.measureHeight(manga.author!!, typography.bodySmall, 2, detailsConstraints)
} else {
0
}
val artistHeight = if (!manga.artist.isNullOrBlank() && manga.author != manga.artist) {
textMeasurer.measureHeight(manga.artist!!, typography.bodySmall, 2, detailsConstraints)
} else {
0
}
val statusHeight = textMeasurer.measureHeight("", typography.bodySmall, 2, detailsConstraints)
val sourceHeight = textMeasurer.measureHeight("", typography.labelSmall, 1, constraints)
val totalHeight = coverHeight + titleHeight + authorHeight + artistHeight + statusHeight + sourceHeight
return with(density) { ((2 * smallPadding) + totalHeight + (5 * extraSmallPadding)).toDp() }
}
private fun TextMeasurer.measureHeight(
text: String,
style: TextStyle,
maxLines: Int,
constraints: Constraints,
): Int = measure(
text = text,
style = style,
overflow = TextOverflow.Ellipsis,
maxLines = maxLines,
constraints = constraints,
)
.size
.height
private val MangaCardWidth = 150.dp
private val MangaDetailsIconWidth = 16.dp
@@ -0,0 +1,45 @@
package eu.kanade.presentation.manga
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.manga.components.MangaNotesTextArea
import eu.kanade.tachiyomi.ui.manga.notes.MangaNotesScreen
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun MangaNotesScreen(
state: MangaNotesScreen.State,
navigateUp: () -> Unit,
onUpdate: (String) -> Unit,
) {
Scaffold(
topBar = { topBarScrollBehavior ->
AppBar(
titleContent = {
AppBarTitle(
title = stringResource(MR.strings.action_edit_notes),
subtitle = state.manga.title,
)
},
navigateUp = navigateUp,
scrollBehavior = topBarScrollBehavior,
)
},
) { contentPadding ->
MangaNotesTextArea(
state = state,
onUpdate = onUpdate,
modifier = Modifier
.padding(contentPadding)
.consumeWindowInsets(contentPadding)
.imePadding(),
)
}
}
@@ -1,10 +1,7 @@
package eu.kanade.presentation.manga
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -27,9 +24,11 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Icon
import androidx.compose.material3.SmallExtendedFloatingActionButton
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.animateFloatingActionButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -69,6 +68,7 @@ import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.getNameForMangaInfo
import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.source.online.all.Lanraragi
import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.source.online.all.NHentai
import eu.kanade.tachiyomi.source.online.english.EightMuses
@@ -87,6 +87,7 @@ import exh.source.isEhBasedManga
import exh.ui.metadata.adapters.EHentaiDescription
import exh.ui.metadata.adapters.EightMusesDescription
import exh.ui.metadata.adapters.HBrowseDescription
import exh.ui.metadata.adapters.LanraragiDescription
import exh.ui.metadata.adapters.MangaDexDescription
import exh.ui.metadata.adapters.NHentaiDescription
import exh.ui.metadata.adapters.PururinDescription
@@ -99,7 +100,6 @@ import tachiyomi.domain.source.model.StubSource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.TwoPanelBox
import tachiyomi.presentation.core.components.VerticalFastScroller
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
@@ -117,7 +117,7 @@ fun MangaScreen(
isTabletUi: Boolean,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@@ -142,6 +142,7 @@ fun MangaScreen(
onEditCategoryClicked: (() -> Unit)?,
onEditFetchIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onEditNotesClicked: () -> Unit,
// SY -->
onMetadataViewerClicked: () -> Unit,
onEditInfoClicked: () -> Unit,
@@ -164,7 +165,7 @@ fun MangaScreen(
onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit,
// Chapter selection
onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit,
onChapterSelected: (ChapterList.Item, Boolean, Boolean) -> Unit,
onAllChapterSelected: (Boolean) -> Unit,
onInvertSelection: () -> Unit,
) {
@@ -182,7 +183,7 @@ fun MangaScreen(
nextUpdate = nextUpdate,
chapterSwipeStartAction = chapterSwipeStartAction,
chapterSwipeEndAction = chapterSwipeEndAction,
onBackClicked = onBackClicked,
navigateUp = navigateUp,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onAddToLibraryClicked = onAddToLibraryClicked,
@@ -201,6 +202,7 @@ fun MangaScreen(
onEditCategoryClicked = onEditCategoryClicked,
onEditIntervalClicked = onEditFetchIntervalClicked,
onMigrateClicked = onMigrateClicked,
onEditNotesClicked = onEditNotesClicked,
// SY -->
onMetadataViewerClicked = onMetadataViewerClicked,
onEditInfoClicked = onEditInfoClicked,
@@ -228,7 +230,7 @@ fun MangaScreen(
chapterSwipeStartAction = chapterSwipeStartAction,
chapterSwipeEndAction = chapterSwipeEndAction,
nextUpdate = nextUpdate,
onBackClicked = onBackClicked,
navigateUp = navigateUp,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onAddToLibraryClicked = onAddToLibraryClicked,
@@ -247,6 +249,7 @@ fun MangaScreen(
onEditCategoryClicked = onEditCategoryClicked,
onEditIntervalClicked = onEditFetchIntervalClicked,
onMigrateClicked = onMigrateClicked,
onEditNotesClicked = onEditNotesClicked,
// SY -->
onMetadataViewerClicked = onMetadataViewerClicked,
onEditInfoClicked = onEditInfoClicked,
@@ -277,7 +280,7 @@ private fun MangaScreenSmallImpl(
nextUpdate: Instant?,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@@ -303,6 +306,7 @@ private fun MangaScreenSmallImpl(
onEditCategoryClicked: (() -> Unit)?,
onEditIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onEditNotesClicked: () -> Unit,
// SY -->
onMetadataViewerClicked: () -> Unit,
onEditInfoClicked: () -> Unit,
@@ -325,7 +329,7 @@ private fun MangaScreenSmallImpl(
onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit,
// Chapter selection
onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit,
onChapterSelected: (ChapterList.Item, Boolean, Boolean) -> Unit,
onAllChapterSelected: (Boolean) -> Unit,
onInvertSelection: () -> Unit,
) {
@@ -345,14 +349,9 @@ private fun MangaScreenSmallImpl(
}
// SY <--
val internalOnBackPressed = {
if (isAnySelected) {
onAllChapterSelected(false)
} else {
onBackClicked()
}
BackHandler(enabled = isAnySelected) {
onAllChapterSelected(false)
}
BackHandler(onBack = internalOnBackPressed)
Scaffold(
topBar = {
@@ -365,26 +364,25 @@ private fun MangaScreenSmallImpl(
val isFirstItemScrolled by remember {
derivedStateOf { chapterListState.firstVisibleItemScrollOffset > 0 }
}
val animatedTitleAlpha by animateFloatAsState(
val titleAlpha by animateFloatAsState(
if (!isFirstItemVisible) 1f else 0f,
label = "Top Bar Title",
)
val animatedBgAlpha by animateFloatAsState(
val backgroundAlpha by animateFloatAsState(
if (!isFirstItemVisible || isFirstItemScrolled) 1f else 0f,
label = "Top Bar Background",
)
MangaToolbar(
title = state.manga.title,
titleAlphaProvider = { animatedTitleAlpha },
backgroundAlphaProvider = { animatedBgAlpha },
hasFilters = state.filterActive,
onBackClicked = internalOnBackPressed,
navigateUp = navigateUp,
onClickFilter = onFilterClicked,
onClickShare = onShareClicked,
onClickDownload = onDownloadActionClicked,
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickEditNotes = onEditNotesClicked,
// SY -->
onClickEditInfo = onEditInfoClicked.takeIf { state.manga.favorite },
onClickRecommend = onRecommendClicked.takeIf { state.showRecommendationsInOverflow },
@@ -392,8 +390,11 @@ private fun MangaScreenSmallImpl(
onClickMerge = onMergeClicked.takeIf { state.showMergeInOverflow },
// SY <--
actionModeCounter = selectedChapterCount,
onCancelActionMode = { onAllChapterSelected(false) },
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
titleAlphaProvider = { titleAlpha },
backgroundAlphaProvider = { backgroundAlpha },
)
},
bottomBar = {
@@ -415,25 +416,23 @@ private fun MangaScreenSmallImpl(
val isFABVisible = remember(chapters) {
chapters.fastAny { !it.chapter.read } && !isAnySelected
}
AnimatedVisibility(
visible = isFABVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = {
val isReading = remember(state.chapters) {
state.chapters.fastAny { it.chapter.read }
}
Text(
text = stringResource(if (isReading) MR.strings.action_resume else MR.strings.action_start),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.shouldExpandFAB(),
)
}
SmallExtendedFloatingActionButton(
text = {
val isReading = remember(state.chapters) {
state.chapters.fastAny { it.chapter.read }
}
Text(
text = stringResource(if (isReading) MR.strings.action_resume else MR.strings.action_start),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.shouldExpandFAB(),
modifier = Modifier.animateFloatingActionButton(
visible = isFABVisible,
alignment = Alignment.BottomEnd,
),
)
},
) { contentPadding ->
val topPadding = contentPadding.calculateTopPadding()
@@ -519,12 +518,14 @@ private fun MangaScreenSmallImpl(
defaultExpandState = state.isFromSource,
description = state.manga.description,
tagsProvider = { state.manga.genre },
notes = state.manga.notes,
onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard,
onEditNotes = onEditNotesClicked,
// SY -->
doSearch = onSearch,
searchMetadataChips = remember(state.meta, state.source.id, state.manga.genre) {
SearchMetadataChips(state.meta, state.source, state.manga.genre)
SearchMetadataChips(state.meta, state.source.id, state.manga.genre)
},
// SY <--
)
@@ -600,7 +601,7 @@ fun MangaScreenLargeImpl(
nextUpdate: Instant?,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@@ -626,6 +627,7 @@ fun MangaScreenLargeImpl(
onEditCategoryClicked: (() -> Unit)?,
onEditIntervalClicked: (() -> Unit)?,
onMigrateClicked: (() -> Unit)?,
onEditNotesClicked: () -> Unit,
// SY -->
onMetadataViewerClicked: () -> Unit,
onEditInfoClicked: () -> Unit,
@@ -648,7 +650,7 @@ fun MangaScreenLargeImpl(
onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit,
// Chapter selection
onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit,
onChapterSelected: (ChapterList.Item, Boolean, Boolean) -> Unit,
onAllChapterSelected: (Boolean) -> Unit,
onInvertSelection: () -> Unit,
) {
@@ -672,14 +674,9 @@ fun MangaScreenLargeImpl(
val chapterListState = rememberLazyListState()
val internalOnBackPressed = {
if (isAnySelected) {
onAllChapterSelected(false)
} else {
onBackClicked()
}
BackHandler(enabled = isAnySelected) {
onAllChapterSelected(false)
}
BackHandler(onBack = internalOnBackPressed)
Scaffold(
topBar = {
@@ -689,25 +686,27 @@ fun MangaScreenLargeImpl(
MangaToolbar(
modifier = Modifier.onSizeChanged { topBarHeight = it.height },
title = state.manga.title,
titleAlphaProvider = { if (isAnySelected) 1f else 0f },
backgroundAlphaProvider = { 1f },
hasFilters = state.filterActive,
onBackClicked = internalOnBackPressed,
navigateUp = navigateUp,
onClickFilter = onFilterButtonClicked,
onClickShare = onShareClicked,
onClickDownload = onDownloadActionClicked,
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onClickEditNotes = onEditNotesClicked,
// SY -->
onClickEditInfo = onEditInfoClicked.takeIf { state.manga.favorite },
onClickRecommend = onRecommendClicked.takeIf { state.showRecommendationsInOverflow },
onClickMergedSettings = onMergedSettingsClicked.takeIf { state.manga.source == MERGED_SOURCE_ID },
onClickMerge = onMergeClicked.takeIf { state.showMergeInOverflow },
// SY <--
onCancelActionMode = { onAllChapterSelected(false) },
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
titleAlphaProvider = { 1f },
backgroundAlphaProvider = { 1f },
)
},
bottomBar = {
@@ -734,27 +733,25 @@ fun MangaScreenLargeImpl(
val isFABVisible = remember(chapters) {
chapters.fastAny { !it.chapter.read } && !isAnySelected
}
AnimatedVisibility(
visible = isFABVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
ExtendedFloatingActionButton(
text = {
val isReading = remember(state.chapters) {
state.chapters.fastAny { it.chapter.read }
}
Text(
text = stringResource(
if (isReading) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.shouldExpandFAB(),
)
}
SmallExtendedFloatingActionButton(
text = {
val isReading = remember(state.chapters) {
state.chapters.fastAny { it.chapter.read }
}
Text(
text = stringResource(
if (isReading) MR.strings.action_resume else MR.strings.action_start,
),
)
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.shouldExpandFAB(),
modifier = Modifier.animateFloatingActionButton(
visible = isFABVisible,
alignment = Alignment.BottomEnd,
),
)
},
) { contentPadding ->
PullRefresh(
@@ -814,12 +811,14 @@ fun MangaScreenLargeImpl(
defaultExpandState = true,
description = state.manga.description,
tagsProvider = { state.manga.genre },
notes = state.manga.notes,
onTagSearch = onTagSearch,
onCopyTagToClipboard = onCopyTagToClipboard,
onEditNotes = onEditNotesClicked,
// SY -->
doSearch = onSearch,
searchMetadataChips = remember(state.meta, state.source.id, state.manga.genre) {
SearchMetadataChips(state.meta, state.source, state.manga.genre)
SearchMetadataChips(state.meta, state.source.id, state.manga.genre)
},
// SY <--
)
@@ -948,7 +947,7 @@ private fun LazyListScope.sharedChapterItems(
// SY <--
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onChapterSelected: (ChapterList.Item, Boolean, Boolean, Boolean) -> Unit,
onChapterSelected: (ChapterList.Item, Boolean, Boolean) -> Unit,
onChapterSwipe: (ChapterList.Item, LibraryPreferences.ChapterSwipeAction) -> Unit,
) {
items(
@@ -1015,14 +1014,14 @@ private fun LazyListScope.sharedChapterItems(
chapterSwipeStartAction = chapterSwipeStartAction,
chapterSwipeEndAction = chapterSwipeEndAction,
onLongClick = {
onChapterSelected(item, !item.selected, true, true)
onChapterSelected(item, !item.selected, true)
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
},
onClick = {
onChapterItemClick(
chapterItem = item,
isAnyChapterSelected = isAnyChapterSelected,
onToggleSelection = { onChapterSelected(item, !item.selected, true, false) },
onToggleSelection = { onChapterSelected(item, !item.selected, false) },
onChapterClicked = onChapterClicked,
)
},
@@ -1086,6 +1085,9 @@ fun metadataDescription(source: Source): MetadataDescriptionComposable? {
is Tsumino -> { state, openMetadataViewer, _ ->
TsuminoDescription(state, openMetadataViewer)
}
is Lanraragi -> { state, openMetadataViewer, _ ->
LanraragiDescription(state, openMetadataViewer)
}
else -> null
}
}
@@ -6,6 +6,7 @@ enum class DownloadAction {
NEXT_10_CHAPTERS,
NEXT_25_CHAPTERS,
UNREAD_CHAPTERS,
BOOKMARKED_CHAPTERS,
}
enum class EditCoverAction {
@@ -9,6 +9,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
@@ -28,10 +29,8 @@ import androidx.compose.material.icons.outlined.BookmarkRemove
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.Label
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.RemoveDone
import androidx.compose.material.icons.outlined.SwapCalls
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
@@ -53,6 +52,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.DownloadDropdownMenu
import eu.kanade.presentation.components.DropdownMenu
@@ -93,10 +93,10 @@ fun MangaBottomActionMenu(
) {
val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false, false, false) }
var resetJob: Job? = remember { null }
var resetJob by remember { mutableStateOf<Job?>(null) }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(0..<7).forEach { i -> confirm[i] = i == toConfirmIndex }
confirm.indices.forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel()
resetJob = scope.launch {
delay(1.seconds)
@@ -193,7 +193,7 @@ private fun RowScope.Button(
targetValue = if (toConfirm) 2f else 1f,
label = "weight",
)
Column(
Box(
modifier = Modifier
.size(48.dp)
.weight(animatedWeight)
@@ -203,24 +203,28 @@ private fun RowScope.Button(
onLongClick = onLongClick,
onClick = onClick,
),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = icon,
contentDescription = title,
)
AnimatedVisibility(
visible = toConfirm,
enter = expandVertically(expandFrom = Alignment.Top) + fadeIn(),
exit = shrinkVertically(shrinkTowards = Alignment.Top) + fadeOut(),
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = title,
overflow = TextOverflow.Visible,
maxLines = 1,
style = MaterialTheme.typography.labelSmall,
Icon(
imageVector = icon,
contentDescription = title,
)
AnimatedVisibility(
visible = toConfirm,
enter = expandVertically(expandFrom = Alignment.Top) + fadeIn(),
exit = shrinkVertically(shrinkTowards = Alignment.Top) + fadeOut(),
) {
Text(
text = title,
overflow = TextOverflow.Visible,
maxLines = 1,
style = MaterialTheme.typography.labelSmall,
)
}
}
content?.invoke()
}
@@ -234,9 +238,10 @@ fun LibraryBottomActionMenu(
onMarkAsUnreadClicked: () -> Unit,
onDownloadClicked: ((DownloadAction) -> Unit)?,
onDeleteClicked: () -> Unit,
onMigrateClicked: (() -> Unit)?,
// SY -->
onClickCleanTitles: (() -> Unit)?,
onClickMigrate: (() -> Unit)?,
onClickCollectRecommendations: (() -> Unit)?,
onClickAddToMangaDex: (() -> Unit)?,
onClickResetInfo: (() -> Unit)?,
// SY <--
@@ -254,12 +259,11 @@ fun LibraryBottomActionMenu(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
) {
val haptic = LocalHapticFeedback.current
val confirm =
remember { mutableStateListOf(false, false, false, false, false /* SY --> */, false /* SY <-- */) }
var resetJob: Job? = remember { null }
val confirm = remember { mutableStateListOf(false, false, false, false, false, false) }
var resetJob by remember { mutableStateOf<Job?>(null) }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(0..<5).forEach { i -> confirm[i] = i == toConfirmIndex }
confirm.indices.forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel()
resetJob = scope.launch {
delay(1.seconds)
@@ -267,7 +271,11 @@ fun LibraryBottomActionMenu(
}
}
// SY -->
val showOverflow = onClickCleanTitles != null || onClickAddToMangaDex != null || onClickResetInfo != null
val showOverflow = onClickCleanTitles != null ||
onClickAddToMangaDex != null ||
onClickResetInfo != null ||
onClickCollectRecommendations != null ||
onMigrateClicked != null
val configuration = LocalConfiguration.current
val moveMarkPrev = remember { !configuration.isTabletUi() }
var overFlowOpen by remember { mutableStateOf(false) }
@@ -296,11 +304,11 @@ fun LibraryBottomActionMenu(
onLongClick = { onLongClickItem(3) },
onClick = { downloadExpanded = !downloadExpanded },
) {
val onDismissRequest = { downloadExpanded = false }
DownloadDropdownMenu(
expanded = downloadExpanded,
onDismissRequest = onDismissRequest,
onDismissRequest = { downloadExpanded = false },
onDownloadClicked = onDownloadClicked,
offset = BottomBarMenuDpOffset,
)
}
}
@@ -352,10 +360,16 @@ fun LibraryBottomActionMenu(
onClick = onClickCleanTitles,
)
}
if (onClickMigrate != null) {
if (onMigrateClicked != null) {
DropdownMenuItem(
text = { Text(stringResource(MR.strings.migrate)) },
onClick = onClickMigrate,
onClick = onMigrateClicked,
)
}
if (onClickCollectRecommendations != null) {
DropdownMenuItem(
text = { Text(stringResource(SYMR.strings.rec_search_short)) },
onClick = onClickCollectRecommendations,
)
}
if (onClickAddToMangaDex != null) {
@@ -379,18 +393,11 @@ fun LibraryBottomActionMenu(
onLongClick = { onLongClickItem(2) },
onClick = onMarkAsUnreadClicked,
)
if (onClickMigrate != null) {
Button(
title = stringResource(MR.strings.migrate),
icon = Icons.Outlined.SwapCalls,
toConfirm = confirm[5],
onLongClick = { onLongClickItem(5) },
onClick = onClickMigrate,
)
}
}
// SY <--
}
}
}
}
private val BottomBarMenuDpOffset = DpOffset(0.dp, 0.dp)
@@ -37,6 +37,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.updatePadding
import coil3.asDrawable
import coil3.imageLoader
@@ -172,20 +173,20 @@ fun MangaCoverDialog(
.memoryCachePolicy(CachePolicy.DISABLED)
.target { image ->
val drawable = image.asDrawable(view.context.resources)
// Copy bitmap in case it came from memory cache
// Because SSIV needs to thoroughly read the image
val copy = (drawable as? BitmapDrawable)?.let {
val config = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Bitmap.Config.HARDWARE
} else {
Bitmap.Config.ARGB_8888
}
BitmapDrawable(
view.context.resources,
it.bitmap.copy(config, false),
val copy = (drawable as? BitmapDrawable)
?.bitmap
?.copy(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Bitmap.Config.HARDWARE
} else {
Bitmap.Config.ARGB_8888
},
false,
)
} ?: drawable
?.toDrawable(view.context.resources)
?: drawable
view.setImage(copy, ReaderPageImageView.Config(zoomDuration = 500))
}
.build()

Some files were not shown because too many files have changed in this diff Show More