Compare commits

...

270 Commits

Author SHA1 Message Date
Jobobby04 a443629234 Fix reflection 2024-10-27 14:07:28 -04:00
Jobobby04 3de4711e03 Try this Shizuku fix 2024-10-27 13:34:33 -04:00
Weblate (bot) 106f63a657 Translations update from Hosted Weblate (#1289)
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/ar/
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/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/zh_Hans/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: Fordas <fordas15@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@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: Noah Kenzie Rodriguez-Beus <noahbeus@protonmail.com>
Co-authored-by: Sergeev Vladimir Dmitrievich <sekhmych@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: ZerOriSama <godarms2010@live.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2024-10-26 23:44:53 -04:00
Luqman 3c09343f7b allow chapter 0 dupe auto mark as read (#1291) 2024-10-26 23:31:44 -04:00
Jobobby04 86e1406565 Spotless 2024-10-26 23:30:07 -04:00
jobobby04 b48556aa9f Fix for ExHentai 2024-10-26 23:06:30 -04:00
Cuong-Tran f3e905513f Fix app crash when removing tracked entry from tracker (#1380)
(cherry picked from commit 6de06419f8afd842f7037e3ecb51200037af3a85)
2024-10-26 22:25:23 -04:00
Roshan Varughese 633a1892b3 Allow completely disabling "Update tracker" snackbar on mark as read (#1374)
Also fixes #1369

(cherry picked from commit fc2f339ea1cdc43c0041b2fed497dcfda853b85e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-10-26 22:25:11 -04:00
Cuong-Tran 74cf08b47b Add libs.material to presentation-widget (#1373)
Fixes some build issues

(cherry picked from commit 264030d6ecbc7492d884eb328b74399cd722dcb0)
2024-10-26 22:16:09 -04:00
Jobobby04 cc7ce80abf Ignore Shizuku min sdk since desurging is enabled 2024-10-26 22:15:35 -04:00
AntsyLich e06941f82d Update dependency com.pinterest.ktlint:ktlint-cli to v1.4.0
Co-authored-by: Mend Renovate <bot@renovateapp.com>
(cherry picked from commit 140083ee39df7d458e5ff9abc6d0ee9831d99387)
2024-10-26 21:59:54 -04:00
AntsyLich a8a290d03d Cleanup Slider usage
(cherry picked from commit df9fff60da3a38acd8fcd540b5fdd275be93f2d5)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt
#	app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt
2024-10-26 21:59:33 -04:00
Mend Renovate b49ca3ce4c Update dependency me.zhanghai.android.libarchive:library to v1.1.4 (#1378)
(cherry picked from commit aae0e3459ce13398a64b5cd9995f4a40a0120822)
2024-10-26 21:53:38 -04:00
Cuong-Tran c51c364cdd Avoid blocking call to load categories in settings (#1364)
(cherry picked from commit f7752a98b2452a69f22a469d0bcbf761fb1c6569)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsLibraryScreen.kt
2024-10-26 21:53:27 -04:00
abdurisaq 366415d323 Fix settings SliderItem steps count (#1356)
(cherry picked from commit 2ba7ed32802ffca1946d567b8afe49bfd3f4326e)
2024-10-26 21:52:33 -04:00
Roshan Varughese 14f6fd7908 Rework Auto Track on Mark as Read (#1365)
(cherry picked from commit c153ac01f545ce9259c58aa5d5f7223d2f8f628b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-10-26 21:52:24 -04:00
Mend Renovate 15f1ee2205 Update dependency com.google.firebase:firebase-bom to v33.5.1 (#1362)
(cherry picked from commit 78d2cc75d5dc04fe5cddcfaeb0a4502d48392f2d)
2024-10-26 21:51:14 -04:00
AntsyLich 651579b243 Update shizuku.version to v13.1.0
(cherry picked from commit c550a81598c98ef9a22dac8f6a408f5c15235fde)
2024-10-26 21:50:55 -04:00
Mend Renovate 8f596069fa Update dependency com.google.firebase:firebase-bom to v33.5.0 (#1352)
(cherry picked from commit 0be36a10c36d3b8c5802ff515302ed29cc8fa013)
2024-10-26 21:50:41 -04:00
Mend Renovate a28d526102 Update dependency org.junit.jupiter:junit-jupiter to v5.11.3 (#1351)
(cherry picked from commit e16c3953c709a6c35c4655f916119fdf665baa62)
2024-10-26 21:50:34 -04:00
Jobobby04 bbaa74d99c Fix build 2024-10-20 01:51:54 -04:00
AntsyLich 310b1ad69b Pass uncaught exception to default handler in GlobalExceptionHandler
Fixes #1347

(cherry picked from commit f3a2f566c8a09ab862758ae69b43da2a2cd8f1db)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/crash/GlobalExceptionHandler.kt
2024-10-20 01:04:23 -04:00
AntsyLich 7f37989c4e Rework Firebase setup
Fixes #1332
Closes #1339

(cherry picked from commit 15e3f28aa36bec3c31f212c572ab57ce960cc862)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2024-10-20 01:03:36 -04:00
AntsyLich 185920b984 Address deprecation, suggestion and spotless
(cherry picked from commit 3bf70b230fc2c3eda58c4d46dec3fb75668e4f69)
2024-10-20 01:02:06 -04:00
AntsyLich 4639077756 Revert "Tweak Preference.collectAsState"
This reverts commit 3bddb5538528c19388e364d21e6a6c16487af759.

Fixes #1341

(cherry picked from commit eb3bea8150ce9bf2320d15c879cbebaa6d51a4c6)
2024-10-20 01:01:58 -04:00
Mend Renovate 0bf1519c25 Update dependency androidx.compose:compose-bom to v2024.10.00 (#1338)
(cherry picked from commit 5612ae0149e9231c9691ee782da8159489a0d057)
2024-10-20 01:01:48 -04:00
Mend Renovate 45a36cef32 Update xml.serialization.version to v0.90.2 (#1331)
* Update xml.serialization.version to v0.90.2

* Fix build

---------

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

# Conflicts:
#	source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt
2024-10-20 01:01:41 -04:00
AntsyLich dece1bc0cb Change "Invalidate downloads index" to "Reindex downloads"
(cherry picked from commit d2afbfe4ede283076aae40633c79c3f90b4390e7)
2024-10-20 01:01:09 -04:00
Mend Renovate eaffd3f2dc Update dependency androidx.annotation:annotation to v1.9.0 (#1336)
(cherry picked from commit 337806d9e17e92a9134d59324e9857d05abc4db3)
2024-10-20 01:00:58 -04:00
Mend Renovate aabe409ee5 Update dependency androidx.glance:glance-appwidget to v1.1.1 (#1335)
(cherry picked from commit 443f6e0ae53dadce1f66818fac0cd1eeaa5fec27)
2024-10-20 01:00:50 -04:00
Mend Renovate e626cdd030 Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.3 (#1334)
(cherry picked from commit 572ee2f02a980a60a1120e7c0c88060fb1a7b3d2)
2024-10-20 01:00:43 -04:00
Mend Renovate b161c333ec Update dependency androidx.activity:activity-compose to v1.9.3 (#1333)
(cherry picked from commit ba1343bed8c00d5ed976111c710c9b5648676a59)
2024-10-20 01:00:36 -04:00
FlaminSarge e587bb7f44 [skip ci] Update i18n readme (#1328)
(cherry picked from commit 9f3d5d13d4fedcca53ebb779a2cfca1e286c79da)
2024-10-20 01:00:26 -04:00
Mend Renovate 6cf7ef7bba Update dependency com.android.tools.build:gradle to v8.7.1 (#1326)
(cherry picked from commit 48166b9b52836f225273651b21fb02e7aba4197e)
2024-10-14 19:32:51 -04:00
AntsyLich 91d61a75e3 Make sure random library sort is at the bottom
(cherry picked from commit 2e2c8d36c1e23bf274c7c19f1242e14b0c7afbc1)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt
2024-10-14 19:32:35 -04:00
AntsyLich 95ae5211a7 Reorder reader menu overflow items
(cherry picked from commit 788235feeca241228eac0561339dd07b5ea0b77d)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/reader/appbars/ReaderAppBars.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
2024-10-14 19:15:44 -04:00
AntsyLich 62afbf8ff3 Cleanup .gitignore files
(cherry picked from commit afa50029882655af8d5eea40aed7644fce4564d8)

# Conflicts:
#	.gitignore
#	app/.gitignore
2024-10-14 19:10:41 -04:00
Jobobby04 2ea8449eb7 Fix issue with not showing source names in merged manga sometimes 2024-10-14 16:49:49 -04:00
Fuad Hasan 697b0de226 Hide sync library option when sync is disabled (#1275)
* Hide sync library option when sync is disabled

- Add isSyncEnabled parameter to LibraryToolbar and LibraryRegularToolbar
- Pass isSyncEnabled from LibraryTab to LibraryToolbar
- Conditionally display sync library action based on isSyncEnabled
- Update LibraryContent to include isSyncEnabled parameter
- Adjust LibraryTab to handle sync-related functionality
- Remove direct dependency on SyncPreferences in LibraryToolbar

* Update LibraryScreenModel to react to sync service changes

- Replace static isSyncEnabled update with dynamic observation
- Use syncPreferences.syncService().changes() to update isSyncEnabled state
- Ensure isSyncEnabled is updated whenever the sync service changes

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

* Fix sync service state update in LibraryScreenModel

- Resolve ambiguity in lambda parameters
- Correctly update isSyncEnabled state based on syncService value

* Optimize sync service state updates in LibraryScreenModel

- Add distinctUntilChanged() to filter out consecutive duplicate emissions
- Simplify mutableState.update lambda for better readability
- Remove redundant boolean comparison in isSyncEnabled assignment

---------

Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2024-10-14 16:35:49 -04:00
NGB-Was-Taken 41e523e074 Allow adding multiple tags separated by commas (#1282) 2024-10-14 16:34:58 -04:00
NGB-Was-Taken dee543c7c5 Respect the altTitlesInDesc preference (MD) (#1283)
* Respect the `altTitlesInDesc` preference (MD)

* Replace hardcoded "Alternative Titles" with localized string
2024-10-14 16:34:26 -04:00
Weblate (bot) 788d3797cb Translations update from Hosted Weblate (#1268)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/de/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/eo/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ja/
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/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/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/zh_Hant/
Translation: Mihon/TachiyomiSY
Translation: Mihon/TachiyomiSY Plurals

Co-authored-by: Chrono Lux <amber_c001@protonmail.com>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: FateXBlood <fatexblood@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: Miguel Angel Gaitan Ortega <gamersusa9@gmail.com>
Co-authored-by: Milihraim <kirill06678@gmail.com>
Co-authored-by: Phymos <phymosmusic@gmail.com>
Co-authored-by: Simon Saade <simonsaade005@gmail.com>
Co-authored-by: Tim Schneeberger <tim.schneeberger@outlook.de>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
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>
2024-10-14 16:33:39 -04:00
Jobobby04 6464c00503 SpotlessApply 2024-10-14 16:23:36 -04:00
Cuong-Tran dc88ea8f63 honor downloadChapters (#1270) 2024-10-14 16:19:48 -04:00
renovate[bot] 95cbb35152 fix(deps): update dependency net.zetetic:sqlcipher-android to v4.6.1 (#1255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-14 16:16:02 -04:00
NGB-Was-Taken 558ce084c8 Show download state and progress on reader chapter list. (#1263)
* Show download state and progress on reader chapter list.

* Update download indicator on progress and status change.
2024-10-14 16:14:58 -04:00
Roshan Varughese 943555c0af Add option to backup non-library read entries (#1324)
Co-authored-by: jobobby04 <jobobby04@gmail.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit de36357da834bff4110dbb56dd7ce7aad04d3c7d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt
#	data/src/main/sqldelight/tachiyomi/data/mangas.sq
2024-10-14 16:12:10 -04:00
AntsyLich 216bc2c57d Adjust expandable fab animation
Co-authored-by: p
(cherry picked from commit eb6092bd0cfa09694985a8bafdd8bbf2815190a1)
2024-10-14 15:28:40 -04:00
AntsyLich cde3002355 Refrain from running spotless on weblate files
Those are akin to generated files and are likely to not follow our formatting

(cherry picked from commit 32d2c2ac1bc224cbda2f09a4023d7d120ea0e954)

# Conflicts:
#	buildSrc/src/main/kotlin/mihon.code.lint.gradle.kts
2024-10-14 15:28:30 -04:00
brewkunz db907cf270 Fix EnhancedTracker not auto binding when adding manga to library (#1298)
(cherry picked from commit 3ed8a91c7b37ed89e6c4cab91daa79e6c846abe3)
2024-10-14 15:26:20 -04:00
Roshan Varughese a269802af9 Confirmation dialog when removing privately installed extensions (#1320)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 87db3f90dee8aa566038b46d0bdc975e715ab8f6)
2024-10-14 15:26:12 -04:00
Mend Renovate affab50a02 Update dependency me.zhanghai.android.libarchive:library to v1.1.3 (#1321)
(cherry picked from commit 0a4ad89b9902061e3e2c2d9f2eb71f6b33c5c01c)
2024-10-14 15:26:03 -04:00
Jack Hamilton 2f102db19d Added random library sort (#1317)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit a72db41bf1746db095fd27bbbce9765c06453581)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt
2024-10-14 15:25:20 -04:00
Roshan Varughese 457e5f963b Add Quantity Badge to Upcoming Screen (#1250)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 6b2bba4e5495274552787adc20db390a89d783b6)
2024-10-14 15:20:37 -04:00
Roshan Varughese 2bd9a914c1 Add option to opt out of Analytics and Crashlytics (#1237)
(cherry picked from commit 7c7af72f8cb12decc06b76c36852dcc54696236d)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSecurityScreen.kt
#	app/src/standard/AndroidManifest.xml
2024-10-14 15:20:28 -04:00
AntsyLich f6d2d0bd48 Remove usage of deprecated accompanist SystemUiController
Co-authored-by: p
(cherry picked from commit 2ba3f0612c08c7021fed2f6d96cd538da2f34a13)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
2024-10-14 15:05:44 -04:00
AntsyLich 91ae683b74 ChapterNavigator: dispatch page change only when needed
Co-authored-by: p
(cherry picked from commit f84d9a08b4af768b1e9920c43cc445c86f5427fc)
2024-10-14 14:59:06 -04:00
AntsyLich bccd1eff2b Bump compile sdk to 35
Co-authored-by: p
(cherry picked from commit 37419cdc26c2b5c4f8583fc2ba439b08fab42856)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
#	core/common/src/main/kotlin/eu/kanade/tachiyomi/util/system/WebViewUtil.kt
2024-10-14 14:58:56 -04:00
AntsyLich 9ed90eb6f2 Update resources exclusion rules
Co-authored-by: p
(cherry picked from commit 481cfedf08576cecfbb35616837bd8f627d8f959)
2024-10-14 14:48:08 -04:00
AntsyLich a246d897de Adjust distinct checker in WidgetManager and run on default dispatcher
Co-authored-by: p
(cherry picked from commit 9b8ab6acc25a5f99c9c5eebf9cc250975931c57c)
2024-10-14 14:47:59 -04:00
AntsyLich 4923ba0b54 Tweak Preference.collectAsState
Co-authored-by: p
(cherry picked from commit 3bddb5538528c19388e364d21e6a6c16487af759)
2024-10-14 14:47:34 -04:00
AntsyLich bd278b1878 Cleanup LibraryScreenModel LibraryMap.applySort and some more
(cherry picked from commit 2beb89d53163a6d288f8acdebe0f5d26fea8ab3e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
2024-10-14 14:47:20 -04:00
Mend Renovate ea0816a6c1 Update kotlin monorepo to v2.0.21 (#1314)
(cherry picked from commit 016f627fb0998dabcd6aea907b54365aa4e6a285)
2024-10-14 14:05:39 -04:00
brewkunz af3c7a0753 Retain remote last chapter read if it's higher than the local one for EnhancedTracker (#1301)
(cherry picked from commit 44aab7a2437ffdab354ee5ed82593fbaabb06a64)
2024-10-14 14:05:30 -04:00
Mend Renovate 4a9184bfc1 Update dependency io.mockk:mockk to v1.13.13 (#1313)
(cherry picked from commit a2dc88965b8b06cd40d65b75450e1ca4a1e08bd4)
2024-10-14 14:05:21 -04:00
AntsyLich 77d75de855 Update renovate configuration
- Remove package rule for "dev.chrisbanes.compose:compose-bom"
- Disable semantic commits

(cherry picked from commit aa998071a1f476a6078f19500bc58f7855c3f8ae)

# Conflicts:
#	.github/renovate.json5
2024-10-14 14:05:12 -04:00
Mend Renovate d7fbdb1b35 fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-rc01 (#1308)
(cherry picked from commit 8113b77f1e762629f31cbcc5b9163819c6384a8b)
2024-10-14 14:04:12 -04:00
Secozzi 6ad9eb098f Fix AniList ALSearchItem.status nullibility (#1297)
(cherry picked from commit 76e0aba70cc3a744e6ef4950a89ff6a498a54909)
2024-10-14 14:04:04 -04:00
Mend Renovate a6667bc91d fix(deps): update dependency androidx.compose:compose-bom to v2024.09.03 (#1288)
(cherry picked from commit f7fbc93833c6107791680412cc110336d0e4e717)
2024-10-14 14:03:56 -04:00
Mend Renovate 1e7b6d488c fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.11.2 (#1294)
(cherry picked from commit 85ee9c6686ee4f4ca5519297df7c4b5482cc26c2)
2024-10-14 14:03:48 -04:00
Mend Renovate d0ef7bcd54 fix(deps): update dependency androidx.profileinstaller:profileinstaller to v1.4.1 (#1289)
(cherry picked from commit c72c07f355a93f67d16166715dfdab88f2cc9201)
2024-10-14 14:03:40 -04:00
Mend Renovate e29e7c9169 fix(deps): update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.2 (#1287)
(cherry picked from commit 6984e0465babed7638481b1982de7415612f32e5)
2024-10-14 14:03:31 -04:00
Mend Renovate 4eb8dc35b9 fix(deps): update dependency com.google.firebase:firebase-bom to v33.4.0 (#1285)
(cherry picked from commit 3ca989eae8593a121fc22a617160f5d7439f937a)
2024-10-14 14:03:22 -04:00
Mend Renovate 1077820d59 fix(deps): update dependency com.android.tools.build:gradle to v8.7.0 (#1284)
(cherry picked from commit cca33481dd1466ae6a9919796229586fe0937523)
2024-10-14 14:02:39 -04:00
renovate[bot] ccf1f3b6ef chore(deps): update dependency gradle to v8.10.2 (#1254)
* chore(deps): update dependency gradle to v8.10.2

* Update binaries

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit f7c8f1801ea8c7af7542ab8e3dce035ada495c7c)
2024-10-14 14:02:30 -04:00
renovate[bot] 73d91a8537 fix(deps): update dependency androidx.compose:compose-bom to v2024.09.02 (#1239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 112b68b782d0f0ac027bf3d73ad28a8df0dc75b8)
2024-10-14 14:02:21 -04:00
renovate[bot] a141e63408 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.11.1 (#1262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 2dd02b73d6059cef372e5d605efdafa7f60b47b0)
2024-10-14 14:02:15 -04:00
renovate[bot] 3e1c346a04 fix(deps): update dependency me.zhanghai.android.libarchive:library to v1.1.2 (#1255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit d04eeface97d64d921e9df23ffeba49d3eca2994)
2024-10-14 14:02:06 -04:00
renovate[bot] 6872dc449f fix(deps): update dependency androidx.profileinstaller:profileinstaller to v1.4.0 (#1242)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 380787a31021d710a8a6619d4e0c1b01e3e47941)
2024-10-14 14:01:48 -04:00
renovate[bot] c672548491 fix(deps): update lifecycle.version to v2.8.6 (#1241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 418ba3026546b4785907c001a05006b609b490a3)
2024-10-14 14:01:40 -04:00
renovate[bot] 74abed9abd fix(deps): update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.1 (#1238)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit b3867dd63c714333f58678f13b4cafc708cbd918)
2024-10-14 14:01:26 -04:00
renovate[bot] cb813908a6 fix(deps): update serialization.version to v1.7.3 (#1246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 6dd93d70cc5c7fa39157d069b41be5557256537e)
2024-10-14 14:01:18 -04:00
Roshan Varughese 049a395790 Change casing for Extention Repos String (#1248)
(cherry picked from commit 2276abbb2373b94535e99c2d72ce0f7f6a1d008a)
2024-10-14 14:01:10 -04:00
renovate[bot] bc79694eae fix(deps): update dependency com.android.tools.build:gradle to v8.6.1 (#1235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 0042cb6582f05d2a139b059bef81dc979e9a8ad6)
2024-10-14 14:00:41 -04:00
renovate[bot] 812f76b8f5 fix(deps): update dependency me.zhanghai.android.libarchive:library to v1.1.1 (#1229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 1e570bc9654fb0382a8d5b37923c9700e49be696)
2024-10-14 14:00:34 -04:00
Roshan Varughese 4d8b5fc8a1 Re-enable fetching chapters list for entries with licenced status (#1230)
Enable Licensed

(cherry picked from commit 9cc7d42dd9676319559eddc7a4a264fca155e1ca)
2024-10-14 14:00:26 -04:00
MajorTanya a40c54e60c Fix Kitsu synopsis nullability (#1233)
This time, the Kitsu API docs are silent on whether this field (or
any other field) can be null/undefined/etc, but it can happen and
caused an error during search and update. This change just ensures the
attribute is nullable and is set to an empty String when it is null.

(cherry picked from commit f5c6d2e1a6896c031b8f4583375ee868f252822a)
2024-10-14 14:00:16 -04:00
Roshan Varughese e8ff402fff Fix WheelPicker Manual Input (#1209)
* Fix WheelPicker Manual Input

* Lambda

* inline

* Update WheelPicker.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 339dc33f5833b224c01577da3da081deecdbbca2)
2024-10-14 14:00:02 -04:00
Cuong-Tran 0753ffe425 Fix: wrong calculation of nextUpdate when setting custom fetchInterval (#1206)
(cherry picked from commit 223af5508f6b56c7d7bf1c68d3c96a59a1ebc5d7)
2024-10-14 13:59:56 -04:00
renovate[bot] 03aa27fb6b fix(deps): update dependency androidx.compose:compose-bom to v2024.09.01 (#1214)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit d42f776c5c5ddd8fade02bc7d0117a7c3e1054d5)
2024-10-14 13:59:48 -04:00
renovate[bot] 51b9004a2d fix(deps): update dependency com.google.firebase:firebase-bom to v33.3.0 (#1216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 5c0dc3e05a8de6b4c75452ea10328935a0de0f37)
2024-10-14 13:59:42 -04:00
renovate[bot] 23285587a7 fix(deps): update dependency com.squareup.okio:okio to v3.9.1 (#1217)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit bebf80dfaec037559af061950083289a0ae23b44)
2024-10-14 13:59:34 -04:00
renovate[bot] 5dcc02c44f fix(deps): update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.9.0 (#1222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 1ff88dd9274db681ae0d76b39223389a1f758973)
2024-10-14 13:59:26 -04:00
renovate[bot] ecd38d9429 chore(deps): update dependency gradle to v8.10.1 (#1211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit fcb01b5bcf81e7c25ff820e99fcf10e867c3782f)
2024-10-14 13:59:15 -04:00
renovate[bot] 3b3e3f5d35 fix(deps): update dependency org.jetbrains.kotlinx:kotlinx-collections-immutable to v0.3.8 (#1198)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 844dae1a4d23b88318e0ea482b38df4e3f5f2be2)
2024-10-14 13:59:08 -04:00
NGB-Was-Taken 0d66d03f56 Show toast for app restart when User-Agent is changed (#1204)
(cherry picked from commit c8ad6cdf31a14bce9a525cfc2a0616e8ac51d7c3)
2024-10-14 13:58:53 -04:00
AntsyLich a68bb60126 Bump NDK version (#1203)
(cherry picked from commit fbcc48fefc7ed050f6416a8684816730bcb5f8a8)

# Conflicts:
#	buildSrc/src/main/kotlin/mihon/buildlogic/AndroidConfig.kt
2024-10-14 13:58:45 -04:00
AntsyLich 1e9f7612f0 Reduce ChapterNavigator horizontal padding on small ui (#1202)
Co-authored-by: p
(cherry picked from commit 6f422745ba6db135514ac4959216923932565760)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/reader/components/ChapterNavigator.kt
2024-10-14 13:58:16 -04:00
AntsyLich 51229ca511 Use TextFieldState in BasicTextField where applicable (#1201)
Co-authored-by: p
(cherry picked from commit bec549cc444328c8b46594c67a84d25dcc1aca6f)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsSearchScreen.kt
2024-10-14 13:56:14 -04:00
Jobobby04 b98e198e15 SpotlessApply 2024-10-14 13:54:54 -04:00
bapeey 3cac63ed91 Ignore "intent://" urls on webview (#1193)
ignore intent urls

(cherry picked from commit b56a97bb8eaf336c75e69e7fb32b87431d991bb3)
2024-10-14 13:50:55 -04:00
renovate[bot] 6bb2bc03f3 fix(deps): update dependency androidx.activity:activity-compose to v1.9.2 (#1189)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 52036e5664cbcf552de706adee6e0b4b972fe1c3)
2024-10-14 13:50:48 -04:00
renovate[bot] da3823daed fix(deps): update dependency com.google.accompanist:accompanist-systemuicontroller to v0.36.0 (#1192)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 29a74509a4af475694551808e317df96ea1146ad)
2024-10-14 13:50:39 -04:00
renovate[bot] 3edb03de32 fix(deps): update lifecycle.version to v2.8.5 (#1190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 0e956cbb518e0e0827c1e7dfde8427cb8660a9fb)
2024-10-14 13:50:31 -04:00
Tran M. Cuong 3408ef635d Fix disappearance items when fast scrolling (#1035)
* Don't use animateItem's fade-in/fade-out in FastScrollLazyColumn

* Move to extension function

Avoid using animateItemPlacement name since it's shadowed by compose-bom's deprecated one

(cherry picked from commit 913ff22132390a59a13c463645ce954c7cbc5c6b)
2024-10-14 13:50:10 -04:00
renovate[bot] 365cd0b14d fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.05.00-alpha03 (#843)
* fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.05.00-alpha03

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 777a071f4a2f32efc3447d118afd8b48006b3919)
2024-10-14 13:39:16 -04:00
AntsyLich 96439afce4 Bump compose version
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit e473c7f09fc009161145aca94bd70027f042b0bf)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/browse/components/GlobalSearchResultItems.kt
#	app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt
#	gradle/compose.versions.toml
2024-10-14 13:38:38 -04:00
AntsyLich c1c615000b Switch to stable compose
(cherry picked from commit 2baffa62cade1abd978d5fd03151b47fc87fd31e)

# Conflicts:
#	gradle/compose.versions.toml
2024-10-14 13:37:01 -04:00
AntsyLich 58df8b79fb Rename LocalesConfigPlugin file to LocalesConfigTask
(cherry picked from commit 70c1a842b207d8faf0d87635674667d190669fd1)
2024-10-14 13:01:00 -04:00
MajorTanya f524763854 Fix Kitsu ratingTwenty being typed as String (#1191)
The API docs and the responses type `ratingTwenty` as a "number" (Int
in Kotlin, it's divided by 2 for a .5 step scale 0-10). It's nullable
because an entry without a user rating returns `null` in that field.

(cherry picked from commit 001249a89dd4824a3df5661733062662c0ab44bd)
2024-10-14 13:00:48 -04:00
renovate[bot] 402f5e6bad fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.2 (#1188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit c4d2fffb12c83c76cf48a85cbc9d7d754a4da39c)
2024-10-14 13:00:35 -04:00
AntsyLich 0d13c6187c Fix mishap in 02af9b1acf9f590d29560bc3fc90d206e8e6e1af
(cherry picked from commit f22767d863a0fa001f93f24092cd5ade87350502)
2024-10-14 13:00:13 -04:00
AntsyLich 1853a86a73 Remove more unnecessary permissions from Firebase dependency
(cherry picked from commit 02af9b1acf9f590d29560bc3fc90d206e8e6e1af)
2024-10-14 13:00:07 -04:00
AntsyLich 77e6e06cfa Add crashlytics to standard builds
(cherry picked from commit 3c611b95fb79e5ac972019b76c7b24f46a3087fd)

# Conflicts:
#	app/build.gradle.kts
2024-10-14 12:59:57 -04:00
AntsyLich 21440a0290 Migrate some classpaths to gradle plugins
(cherry picked from commit fc1c804bfda1d76c0399bbb6214e75b3def951cc)

# Conflicts:
#	app/build.gradle.kts
#	build.gradle.kts
#	i18n/build.gradle.kts
2024-10-14 12:32:35 -04:00
Roshan Varughese d6ffef15e1 Option to update trackers when chapter marked as read (#1177)
* Track when marked as read

* Add dismiss to snack bar

* i18n & ignore decimal chapters

* Detekt would have caught that 🤣

* `Ok` > `Yes`

* Dont prompt if untracked or current > new

* Move to MangaScreenModel

* Suggestions

Co-Authored-By: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

* Review 2

* toggleAllSelections first

---------

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

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-10-14 12:27:14 -04:00
Smol Ame 3cc250e122 Enable 'Split Tall Images' by default (#1185)
(cherry picked from commit 9c1905ede750f0229fad1a01431058b1cc9fb32d)
2024-10-14 12:26:23 -04:00
MajorTanya 051c559840 Use DTOs to parse tracking API responses (#1103)
* Migrate tracking APIs to DTOs

Changes the handling of tracker API responses to be parsed to DTOs
instead of doing so "manually" by use of `jsonPrimitive`s and/or
`Json.decodeFromString` invocations.

This greatly simplifies the API response handling.

Renamed constants to SCREAMING_SNAKE_CASE.

Largely tried to name the DTOs in a uniform pattern, with the
tracker's (short) name at the beginning of file and data class names
(ALOAuth instead of OAuth, etc).

With these changes, no area of the code base should be using
`jsonPrimitive` and/or `Json.decodeFromString` anymore.

* Fix wrong types in KitsuAlgoliaSearchItem

This API returns start and end dates as Long and the score as Double.

Kitsu's docs claim they're strings (and they are, when requesting
manga details from Kitsu directly) but the Algolia search results
return Longs and Double, respectively.

* Apply review changes

- Renamed `BangumiX` classes to `BGMX` classes.
- Renamed `toXStatus` and `toXScore` to `toApiStatus` and `toApiScore`

* Handle migration from detekt to spotless

Removed Suppressions added for detekt.

Specifically removed:
- `SwallowedException` where an exception ends as a default value
- `MagicNumber`
- `CyclomaticComplexMethod`
- `TooGenericExceptionThrown`

Also ran spotlessApply which changed SMAddMangaResponse

* Fix Kitsu failing to add series

The `included` attribute seems to only appear when the user already
has the entry in their Kitsu list.

Since both `data` and `included` are required for `firstToTrack`, a
guard clause has been added before all its calls.

* Fix empty Bangumi error when entry doesn't exist

Previously, the non-null assertion (!!) would cause a
NullPointerException and a Toast with
"Bangumi error: " (no message) when the user had removed their list
entry from Bangumi through other means like the website.

Now it will show "Bangumi error: Could not find manga".

This is analogous to the error shown by Kitsu under these
circumstances.

* Fix Shikimori ignoring missing remote entry

The user would see no indication that Shikimori could not properly
refresh the track from the remote. This change causes the error Toast
notification to pop up with the following message
"Shikimori error: Could not find manga".

This is analogous to Kitsu and Bangumi.

* Remove usage of let where not needed

These particular occurrences weren't needed because properties are
directly accessible to further act upon. This neatly simplifies these
clauses.

* Remove missed let

(cherry picked from commit 9f99f038f341e325c4f56372a5ce950cf9f7cd6d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistInterceptor.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuInterceptor.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt
2024-10-14 12:26:09 -04:00
AntsyLich 3972d7fe4b spotlessApply my beloved
(cherry picked from commit 6c6ea84509cc1bd859c880bebbc69067a241b358)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
2024-10-14 12:19:01 -04:00
AntsyLich 44fd9f3564 Add stable marker to Manga data class
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 4ee31bfea5b6908e7131e2c46e4cb46155005abf)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt
#	domain/build.gradle.kts
2024-10-14 12:17:18 -04:00
AntsyLich f36906df45 Collect MangaScreen state with lifecycle
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 03eb756ecba0692d88d3a76254afc4c157fa225b)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-10-14 12:07:03 -04:00
AntsyLich efbaf1a4ca PagerPageHolder: lazy init loading indicator
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit a45eb5e5288159dbbbbb5f92140ce0dd32a8f3ab)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt
2024-10-14 12:05:13 -04:00
Jobobby04 2f8efe0526 Switch Injekt to Koin-Injekt bridge and implement InjektRegistrar bridge 2024-10-14 11:59:02 -04:00
AntsyLich dea38912fc Use feature flags in compose compiler plugin
And slight cleanup

(cherry picked from commit 8f9a325895bb7b94c2ec92dd969094fc30b3b5e2)
2024-09-01 11:39:34 -04:00
renovate[bot] 5243346356 fix(deps): update dependency com.android.tools.build:gradle to v8.6.0 (#1178)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit f74071ab0a70c4fd649b451e58841539d011496a)
2024-09-01 11:39:27 -04:00
renovate[bot] 6bb3ec5b8a fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.1 (#1172)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 7fb3ef48e4fafce471173111fe1632754e5e9e99)
2024-09-01 11:39:20 -04:00
renovate[bot] 7390e72045 fix(deps): update serialization.version to v1.7.2 (#1173)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 1837faa573f11a6b97fe13f358d6fa0e980c2ef7)
2024-09-01 11:39:12 -04:00
AntsyLich 64ff5cb9af Remove legacy broken source and history backup
(cherry picked from commit 518abf032ccb9bb45d197927be2a5faca4167d29)
2024-09-01 11:38:46 -04:00
Roshan Varughese 82f011e48e Hide keyboard when a Tracker SearchResultItem is clicked (#1168)
* Hide keyboard on select

* Code Review Suggestion

(cherry picked from commit 7ca64a67c5c64103aa3a5c7efb9227d3a98b715d)
2024-09-01 11:38:36 -04:00
renovate[bot] 8868a5db2b fix(deps): update dependency com.android.tools:desugar_jdk_libs to v2.1.0 (#1162)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 607e56a4ec6393a3bfd25fe74cbae676fd94df22)
2024-09-01 11:38:27 -04:00
Catting a335feedfc Add "show entry" action to download notifications (#1159)
* Add 'show entry' to download notifications

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>

* fixup! Add 'show entry' to download notifications

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>

* fixup! Add 'show entry' to download notifications

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>

* spotless! Add 'show entry' to download notifications

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>

* Apply suggestions from code review

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

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

* fixup! spotless- Apply suggestions from code review

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>

---------

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 952a98c1804b2134e59fcb471c54cf7c4e1f415e)
2024-09-01 11:38:14 -04:00
Roshan Varughese 90ff5e69ec Add confirmation when adding repo via URI (#1158)
* Add confirmation when adding repo via URI

* Blank lines

* Suggestions

* Reverting Changes

* Removing Unused Imports

(cherry picked from commit 45628b14db477b266eb1f1f4ca9bec0b43f741cc)
2024-09-01 11:37:58 -04:00
Roshan Varughese 68a1820695 Respect privacy settings in extension update notification (#1156)
* Hide Extension Names in Update Notifications when Content is Hidden

* Moving `val` inside if

* [skip ci] Update CHANGELOG.md

(cherry picked from commit 5dc6569a683da47f5323c252fce1bd4094a5d232)

# Conflicts:
#	CHANGELOG.md
2024-09-01 11:37:48 -04:00
renovate[bot] 292b551027 fix(deps): update aboutlib.version to v11.2.3 (#1151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit fba9bacdc19dee7cdf9e3d1cb4ee4a496fa7b514)
2024-09-01 11:37:23 -04:00
Dani e19c62a8ae Add option to skip downloading duplicate read chapters (#1125)
* Add query to get chapter count by manga and chapter number

* Add functions to get chapter count by manga and chapter number

* Only count read chapters

* Add interactor

* Savepoint

* Extract new chapter logic to separate function

* Update javadocs

* Add preference to toggle new functionality

* Add todo

* Add debug logcat

* Use string resource instead of hardcoding title

* Add temporary logcat for debugging

* Fix detekt issues

* Update javadocs

* Update download unread chapters preference

* Remove debug logcat calls

* Update javadocs

* Resolve issue where read chapters were still being downloaded during manual manga fetch

* Apply code review changes

* Apply code review changes

* Revert "Apply code review changes"

This reverts commit 1a2dce78acc66a7c529ce5b572bdaf94804b1a30.

* Revert "Apply code review changes"

This reverts commit ac2a77829313967ad39ce3cb0c0231083b9d640d.

* Group download chapter logic inside the interactor GetChaptersToDownload

* Update javadocs

* Apply code review

* Apply code review

* Apply code review

* Update CHANGELOG.md to include the new feature

* Run spotless

* Update domain/src/main/java/mihon/domain/chapter/interactor/FilterChaptersForDownload.kt

---------

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

# Conflicts:
#	CHANGELOG.md
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-09-01 11:37:04 -04:00
renovate[bot] 348cb335c4 fix(deps): update moko to v0.24.2 (#1148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 379d5878266ba0287bfcc4a06452c27d70f33ba1)
2024-09-01 10:53:49 -04:00
renovate[bot] c426d11d76 chore(deps): update kotlin monorepo to v2.0.20 (#1144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 034ec4cb120c0f36cad1303de1314c28c4ec4969)
2024-09-01 10:53:39 -04:00
renovate[bot] 1965c0825d fix(deps): update dependency com.google.firebase:firebase-analytics to v22.1.0 (#1146)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit ab2b734d49299dc3b30e0a7f0d5cbb268b0bff97)
2024-09-01 10:53:27 -04:00
renovate[bot] 0124763fcd fix(deps): update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.0 (#1142)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 08ae51ea8c5ceccc8c5c65120f387d7b19d18052)
2024-09-01 10:53:18 -04:00
Hosted Weblate b0d737592c Translations update from Hosted Weblate
Co-authored-by: Ahmed seif al-nasr <ahmdsyfalnsr2@gmail.com>
Co-authored-by: Anas KANJO <anas.kanjo2022@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Frosted <cinardogan110@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
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/es/
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/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sv/
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
(cherry picked from commit 4387ae5ff3131dd4aaaacd75fa6e82e7b322d474)

# Conflicts:
#	i18n/src/commonMain/moko-resources/tr/strings.xml
2024-09-01 10:53:09 -04:00
renovate[bot] e14596465b fix(deps): update dependency org.conscrypt:conscrypt-android to v2.5.3 (#1135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit b2f1719c50365279e157a3b9ee015fc6c13a9a92)
2024-09-01 10:51:14 -04:00
renovate[bot] 5e52dfcc66 chore(deps): update dependency gradle to v8.10 (#1122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 3f050a83dd0907e0ffb56a1e1833f9de5b10b329)
2024-09-01 10:51:07 -04:00
renovate[bot] a09643fc77 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.11.0 (#1121)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 6f4e3f776f98d7a47dfa33b2cdfe992fc211ec28)
2024-09-01 10:51:00 -04:00
NGB-Was-Taken 19bc08659b Move "Choose what to sync" out of "Sync now" (#1264) 2024-09-01 10:45:30 -04:00
NGB-Was-Taken 2cb8f8f872 Show local chapters as downloaded on merged entries. (#1262)
* Show local chapters as downloaded on merged entries.

* Disable downloadIndicator for local chapters on merged entries.
2024-09-01 10:45:20 -04:00
NGB-Was-Taken 23c7bb09d3 Update links. (#1261)
* Update links.

* [skip ci] Change a tachiyomi.org link.
2024-09-01 10:45:11 -04:00
NGB-Was-Taken bdb8553e28 Respect thumbnailQuality and tryUsingFirstVolumeCover preferences. (MD) (#1260) 2024-09-01 10:45:01 -04:00
Weblate (bot) fbac29e0cd Translations update from Hosted Weblate (#1259)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/es/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ja/
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/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
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: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Fadhil Muhammad <alpanumerik1@gmail.com>
Co-authored-by: HDYOU <308485965@qq.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: NGB-Was-Taken <myalternate34@gmail.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2024-09-01 10:44:49 -04:00
Jobobby04 b0aa2ffc42 Test to auto-add translations label 2024-08-23 16:39:17 -04:00
Jobobby04 45b5d9b8a4 Exclude weblate strings 2024-08-23 16:26:54 -04:00
Tran M. Cuong 91b98cdb82 Fix spotless error caused by #1253 being created before apply spotless (#1258) 2024-08-23 08:59:22 -04:00
Weblate (bot) 7f544f7163 Translations update from Hosted Weblate (#1253)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ja/
Translation: Mihon/TachiyomiSY

Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: jobobby04 <jobobby04@users.noreply.github.com>
2024-08-22 21:37:06 -04:00
Tran M. Cuong 3705880a77 Implement Mihon's spotless PR (#1257)
* Remove detekt (mihonapp/mihon#1130)

Annoying. More annoying in this project.

(cherry picked from commit 777ae2461e1eb277a3aa0c998ff69e4f100387a1)

* Add spotless (with ktlint) (mihonapp/mihon#1136)

(cherry picked from commit 5ae8095ef1ed2ae9f98486f9148e933c77a28692)

* Address spotless lint errors (mihonapp/mihon#1138)

* Add spotless (with ktlint)

* Run spotlessApply

* screaming case screaming case screaming case

* Update PagerViewerAdapter.kt

* Update ReaderTransitionView.kt

(cherry picked from commit d6252ab7703d52ecf9f43de3ee36fd63e665a31f)

* Generate locales_config.xml in build dir

(cherry picked from commit ac41bffdc97b4cfed923de6b9e8e01cccf3eb6eb)

* Address more spotless lint errors in SY

* some more missed

* more missed

* still missing, not sure while it won't report error when running locally

* one more

* more

* more

* correct comment

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-08-22 21:24:50 -04:00
Jobobby04 759fd4d4e3 Follow previous comment 2024-08-17 20:38:26 -04:00
FooIbar fc956fc791 Add comment about RecyclerView cache size (#1119)
Note for forks: Increasing cache size may cause OOM on API < 26, better
to make it API 26+ only.

(cherry picked from commit 1c47a6b9b35c622200c731cdbbc076f5263e8d06)
2024-08-17 20:33:30 -04:00
AntsyLich 9d7346157b Sync compose theme with MDC theme
(cherry picked from commit 9a34ace09c66274e6c2b3f9446058a0fa99d4bd0)

# Conflicts:
#	CHANGELOG.md
2024-08-17 20:31:20 -04:00
Weblate (bot) 0f0f4cf4a9 Translations update from Hosted Weblate (#1247)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ru/
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/fil/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ru/
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: Ahmed seif al-nasr <ahmdsyfalnsr2@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Howard Wu <HowardWu20@outlook.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: TawfikSharaf <tawfikahmed132.wa@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: Tim Schneeberger <thebone.main@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2024-08-17 20:27:46 -04:00
akir45 426ef65102 Add japanese Translation (#1248)
* Add plurals.xml

* Add string.xml
2024-08-17 20:27:36 -04:00
Shamicen 95c834581b Libarchive refactor (#1249)
* Refactor archive support with libarchive

* Refactor archive support with libarchive

* Revert string resource changs

* Only mark archive formats as supported

Comic book archives should not be compressed.

* Fixup

* Remove epub from archive format list

* Move to mihon package

* Format

* Cleanup

Co-authored-by: Shamicen <84282253+Shamicen@users.noreply.github.com>
(cherry picked from commit 239c38982c4fd55d4d86b37fd9c3c51c3b47d098)

* handle incorrect passwords

* lint

* fixed broken encryption detection + small tweaks

* Add safeguard to prevent ArchiveInputStream from being closed twice (#967)

* fix: Add safeguard to prevent ArchiveInputStream from being closed twice

* detekt

* lint: Make detekt happy

---------

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

(cherry picked from commit e620665dda9eb5cc39f09e6087ea4f60a3cbe150)

* fixed ArchiveReaderMode CACHE_TO_DISK

* Added some missing SY --> comments

---------

Co-authored-by: FooIbar <118464521+fooibar@users.noreply.github.com>
Co-authored-by: Ahmad Ansori Palembani <46041660+null2264@users.noreply.github.com>
2024-08-17 20:25:25 -04:00
NGB-Was-Taken 71f2daf8f3 Delete duplicate downloaded chapters when they are automatically marked as read (#1252) 2024-08-17 20:24:29 -04:00
Jobobby04 7ec14cd9f0 Fix preview 2024-08-11 20:42:40 -04:00
AntsyLich c23c9491fc Handle Android SDK 35 API collision
(cherry picked from commit fdb96179c6373eb0a8e7d6daea671a315d5ce5f0)
2024-08-11 19:41:15 -04:00
Jobobby04 29f3766c87 Update version code 2024-08-11 19:37:48 -04:00
Jobobby04 07c89890bc Fix SY migrations 2024-08-11 19:37:05 -04:00
Weblate (bot) 64a54f55b3 Translations update from Hosted Weblate (#1228)
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy-plurals/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/tachiyomisy/ar/
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: Ahmed seif al-nasr <ahmdsyfalnsr2@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Howard Wu <HowardWu20@outlook.com>
Co-authored-by: TawfikSharaf <tawfikahmed132.wa@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
2024-08-11 18:39:57 -04:00
Tim Schneeberger f7202e67cc feat(migration): add option to only show entries with new chapters (#1238) 2024-08-11 18:30:19 -04:00
renovate[bot] 155b03c176 fix(deps): update dependency com.elvishew:xlog to v1.11.1 (#1239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 18:29:49 -04:00
renovate[bot] 6b0482576b chore(deps): update gradle/actions action to v4 (#1243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 18:29:42 -04:00
AntsyLich c137bafd68 Fix UI freeze after migration
Fixes #938

(cherry picked from commit 3f1d28c3833e6b868152149ed02b3fb8c54eccef)
2024-08-11 18:09:02 -04:00
AntsyLich 49bdffdc28 Add a button to select all scanlators
Resolves #943
Closes #1109

(cherry picked from commit 84b2164787a795f3fd757c325cbfb6ef660ac3a3)
2024-08-11 18:08:43 -04:00
Catting f1b32d531a Add Copy Tracker URL on icon long press (#1101)
* Add Copy Tracker URL on icon long press

Signed-off-by: Catt0s <5874051+mm12@users.noreply.github.com>

* Add 'Copy To Clipboard' to tracker item menu

Signed-off-by: Catt0s <5874051+mm12@users.noreply.github.com>

* Add 'Copy link' to locales.

Signed-off-by: Catt0s <5874051+mm12@users.noreply.github.com>

* Implement code review suggestions
>
> Co-authored-by: AntsyLich  <59261191+AntsyLich@users.noreply.github.com>

Signed-off-by: Catt0s <5874051+mm12@users.noreply.github.com>

* Update app/src/main/java/eu/kanade/presentation/track/components/TrackLogoIcon.kt

---------

Signed-off-by: Catt0s <5874051+mm12@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 200d39e023af79b02276554a1bef1d7d53e3b903)
2024-08-11 18:02:09 -04:00
Weblate (bot) a5ec6c5cdd Translations update from Hosted Weblate (#939)
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ar/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ca/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/cs/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/de/
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/id/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ja/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ru/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/sv/
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/ar/
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/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/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/jv/
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/ko/
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/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/mr/
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/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/
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/sdh/
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/te/
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/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: Ahmed seif al-nasr <ahmdsyfalnsr2@gmail.com>
Co-authored-by: Ajeje Brazorf <lmelonimamo@yahoo.it>
Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: Animeboynz <40583749+Animeboynz@users.noreply.github.com>
Co-authored-by: David Katrinka <davidkatrinka1995@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: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: Iker Lerones <ikerlero@hotmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Matyáš Caras <matyas@caras.wtf>
Co-authored-by: Norsze <norbert.szabo7+github@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: abc0922001 <abc0922001@hotmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: vodkapmp <vodkapmp@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Артём Голуб <artemtirax2001@gmail.com>
(cherry picked from commit b1b15a93eec15a82e2e83650abf97c1b9f0c501c)
2024-08-11 18:02:02 -04:00
MajorTanya 9c56cdb1c1 Fix MAL search results not showing start dates (#1098)
The previous approach would always throw an Exception because
`SimpleDateFormat.format()` expects the input to be of type `Date` or
`Number`, not `String`.

(cherry picked from commit 97c81fadb426d71ac99c9443ab0e89f4089046ef)
2024-08-11 18:01:51 -04:00
MajorTanya 543de065a6 Change Kitsu to kitsu.app domain (#1106)
cf. https://github.com/hummingbird-me/kitsu-server/commit/244fdccca9754d8579c049e738832843001b33b1

(cherry picked from commit 9240eceedc5e2b065dd680819c4180c1ae09512b)

# Conflicts:
#	README.md
2024-08-11 18:01:43 -04:00
Jobobby04 33296e1faf Translations readme 2024-08-11 18:00:59 -04:00
Catting d1a90c0bb7 Contributing: ktLintFormat -> detekt (#1102)
* Contributing: ktLintFormat -> detekt

update Contributing info to use detekt instead of ktLintFormat

* Update CONTRIBUTING.md

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 14ae57d78b31f0bb3b58d19c1d8cfcebcc8e2253)
2024-08-11 18:00:34 -04:00
renovate[bot] 9fa61d33be fix(deps): update dependency com.android.tools.build:gradle to v8.5.2 (#1099)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 4828c54245dd6532c0e7a2b6c8cf5d8a703d3376)
2024-08-11 18:00:26 -04:00
renovate[bot] 0e9dcc7855 fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-alpha10 (#1092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit e8b7c3e24bb677d289554b972ef2496a976c79aa)
2024-08-11 18:00:18 -04:00
renovate[bot] 6738c6072d fix(deps): update dependency androidx.work:work-runtime to v2.9.1 (#1091)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit af77083660000e7378587dbc8d44e44bd8b196ec)
2024-08-11 18:00:11 -04:00
renovate[bot] 29033c539c fix(deps): update dependency androidx.annotation:annotation to v1.8.2 (#1090)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 36b9caeea8baf15f0d0ed37abc12638d44194c09)
2024-08-11 18:00:04 -04:00
renovate[bot] eaa3413c37 fix(deps): update paging.version to v3.3.2 (#1093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 8e40146f96704c3dc98bbb4f9f89d470ffa32f69)
2024-08-11 17:59:57 -04:00
AntsyLich 73d9d1d46d ExpandableMangaDescription: Adjust size transform anim spec
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 1c16fc79c2ac4c4be30308fed84ffb371dab5902)
2024-08-11 17:59:47 -04:00
Roshan Varughese 94f9aaf351 Add Backup and Restore of Extension Repos (#1057)
* Backup/Restore Extension Repos

* Refactor

* Moving to Under App Settings

* Sort by URL, Check existing by SHA and Error Logging

Untested. Currently in a lecture and can't test if the changes really work.

* Changes to logic

* Don't ask me what's happening here

* Renaming Variables

* Fixing restoreAmount & changes to logic

Co-Authored-By: AntsyLich <59261191+AntsyLich@users.noreply.github.com>

---------

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

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/models/Backup.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/BackupRestorer.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/RestoreOptions.kt
2024-08-11 17:59:35 -04:00
AntsyLich e21149cb37 Rename backup restore error log file
(cherry picked from commit 2858ef835fec8d7278b1d0cad1b5664104d1e4b0)
2024-08-11 17:39:41 -04:00
renovate[bot] 11aad16f59 chore(deps): update kotlin monorepo to v2.0.10 (#1085)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit edb8201f74e516c296b62e04a13802e1bd9e0b6b)
2024-08-11 17:39:30 -04:00
FooIbar 33a3918e86 Don't crash on ill-formed URLs (#1084)
(cherry picked from commit 854474f85ffc41eccdc2b3a6cf105fa2805ebc3c)
2024-08-11 17:39:21 -04:00
Tran M. Cuong d655b8ecdf fix: drawScrollbar crash on list with 0 item but only sticky header (#1083)
(cherry picked from commit 04db46fe75c2406fe9750e97da65774a6b268f27)
2024-08-11 17:39:12 -04:00
FooIbar 70a8bef7a5 Match extra layout space with scroll distance (#1076)
And increase recycler item view cache size.

(cherry picked from commit a3dfd2efe6ace7a2a4d79bd09fb1a729989f1094)
2024-08-11 17:38:58 -04:00
Vetle Ledaal 999a8613cf Improve error message if restoring from JSON file (#1056)
* Improve error message if restoring from JSON file

* Replace Exception with IOException

* Use more generic error message if protobuf fails

* fix lint

(cherry picked from commit de8ef6dad7c89afb7041ccb489d68539a4849cb5)
2024-08-11 17:38:48 -04:00
AntsyLich 5721a02bca Bump default user agent string
(cherry picked from commit 8160b47ff5fbbd9b32caeb462b5be881fabd3449)
2024-08-11 17:38:39 -04:00
AntsyLich e303b88b90 Cleanup backup/restore related code
(cherry picked from commit c201b341a716b90d378dcda4bd9b8ac4a343d4fc)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
2024-08-11 17:38:13 -04:00
AntsyLich a62dd5821a Fix library is backed up when disabled and make categories backup/restore independent
(cherry picked from commit 56fb4f62a152e87a71892aa68c78cac51a2c8596)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupOptions.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/RestoreOptions.kt
2024-08-11 17:34:04 -04:00
Roshan Varughese a0786d9b09 Adds Option to Copy Panel to Clipboard (#1003)
* Add Copy to Clipboard

* Removing Unused Import

* Reusing onShare function

* Commit Suggestion

* Early Return on null

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

---------

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

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
2024-08-11 17:25:33 -04:00
renovate[bot] 04580ce357 fix(deps): update paging.version to v3.3.1 (#1046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 41e2dc7ae80250d9166fc637c1170667afdb0a9e)
2024-08-11 15:39:47 -04:00
Roshan Varughese b759f2f02a Format Category String on Subtitle Display (#1030)
* Fixes #1029

* Max Line Length Fix

* Update SettingsLibraryScreen.kt

No idea how this works.

Co-authored-by: Foolbar <118464521+Foolbar@users.noreply.github.com>

---------

Co-authored-by: Foolbar <118464521+Foolbar@users.noreply.github.com>
(cherry picked from commit 88efde8796b0e1cc8fba6cd987bdc487bd97f248)
2024-08-11 15:39:38 -04:00
renovate[bot] 8ae8068ecd fix(deps): update lifecycle.version to v2.8.4 (#1045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit b7849d714698900a25188bdbfd77bf24936f2dd7)
2024-08-11 15:39:31 -04:00
renovate[bot] eecd9367d4 fix(deps): update dependency androidx.annotation:annotation to v1.8.1 (#1043)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 602b58f364b95b83a3148be34cd4c90d95d7d405)
2024-08-11 15:39:24 -04:00
renovate[bot] 55dee69838 fix(deps): update dependency androidx.activity:activity-compose to v1.9.1 (#1042)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit e48dbdbf2356c0e6e148313dc6610e865cd8e995)
2024-08-11 15:39:16 -04:00
FooIbar a730ca5444 Remove obsolete workaround (#1021)
(cherry picked from commit 51b68cd25ff4bf556de88cb31525c55dd7eb7027)
2024-08-11 15:39:06 -04:00
renovate[bot] cebd8fe0a8 fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-alpha09 (#1039)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit ca784cbe3267e94e652e4c54f91b7107cc53c307)
2024-08-11 15:38:54 -04:00
renovate[bot] 55a979c5f7 fix(deps): update dependency io.mockk:mockk to v1.13.12 (#1016)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 4f61b2e4e89bc257cf5e629823904805907bf75c)
2024-08-11 15:38:37 -04:00
renovate[bot] 728f3fc349 chore(deps): update dependency gradle to v8.9 (#1007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit f63e95091013320b27bfc3c7c975c4bdd4a983c5)
2024-08-11 15:38:17 -04:00
renovate[bot] a9a3ed1d16 fix(deps): update dependency org.jsoup:jsoup to v1.18.1 (#999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit f3f2bd41c3974878bcf0e3a62d99ee89bf92fb41)
2024-08-11 15:38:08 -04:00
renovate[bot] 36f13a7c6a fix(deps): update dependency com.android.tools.build:gradle to v8.5.1 (#1010)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 7a2ca4bf4d41764705637d61c6d86249f8815b7b)
2024-08-11 15:37:37 -04:00
renovate[bot] 37a2ccc678 Bump coil version and some cleanup
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit e65634cb427eafe9e3bd192f9e8bf71f2243ce6c)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
2024-08-11 15:37:16 -04:00
FooIbar bb39088dd7 Fix some issues when reading/saving images (#993)
* Fix unsupported mime type error when saving images

Avoid using platform mime type map to get extensions as it may not have
all mime types we support.

* Fix jxl images downloading/reading

(cherry picked from commit daa47e049327c4d8b1fe4724ed1b84897d81fcf2)

# Conflicts:
#	core/common/src/main/kotlin/tachiyomi/core/common/util/system/ImageUtil.kt
2024-08-11 15:34:57 -04:00
AntsyLich c5546e1095 Fix login prompts despite being logged in to trackers in Manga screen
(cherry picked from commit cbcd8bd6682023f728568f2b44da26124618aed7)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-08-11 15:32:28 -04:00
AntsyLich 2d12c670db Observe tracker login state instead of fetching once (#987)
* Observe tracker login state instead of fetching once

* Review changes

(cherry picked from commit 2092c81bad59fd745a8514af320e534ecf40a5da)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/library/LibrarySettingsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
2024-08-11 15:15:44 -04:00
AntsyLich 3db4bccebc Make global search "Has result" sticky
Closes #133

(cherry picked from commit 5a61ca5535fe0d9e8e7bcb9e665ba2f9cb0cf649)

# Conflicts:
#	app/src/main/java/eu/kanade/domain/source/service/SourcePreferences.kt
2024-08-11 14:49:11 -04:00
Roshan Varughese 2f23ad6bfd Smart Update Dialog Tweak (#977)
* Smart Update Dialog Fix

* Build Fail Change 1

* Commit Suggested Change

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

* Build Fail Change 2

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit ddba71df37359e6abbbcc96b18685435961710dc)
2024-08-11 14:48:33 -04:00
CrepeTF de1898a2c9 Correct tako variable colours (#976)
(cherry picked from commit 75b5d966018aa917f57adf37370088a51e4914b2)
2024-08-11 14:48:18 -04:00
renovate[bot] eb135ec22d fix(deps): update lifecycle.version to v2.8.3 (#972)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 77db8873f6753cc9db8f67b39d53685563380cc6)
2024-08-11 14:48:10 -04:00
WerctFourth bf6c646dc7 Update image-decoder revision (#971)
(cherry picked from commit bff6183cf3ef400d8ddcdccf7180e4139816cc09)
2024-08-11 14:48:01 -04:00
renovate[bot] 9ce16d5e1c fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-alpha07 (#960)
* fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-alpha07

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit c0f9de88e70ef1db97c521993462ae27550b5790)
2024-08-11 14:47:41 -04:00
renovate[bot] 619ff726c8 fix(deps): update aboutlib.version to v11.2.2 (#965)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 80cdebcdf467ed00e530651aeed2b36cc63b8356)
2024-08-11 14:47:22 -04:00
renovate[bot] 730ceaaf49 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.10.3 (#962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 9e2f97eeb8a0f1d1b353dc3e77fb64d69b568674)
2024-08-11 14:47:13 -04:00
CrepeTF 07b701cb3c Theme fixes (#963)
* Fix theme issue with download progress indicator

* Fix theme issue with download progress indicator + better contrast

(cherry picked from commit e132cc405f23e18dd8d73626730821eae9051149)
2024-08-11 14:47:02 -04:00
Caio Oliveira b64c6b78ea buildSrc: Fix strange warning in ci build (#952)
* buildSrc: Fix strange warning

´Project accessors enabled, but root project name not explicitly set for 'buildSrc'. Checking out the project in different folders will impact the generated code and implicitly the buildscript classpath, breaking caching.´

* Update settings.gradle.kts

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 2674b849746f20c051dab3fd6edfad1594e41b42)
2024-08-11 14:46:50 -04:00
renovate[bot] 521bce5c08 fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.1 (#958)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit f34702d4fcc10f24953b21e883fb454778bbae77)
2024-08-11 14:46:36 -04:00
renovate[bot] a719ed8c9e fix(deps): update dependency androidx.test.ext:junit-ktx to v1.2.1 (#959)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 7823966ddf2289fee743feaa58b906ab9179a4ed)
2024-08-11 14:46:22 -04:00
renovate[bot] f6fc2d7e2f fix(deps): update dependency net.zetetic:sqlcipher-android to v4.6.0 (#1221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-27 09:55:53 -04:00
renovate[bot] 48d43c4f07 chore(deps): update actions/upload-artifact action to v4 (#1222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-27 09:55:42 -04:00
renovate[bot] f4fa86b2dc chore(deps): update softprops/action-gh-release action to v2 (#1223)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-27 09:55:29 -04:00
renovate[bot] 37db0dc1f6 fix(deps): update dependency com.google.oauth-client:google-oauth-client to v1.36.0 (#1220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-26 20:55:33 -04:00
renovate[bot] 1ada03b07a chore(deps): update actions/setup-java action to v4 (#1217)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-26 20:54:25 -04:00
renovate[bot] f4c1e7c2d5 chore(deps): update damianreeves/write-file-action action to v1.3 (#1216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-26 20:54:11 -04:00
Jobobby04 6c5282c598 Another 2024-06-26 20:39:26 -04:00
Jobobby04 7899474a36 Fix build errors 2024-06-26 20:38:12 -04:00
Jobobby04 225b419bba Update wrapper validation 2024-06-26 20:23:59 -04:00
Jobobby04 fa64103a1c Actual baseline 2024-06-26 20:20:12 -04:00
Jobobby04 57e0e99f06 Preview branch makes preview 2024-06-26 20:10:45 -04:00
Jobobby04 efde7afa8e Update baseline 2024-06-26 20:09:09 -04:00
Jobobby04 f929a4bc26 Move some libs to sylibs 2024-06-26 20:03:24 -04:00
renovate[bot] d35141c1cc chore: Configure Renovate (#1215)
* Add renovate.json

* Only update specific files

* Add a glob

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jobobby04 <jobobby04@users.noreply.github.com>
2024-06-26 19:57:10 -04:00
renovate[bot] 6988966019 fix(deps): update serialization.version to v1.7.1 (#951)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit d8fe7d32ca6bacbb74e9e80173625a993621e4b2)
2024-06-26 19:32:52 -04:00
Maddie Witman f6d8ebbb0a Added configuration options to e-ink page flashes (#625)
* Recommit for e-ink pref changes

* Fixed state holder for flash interval

* Detekt

* Refactor suggested by Antsy

* inverted currentDisplayRefresh check for early exit

(cherry picked from commit 2f86f25d5b24c2054a604802dc65b8bc3a99c7c0)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt
#	app/src/main/java/eu/kanade/presentation/reader/settings/GeneralSettingsPage.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt
2024-06-26 19:32:42 -04:00
renovate[bot] ae45df9fcf fix(deps): update dependency androidx.test.ext:junit-ktx to v1.2.0 (#948)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 36e40c099772d2cb53d4ec87b2b00f97fe455c98)
2024-06-26 19:31:12 -04:00
renovate[bot] f332344681 fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.0 (#947)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 40754659a9e146626add56c494a6dc9873691f14)
2024-06-26 19:31:03 -04:00
AntsyLich c6abb340ca Cleanup in CommonMangaItem.kt
Closes #19

Co-authored-by: Roshan Varughese <40583749+Animeboynz@users.noreply.github.com>
(cherry picked from commit e17f70f7226ea031fc1f962c9dfea3e404ba53ad)
2024-06-26 19:30:50 -04:00
Tran M. Cuong 99dbb16a7a Fix Migrator test and also add the test to build script (#896)
* Fix MigratorTest after update to Kotlin 2.0.0

* add main module's test to build script

(cherry picked from commit e57638a49c759d36d25b92f26633df5bdfb0d2b3)

# Conflicts:
#	.github/workflows/build_pull_request.yml
#	.github/workflows/build_push.yml
2024-06-26 19:30:39 -04:00
FooIbar f62e8933d7 Fix unexpected skips in strong skipping mode (#940)
(cherry picked from commit 0ce1cf22cdbb7d82df3db1a901253b4973ab027f)

# Conflicts:
#	source-api/build.gradle.kts
2024-06-26 19:30:00 -04:00
renovate[bot] ee3c2fd79c fix(deps): update dependency io.github.fornewid:material-motion-compose-core to v2.0.1 (#945)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit f6ec53cdde32a17bc394e55b697a3b59bfd76e58)
2024-06-26 19:28:53 -04:00
renovate[bot] 6b08b873a8 fix(deps): update dependency com.google.firebase:firebase-analytics to v22.0.2 (#936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit b37357f9097730edb1d72f1297461e580286856c)
2024-06-26 19:28:43 -04:00
renovate[bot] a3f2f49ab8 fix(deps): update moko to v0.24.1 (#933)
* fix(deps): update moko to v0.24.1

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit f58a05e91828a69c01d49d629e5bfa9ec7ae3ffc)
2024-06-26 19:28:27 -04:00
Weblate (bot) 524f5cc6ab Translations update from Hosted Weblate (#904)
* Translated using Weblate (Malayalam)

Currently translated at 16.9% (136 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/

* Translated using Weblate (Swedish)

Currently translated at 99.1% (797 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sv/

* Translated using Weblate (Arabic)

Currently translated at 99.5% (800 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ar/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sv/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (18 of 18 strings)

Translation: Mihon/Mihon Plurals
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/sv/

---------

Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: Norsze <norbert.szabo7+github@gmail.com>
Co-authored-by: Duh051 <duhduh272@gmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
(cherry picked from commit cf02119da55c431d0fb4c42ecfec3681d466ae43)
2024-06-26 19:16:39 -04:00
FooIbar a35e084b9e Fix R8 version configuration not working (#916)
This reverts commit f3226fb278cab87422255e04e647c50095b61529.

(cherry picked from commit 4182ae89a036525c5575961a68371df249ce384f)

# Conflicts:
#	build.gradle.kts
2024-06-26 19:16:27 -04:00
FooIbar 78f7fba67b Update R8 to fix NoSuchMethodError crash (#914)
(cherry picked from commit f3226fb278cab87422255e04e647c50095b61529)

# Conflicts:
#	build.gradle.kts
2024-06-26 19:15:56 -04:00
renovate[bot] 69d1db3018 fix(deps): update dependency com.android.tools.build:gradle to v8.5.0 (#901)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 2e78bceb30908aca8e585f91942849a6e4e7cb15)
2024-06-26 19:15:21 -04:00
Weblate (bot) d1b317e5c8 Translations update from Hosted Weblate (#878)
* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/zh_Hant/

* Translated using Weblate (Croatian)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/

* Translated using Weblate (Malayalam)

Currently translated at 15.5% (125 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/

* Translated using Weblate (Malayalam)

Currently translated at 15.5% (125 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/

* Translated using Weblate (Malayalam)

Currently translated at 94.4% (17 of 18 strings)

Translation: Mihon/Mihon Plurals
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ml/

---------

Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: Animeboynz <roshanvarughese@hotmail.com>
(cherry picked from commit aa1714b2acf0e5b16558ea703220f60d4ecd23e9)
2024-06-26 19:15:06 -04:00
AntsyLich fff40e031f Fix issue with creating and restoring backup
Fixes #881

(cherry picked from commit f696f209c6b3efb3148e1d587af9e42c71d8dc6f)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/create/BackupCreator.kt
2024-06-26 19:14:54 -04:00
renovate[bot] 5be2ec51ba fix(deps): update dependency androidx.glance:glance-appwidget to v1.1.0 (#890)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit af57e124f2113f78028771f1579a356884d7ead7)
2024-06-26 19:13:53 -04:00
renovate[bot] 1c2a7af13e fix(deps): update lifecycle.version to v2.8.2 (#889)
fix(deps): update dependency androidx.lifecycle:lifecycle-runtime-ktx to v2.8.2

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 8e8ee69bbacb2260d0ae52808c02684e567119b9)
2024-06-26 19:13:44 -04:00
renovate[bot] 182158acb0 fix(deps): update dependency com.android.tools.build:gradle to v8.4.2 (#883)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit e9d69a83febccf8840dad03597e3ac2a6aa3f972)
2024-06-26 19:13:34 -04:00
AntsyLich 21f92bfb3a Fix chapter number parsing when number is after unwanted tag
Fixes #554

Co-authored-by: Naputt1 <94742489+Naputt1@users.noreply.github.com>
(cherry picked from commit 6a80305d6c572da6c08c0c69f5c25ff26ecf7383)
2024-06-26 19:13:24 -04:00
AntsyLich a5522ef732 Check category order before restoring from backup
Closes #632

Co-authored-by: Cologler <10906962+Cologler@users.noreply.github.com>
(cherry picked from commit 119bcbf8ed2415664922ea77fadf0da1165d1732)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/restore/restorers/CategoriesRestorer.kt
2024-06-26 19:13:14 -04:00
Weblate (bot) 239793f7fd Translations update from Hosted Weblate (#611)
* Translated using Weblate (Malayalam)

Currently translated at 12.9% (104 of 803 strings)

Translated using Weblate (Malayalam)

Currently translated at 94.4% (17 of 18 strings)

Translated using Weblate (Malayalam)

Currently translated at 11.8% (95 of 803 strings)

Added translation using Weblate (Malayalam)

Added translation using Weblate (Malayalam)

Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ml/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ml/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

* Translated using Weblate (Italian)

Currently translated at 99.6% (800 of 803 strings)

Co-authored-by: Federico Pierantoni <federico.pieranton@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/
Translation: Mihon/Mihon

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hu/
Translation: Mihon/Mihon

* Translated using Weblate (Javanese)

Currently translated at 38.7% (311 of 803 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (803 of 803 strings)

Translated using Weblate (Indonesian)

Currently translated at 98.7% (793 of 803 strings)

Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
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/
Translation: Mihon/Mihon

* Translated using Weblate (Greek)

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/el/
Translation: Mihon/Mihon

* Translated using Weblate (Serbian)

Currently translated at 99.2% (797 of 803 strings)

Co-authored-by: Rikishaaa <jebote90@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/sr/
Translation: Mihon/Mihon

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: Blackiezin <mcperenan134@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt_BR/
Translation: Mihon/Mihon

* Translated using Weblate (French)

Currently translated at 100.0% (18 of 18 strings)

Translated using Weblate (French)

Currently translated at 99.0% (795 of 803 strings)

Co-authored-by: LaQuiche426 <loic.dossantos42630@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/fr/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

* Translated using Weblate (Portuguese)

Currently translated at 99.8% (802 of 803 strings)

Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pt/
Translation: Mihon/Mihon

* Translated using Weblate (Vietnamese)

Currently translated at 100.0% (18 of 18 strings)

Translated using Weblate (Vietnamese)

Currently translated at 96.8% (778 of 803 strings)

Co-authored-by: Karuto <nguyenthaison609@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/vi/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

* Translated using Weblate (Croatian)

Currently translated at 99.5% (799 of 803 strings)

Co-authored-by: Milo Ivir <mail@milotype.de>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/
Translation: Mihon/Mihon

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: Eji-san <ejierubani@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/id/
Translation: Mihon/Mihon

* Translated using Weblate (Galician)

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: kevans <albapazpi@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/gl/
Translation: Mihon/Mihon

* Translated using Weblate (Ukrainian)

Currently translated at 99.8% (802 of 803 strings)

Co-authored-by: Kodekiro Kodekihara <lolbitoklol@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/uk/
Translation: Mihon/Mihon

* Translated using Weblate (Malay)

Currently translated at 98.6% (792 of 803 strings)

Co-authored-by: Farith <mail2@farithadnan.net>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ms/
Translation: Mihon/Mihon

* Translated using Weblate (Nepali)

Currently translated at 100.0% (18 of 18 strings)

Translated using Weblate (Nepali)

Currently translated at 100.0% (803 of 803 strings)

Co-authored-by: FateXBlood <fatexblood@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ne/
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/
Translation: Mihon/Mihon
Translation: Mihon/Mihon Plurals

* Translated using Weblate (Vietnamese)

Currently translated at 100.0% (803 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/vi/

* Translated using Weblate (Croatian)

Currently translated at 100.0% (803 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/hr/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (18 of 18 strings)

Translation: Mihon/Mihon Plurals
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/es/

* Translated using Weblate (Romanian)

Currently translated at 99.6% (800 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ro/

* Translated using Weblate (Romanian)

Currently translated at 100.0% (18 of 18 strings)

Translation: Mihon/Mihon Plurals
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ro/

* Translated using Weblate (Italian)

Currently translated at 100.0% (803 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/it/

* Translated using Weblate (Polish)

Currently translated at 99.5% (799 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/pl/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (803 of 803 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/

* Translated using Weblate (German)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/de/

* Translated using Weblate (Russian)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ru/

* Translated using Weblate (French)

Currently translated at 99.5% (800 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fr/

* Translated using Weblate (Filipino)

Currently translated at 99.8% (803 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/fil/

* Translated using Weblate (Nepali)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ne/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/ca/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (804 of 804 strings)

Translation: Mihon/Mihon
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon/es/

* Translated using Weblate (Catalan)

Currently translated at 100.0% (18 of 18 strings)

Translation: Mihon/Mihon Plurals
Translate-URL: https://hosted.weblate.org/projects/mihon/mihon-plurals/ca/

---------

Co-authored-by: Akhil Raj <akhilakae07@gmail.com>
Co-authored-by: Federico Pierantoni <federico.pieranton@gmail.com>
Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Rikishaaa <jebote90@gmail.com>
Co-authored-by: Blackiezin <mcperenan134@gmail.com>
Co-authored-by: LaQuiche426 <loic.dossantos42630@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Karuto <nguyenthaison609@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: kevans <albapazpi@gmail.com>
Co-authored-by: Kodekiro Kodekihara <lolbitoklol@gmail.com>
Co-authored-by: Farith <mail2@farithadnan.net>
Co-authored-by: FateXBlood <fatexblood@gmail.com>
Co-authored-by: Nguyễn Trung Đức <vaicato16@gmail.com>
Co-authored-by: Chrono Lux <amber_c001@protonmail.com>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Giorgio Sanna <sannagiorgio1997@gmail.com>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: Tim Schneeberger <thebone.main@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: Naga <yz2000.pro@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Eduard Ereza Martínez <eduard@ereza.cat>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
(cherry picked from commit 87fe64468ca08466af5b9fcc7f9e17e9a23021e6)

# Conflicts:
#	i18n/src/commonMain/resources/MR/gl/strings.xml
#	i18n/src/commonMain/resources/MR/ro/strings.xml
2024-06-26 19:12:15 -04:00
renovate[bot] 4e9cfe4602 fix(deps): update dependency io.github.fornewid:material-motion-compose-core to v2 (#873)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit bdce3c39f1475dc77dad300a0bf3702e85d32916)
2024-06-26 19:11:01 -04:00
AntsyLich f548c85e7a MangaChapterListItem: Don't use alpha modifier
Possibly fixes #822

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
(cherry picked from commit 15d999229fcce865001d5fa77d0163e6e80e38db)
2024-06-26 19:10:39 -04:00
renovate[bot] 576349c446 fix(deps): update okhttp monorepo to v5.0.0-alpha.14 (#688)
* fix(deps): update okhttp monorepo to v5.0.0-alpha.14

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 1edd55c981aa72faf49c06173f33bf0c2f99fe60)
2024-06-26 19:10:28 -04:00
renovate[bot] 9b00e0458b fix(deps): update serialization.version to v1.7.0 (#870)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 71b558cb34c4e2da435877f391e57b6d49c4ef4f)
2024-06-26 19:06:15 -04:00
renovate[bot] 6a1ff99441 chore(deps): update kotlin and compose compiler to v2 (major) (#819)
* chore(deps): update kotlin and compose compiler to v2

* Update .gitignore

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 46003ec25139319079abc9fde89b3afd344a1a11)

# Conflicts:
#	.github/renovate.json5
#	gradle/compose.versions.toml
#	source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt
2024-06-26 19:06:10 -04:00
renovate[bot] 0121fe9397 fix(deps): update dependency io.kotest:kotest-assertions-core to v5.9.1 (#869)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 1f7574bd4fc0471b7f974cffdf166c2551b2749b)
2024-06-26 17:41:20 -04:00
Cuong M. Tran 5c47c7a409 Fix MigratorTest after update to io.mockk v1.13.11 (#814)
* Fix MigratorTest after update to io.mockk v1.13.11

Causing error: io.mockk.MockKException: was not can only be called on a mocked object

* remove import

(cherry picked from commit da62c7a21a81f513988fa64df6253376f85228ef)
2024-06-26 17:40:33 -04:00
renovate[bot] 8bb4f33f2e fix(deps): update dependency io.github.fornewid:material-motion-compose-core to v1.2.1 (#858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit 0870cffba121c0cc7db9c79f83f770a43d9c32e7)
2024-06-26 17:40:17 -04:00
Sven 5f5fd51668 fix: storage permission request for non-conforming devices (#726)
* fix: storage permission request for non-conforming devices

* fix: catch more specific exception

* chore: add toast message to indicate missing persistent permissions

* chore: correct newly introduced translaction string

* Change error toast message

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 8632ba85ee1ed080d7baa70050d460807c8edfcf)
2024-06-26 17:40:03 -04:00
Jobobby04 c7bbad93b2 Fix some MDLang issues 2024-06-26 17:38:53 -04:00
Jobobby04 1a4a2506f4 Codestral(ChatGPT) cleanup of some double pages code 2024-06-26 17:38:51 -04:00
gelionexists 7b7a594ddb Update LewdMangaChecker.kt (#1204)
- Added the `mature` tag
- Added `doujins` (doujins.com) and `luscious` (luscious.net) as filter keywords
2024-06-26 17:31:41 -04:00
KaiserBh c2eece0fff chore: improve google drive sync. (#1200)
improve google drive sync, removes the lock, change to protobuf, and potentially fix deviceId not being unique, since it wasn't appState...
2024-06-26 17:31:12 -04:00
ɴᴇᴋᴏ d29a4ff381 Update TW strings.xml (#1202)
Add Google sync strings
2024-06-26 17:30:06 -04:00
699 changed files with 12151 additions and 7765 deletions
+7
View File
@@ -0,0 +1,7 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"labels": ["Dependencies"],
"includePaths": [".github/workflows/*", "gradle/sy.versions.toml"],
"semanticCommits": "disabled"
}
+5 -5
View File
@@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/actions/wrapper-validation@v4
build:
name: Build app
@@ -27,19 +27,19 @@ jobs:
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: adopt
- name: Set up gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
- name: Build app
run: ./gradlew detekt assembleDevDebug
run: ./gradlew spotlessCheck assembleDevDebug
- name: Upload APK
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: TachiyomiSY-${{ github.sha }}.apk
path: app/build/outputs/apk/dev/debug/app-dev-debug.apk
+7 -7
View File
@@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2
uses: gradle/actions/wrapper-validation@v4
- name: Setup Android SDK
run: |
@@ -31,18 +31,18 @@ jobs:
distribution: adopt
- name: Set up gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
# SY <--
- name: Write google-services.json
uses: DamianReeves/write-file-action@v1.2
uses: DamianReeves/write-file-action@v1.3
with:
path: app/google-services.json
contents: ${{ secrets.GOOGLE_SERVICES_TEXT }}
write-mode: overwrite
- name: Write client_secrets.json
uses: DamianReeves/write-file-action@v1.2
uses: DamianReeves/write-file-action@v1.3
with:
path: app/src/main/assets/client_secrets.json
contents: ${{ secrets.CLIENT_SECRETS_TEXT }}
@@ -50,7 +50,7 @@ jobs:
# SY -->
- name: Build app and run unit tests
run: ./gradlew detekt assembleStandardRelease testStandardReleaseUnitTest --stacktrace
run: ./gradlew spotlessCheck assembleStandardRelease testStandardReleaseUnitTest --stacktrace
- name: Sign APK
uses: r0adkll/sign-android-release@v1
@@ -86,7 +86,7 @@ jobs:
echo "APK_X86_64_SHA=$sha" >> $GITHUB_ENV
- name: Create release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.run_number }}
name: TachiyomiSY
+2 -3
View File
@@ -3,12 +3,11 @@ name: Remote Dispatch Action Initiator
on:
push:
branches:
- 'master'
- 'preview'
jobs:
trigger_preview_build:
name: Trigger preview build
if: ${{ github.ref == 'refs/heads/master' }}
runs-on: ubuntu-latest
steps:
@@ -16,7 +15,7 @@ jobs:
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/actions/wrapper-validation@v4
- name: Create Tag
run: |
+26
View File
@@ -0,0 +1,26 @@
name: Label PRs
on:
pull_request:
types: [opened]
jobs:
label_pr:
runs-on: ubuntu-latest
steps:
- name: Check PR and Add Label
uses: actions/github-script@v7
with:
script: |
const prAuthor = context.payload.pull_request.user.login;
if (prAuthor === 'weblate') {
const labels = ['Translations'];
await github.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: labels
});
}
+16 -20
View File
@@ -1,25 +1,21 @@
# Build files
.gradle
/local.properties
/.idea/workspace.xml
.DS_Store
.kotlin
build
# IDE files
*.iml
.idea/*
!.idea/icon.png
*iml
*.iml
/mainframer
/.mainframer
# Built files
*/build
/build
*.apk
app/**/output.json
# Unnecessary file
*.swp
TODO.md
CHANGELOG.md
/captures
build.sh
# Configuration files
local.properties
# macOS specific files
.DS_Store
# SY ignores
google-services.json
/app/src/main/assets/client_secrets.json
*.apk
+7 -14
View File
@@ -1,4 +1,4 @@
Looking to report an issue/bug or make a feature request? Please refer to the [README file](https://github.com/tachiyomiorg/tachiyomi#issues-feature-requests-and-contributing).
Looking to report an issue/bug or make a feature request? Please refer to the [README file](/README.md#issues-feature-requests-and-contributing).
---
@@ -9,7 +9,7 @@ Thanks for your interest in contributing to Tachiyomi!
Pull requests are welcome!
If you're interested in taking on [an open issue](https://github.com/tachiyomiorg/tachiyomi/issues), please comment on it so others are aware.
If you're interested in taking on [an open issue](https://github.com/jobobby04/TachiyomiSY/issues), please comment on it so others are aware.
You do not need to ask for permission nor an assignment.
## Prerequisites
@@ -24,34 +24,27 @@ Before you start, please note that the ability to use following technologies is
- [Android Studio](https://developer.android.com/studio)
- Emulator or phone with developer options enabled to test changes.
## Linting
To auto-fix some linting errors, run the `ktlintFormat` Gradle task.
## Getting help
- Join [the Discord server](https://discord.gg/tachiyomi) for online help and to ask questions while developing.
- Join [the Discord server](https://discord.gg/mihon) for online help and to ask questions while developing.
# Translations
Translations are done externally via Weblate. See [our website](https://tachiyomi.org/docs/contribute#translation) for more details.
Translations are done externally via Weblate. See [our website](https://mihon.app/docs/contribute#translation) for more details.
# Forks
Forks are allowed so long as they abide by [the project's LICENSE](https://github.com/tachiyomiorg/tachiyomi/blob/master/LICENSE).
Forks are allowed so long as they abide by [the project's LICENSE](/LICENSE).
When creating a fork, remember to:
- To avoid confusion with the main app:
- Change the app name
- Change the app icon
- Change or disable the [app update checker](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt)
- Change or disable the [app update checker](/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt)
- To avoid installation conflicts:
- Change the `applicationId` in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts)
- To avoid having your data polluting the main app's analytics and crash report services:
- If you want to use Firebase analytics, replace [`google-services.json`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/standard/google-services.json) with your own
- If you want to use ACRA crash reporting, replace the `ACRA_URI` endpoint in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts) with your own
- Change the `applicationId` in [`build.gradle.kts`](/app/build.gradle.kts)
### Supporting Cloud Sync - Google Drive Implementation
+11 -2
View File
@@ -14,7 +14,7 @@ Features of Mihon(original) include:
* Online reading from a variety of sources
* Local reading of downloaded content
* A configurable reader with multiple viewers, reading directions and other settings.
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.io/), [MangaUpdates](https://mangaupdates.com), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.app/), [MangaUpdates](https://mangaupdates.com), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
* Categories to organize your library
* Light and dark themes
* Schedule updating your library for new chapters
@@ -67,13 +67,22 @@ Get the app from our [releases page](https://github.com/jobobby04/tachiyomisy/re
If you want to try new features before they get to the stable release, you can download the preview version [here](https://github.com/jobobby04/tachiyomisypreview/releases).
## Translation
Feel free to translate the project on [Weblate](https://hosted.weblate.org/projects/mihon/tachiyomisy/)
<details><summary>Translation Progress</summary>
<a href="https://hosted.weblate.org/engage/mihon/">
<img src="https://hosted.weblate.org/widgets/mihon/-/tachiyomisy/multi-auto.svg" alt="Translation status" />
</a>
</details>
## Issues, Feature Requests and Contributing
Please make sure to read the full guidelines. Your issue may be closed without warning if you do not.
<details><summary>Issues</summary>
1. **Before reporting a new issue, take a look at the [FAQ](https://tachiyomi.org/docs/faq/general), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
1. **Before reporting a new issue, take a look at the [FAQ](https://mihon.app/docs/faq/general), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
2. If you are unsure, ask here: [![Discord](https://img.shields.io/discord/1195734228319617024.svg)](https://discord.gg/mihon)
</details>
-4
View File
@@ -1,4 +0,0 @@
/build
*iml
*.iml
google-services.json
+32 -24
View File
@@ -6,22 +6,23 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("mihon.android.application")
id("mihon.android.application.compose")
id("com.mikepenz.aboutlibraries.plugin")
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
// id("com.github.zellius.shortcut-helper")
alias(libs.plugins.aboutLibraries)
id("com.github.ben-manes.versions")
}
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
apply<com.google.gms.googleservices.GoogleServicesPlugin>()
// Firebase Crashlytics
apply(plugin = "com.google.firebase.crashlytics")
pluginManager.apply {
apply(libs.plugins.google.services.get().pluginId)
apply(libs.plugins.firebase.crashlytics.get().pluginId)
}
}
// shortcutHelper.setFilePath("./shortcuts.xml")
val SUPPORTED_ABIS = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
val supportedAbis = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
android {
namespace = "eu.kanade.tachiyomi"
@@ -29,7 +30,7 @@ android {
defaultConfig {
applicationId = "eu.kanade.tachiyomi.sy"
versionCode = 68
versionCode = 69
versionName = "1.10.5"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
@@ -38,7 +39,7 @@ android {
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
ndk {
abiFilters += SUPPORTED_ABIS
abiFilters += supportedAbis
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -47,7 +48,7 @@ android {
abi {
isEnable = true
reset()
include(*SUPPORTED_ABIS.toTypedArray())
include(*supportedAbis.toTypedArray())
isUniversalApk = true
}
}
@@ -106,13 +107,16 @@ android {
packaging {
resources.excludes.addAll(
listOf(
"kotlin-tooling-metadata.json",
"META-INF/DEPENDENCIES",
"LICENSE.txt",
"META-INF/LICENSE",
"META-INF/LICENSE.txt",
"META-INF/**/LICENSE.txt",
"META-INF/*.properties",
"META-INF/**/*.properties",
"META-INF/README.md",
"META-INF/NOTICE",
"META-INF/*.kotlin_module",
"META-INF/*.version",
),
)
}
@@ -161,14 +165,15 @@ dependencies {
debugImplementation(compose.ui.tooling)
implementation(compose.ui.tooling.preview)
implementation(compose.ui.util)
implementation(compose.accompanist.systemuicontroller)
implementation(androidx.interpolator)
implementation(androidx.paging.runtime)
implementation(androidx.paging.compose)
implementation(libs.bundles.sqlite)
// SY -->
implementation(libs.sqlcipher)
implementation(sylibs.sqlcipher)
// SY <--
implementation(kotlinx.reflect)
@@ -210,10 +215,6 @@ dependencies {
// Disk
implementation(libs.disklrucache)
implementation(libs.unifile)
implementation(libs.bundles.archive)
// SY -->
implementation(libs.zip4j)
// SY <--
// Preferences
implementation(libs.preferencektx)
@@ -245,15 +246,13 @@ dependencies {
implementation(libs.compose.webview)
implementation(libs.compose.grid)
implementation(libs.google.api.services.drive)
implementation(libs.google.api.client.oauth)
// Logging
implementation(libs.logcat)
// Crash reports/analytics
// "standardImplementation"(libs.firebase.analytics)
// "standardImplementation"(platform(libs.firebase.bom))
// "standardImplementation"(libs.firebase.analytics)
// "standardImplementation"(libs.firebase.crashlytics)
// Shizuku
implementation(libs.bundles.shizuku)
@@ -272,8 +271,9 @@ dependencies {
implementation(sylibs.simularity)
// Firebase (EH)
implementation(sylibs.firebase.analytics)
implementation(sylibs.firebase.crashlytics.ktx)
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
implementation(libs.firebase.crashlytics)
// Better logging (EH)
implementation(sylibs.xlog)
@@ -281,6 +281,14 @@ dependencies {
// RatingBar (SY)
implementation(sylibs.ratingbar)
implementation(sylibs.composeRatingbar)
// Google drive
implementation(sylibs.google.api.services.drive)
implementation(sylibs.google.api.client.oauth)
// Koin
implementation(sylibs.koin.core)
implementation(sylibs.koin.android)
}
androidComponents {
@@ -302,7 +310,7 @@ androidComponents {
tasks {
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs += listOf(
compilerOptions.freeCompilerArgs.addAll(
"-Xcontext-receivers",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
-3
View File
@@ -127,9 +127,6 @@
# XmlUtil
-keep public enum nl.adaptivity.xmlutil.EventType { *; }
# Apache Commons Compress
-keep class * extends org.apache.commons.compress.archivers.zip.ZipExtraField { <init>(); }
# Firebase
-keep class com.google.firebase.installations.** { *; }
-keep interface com.google.firebase.installations.** { *; }
@@ -3,4 +3,4 @@
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_tachi_monochrome_launcher" />
</adaptive-icon>
</adaptive-icon>
@@ -3,4 +3,4 @@
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_tachi_monochrome_launcher" />
</adaptive-icon>
</adaptive-icon>
@@ -0,0 +1,11 @@
package mihon.core.firebase
import android.content.Context
object FirebaseConfig {
fun init(context: Context) = Unit
fun setAnalyticsEnabled(enabled: Boolean) = Unit
fun setCrashlyticsEnabled(enabled: Boolean) = Unit
}
+24 -1
View File
@@ -34,11 +34,23 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Remove permission from Firebase dependency -->
<!-- Remove unnecessary permissions from Firebase dependency -->
<uses-permission
android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"
tools:node="remove" />
<uses-permission
android:name="com.google.android.gms.permission.AD_ID"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_ADSERVICES_AD_ID"
tools:node="remove" />
<application
android:name=".App"
android:allowBackup="false"
@@ -256,6 +268,14 @@
android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<!-- Disable for manual opt-in -->
<meta-data
android:name="firebase_analytics_collection_enabled"
android:value="false" />
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false" />
<!-- Disable advertising ID collection for Firebase -->
<meta-data
android:name="google_analytics_adid_collection_enabled"
@@ -395,4 +415,7 @@
</activity>
</application>
<uses-sdk tools:overrideLibrary="rikka.shizuku.api"
tools:ignore="ManifestOrder" />
</manifest>
@@ -5,7 +5,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun <T : R, R : Any> List<T>.insertSeparators(
generator: (T?, T?) -> R?,
generator: (before: T?, after: T?) -> R?,
): List<R> {
if (isEmpty()) return emptyList()
val newList = mutableListOf<R>()
@@ -19,6 +19,24 @@ fun <T : R, R : Any> List<T>.insertSeparators(
return newList
}
/**
* Similar to [eu.kanade.core.util.insertSeparators] but iterates from last to first element
*/
fun <T : R, R : Any> List<T>.insertSeparatorsReversed(
generator: (before: T?, after: T?) -> R?,
): List<R> {
if (isEmpty()) return emptyList()
val newList = mutableListOf<R>()
for (i in size downTo 0) {
val after = getOrNull(i)
after?.let(newList::add)
val before = getOrNull(i - 1)
val separator = generator.invoke(before, after)
separator?.let(newList::add)
}
return newList.asReversed()
}
fun <E> HashSet<E>.addOrRemove(value: E, shouldAdd: Boolean) {
if (shouldAdd) {
add(value)
@@ -23,7 +23,11 @@ import eu.kanade.domain.track.interactor.AddTracks
import eu.kanade.domain.track.interactor.RefreshTracks
import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
import eu.kanade.domain.track.interactor.TrackChapter
import eu.kanade.tachiyomi.di.InjektModule
import eu.kanade.tachiyomi.di.addFactory
import eu.kanade.tachiyomi.di.addSingletonFactory
import mihon.data.repository.ExtensionRepoRepositoryImpl
import mihon.domain.chapter.interactor.FilterChaptersForDownload
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo
import mihon.domain.extensionrepo.interactor.DeleteExtensionRepo
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
@@ -90,11 +94,7 @@ import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.domain.track.repository.TrackRepository
import tachiyomi.domain.updates.interactor.GetUpdates
import tachiyomi.domain.updates.repository.UpdatesRepository
import uy.kohesive.injekt.api.InjektModule
import uy.kohesive.injekt.api.InjektRegistrar
import uy.kohesive.injekt.api.addFactory
import uy.kohesive.injekt.api.addSingletonFactory
import uy.kohesive.injekt.api.get
class DomainModule : InjektModule {
@@ -152,6 +152,7 @@ class DomainModule : InjektModule {
addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get()) }
addFactory { GetAvailableScanlators(get()) }
addFactory { FilterChaptersForDownload(get(), get(), get(), get()) }
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
addFactory { GetHistory(get()) }
@@ -14,6 +14,9 @@ import eu.kanade.domain.source.interactor.GetSourceCategories
import eu.kanade.domain.source.interactor.RenameSourceCategory
import eu.kanade.domain.source.interactor.SetSourceCategories
import eu.kanade.domain.source.interactor.ToggleExcludeFromDataSaver
import eu.kanade.tachiyomi.di.InjektModule
import eu.kanade.tachiyomi.di.addFactory
import eu.kanade.tachiyomi.di.addSingletonFactory
import eu.kanade.tachiyomi.source.online.MetadataSource
import exh.search.SearchEngine
import tachiyomi.data.manga.CustomMangaRepositoryImpl
@@ -42,7 +45,7 @@ import tachiyomi.domain.manga.interactor.GetMergedManga
import tachiyomi.domain.manga.interactor.GetMergedMangaById
import tachiyomi.domain.manga.interactor.GetMergedMangaForDownloading
import tachiyomi.domain.manga.interactor.GetMergedReferencesById
import tachiyomi.domain.manga.interactor.GetReadMangaNotInLibrary
import tachiyomi.domain.manga.interactor.GetReadMangaNotInLibraryView
import tachiyomi.domain.manga.interactor.GetSearchMetadata
import tachiyomi.domain.manga.interactor.GetSearchTags
import tachiyomi.domain.manga.interactor.GetSearchTitles
@@ -71,11 +74,7 @@ import tachiyomi.domain.source.interactor.InsertSavedSearch
import tachiyomi.domain.source.repository.FeedSavedSearchRepository
import tachiyomi.domain.source.repository.SavedSearchRepository
import tachiyomi.domain.track.interactor.IsTrackUnfollowed
import uy.kohesive.injekt.api.InjektModule
import uy.kohesive.injekt.api.InjektRegistrar
import uy.kohesive.injekt.api.addFactory
import uy.kohesive.injekt.api.addSingletonFactory
import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
class SYDomainModule : InjektModule {
@@ -102,7 +101,7 @@ class SYDomainModule : InjektModule {
addFactory { GetPagePreviews(get(), get()) }
addFactory { SearchEngine() }
addFactory { IsTrackUnfollowed() }
addFactory { GetReadMangaNotInLibrary(get()) }
addFactory { GetReadMangaNotInLibraryView(get()) }
// Required for [MetadataSource]
addFactory<MetadataSource.GetMangaId> { GetManga(get()) }
@@ -32,10 +32,11 @@ class GetEnabledSources(
) { a, b, c -> Triple(a, b, c) },
// SY <--
repository.getSources(),
) { pinnedSourceIds,
(enabledLanguages, disabledSources, lastUsedSource),
(excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter),
sources,
) {
pinnedSourceIds,
(enabledLanguages, disabledSources, lastUsedSource),
(excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter),
sources,
->
val sourcesAndCategories = sourcesInCategories.map {
@@ -49,6 +49,11 @@ class SourcePreferences(
emptySet(),
)
fun globalSearchFilterState() = preferenceStore.getBoolean(
Preference.appStateKey("has_filters_toggle_state"),
false,
)
// SY -->
fun enableSourceBlacklist() = preferenceStore.getBoolean("eh_enable_source_blacklist", true)
@@ -13,7 +13,7 @@ class SyncPreferences(
fun clientAPIKey() = preferenceStore.getString("sync_client_api_key", "")
fun lastSyncTimestamp() = preferenceStore.getLong(Preference.appStateKey("last_sync_timestamp"), 0L)
fun lastSyncEtag() = preferenceStore.getString("sync_etag", "")
fun lastSyncEtag() = preferenceStore.getString("sync_etag", "")
fun syncInterval() = preferenceStore.getInt("sync_interval", 0)
fun syncService() = preferenceStore.getInt("sync_service", 0)
@@ -29,7 +29,7 @@ class SyncPreferences(
)
fun uniqueDeviceID(): String {
val uniqueIDPreference = preferenceStore.getString("unique_device_id", "")
val uniqueIDPreference = preferenceStore.getString(Preference.appStateKey("unique_device_id"), "")
// Retrieve the current value of the preference
var uniqueID = uniqueIDPreference.get()
@@ -53,12 +53,14 @@ class SyncPreferences(
tracking = preferenceStore.getBoolean("tracking", true).get(),
history = preferenceStore.getBoolean("history", true).get(),
appSettings = preferenceStore.getBoolean("appSettings", true).get(),
extensionRepoSettings = preferenceStore.getBoolean("extensionRepoSettings", true).get(),
sourceSettings = preferenceStore.getBoolean("sourceSettings", true).get(),
privateSettings = preferenceStore.getBoolean("privateSettings", true).get(),
// SY -->
customInfo = preferenceStore.getBoolean("customInfo", true).get(),
readEntries = preferenceStore.getBoolean("readEntries", true).get()
readEntries = preferenceStore.getBoolean("readEntries", true).get(),
savedSearches = preferenceStore.getBoolean("savedSearches", true).get(),
// SY <--
)
}
@@ -70,12 +72,14 @@ class SyncPreferences(
preferenceStore.getBoolean("tracking", true).set(syncSettings.tracking)
preferenceStore.getBoolean("history", true).set(syncSettings.history)
preferenceStore.getBoolean("appSettings", true).set(syncSettings.appSettings)
preferenceStore.getBoolean("extensionRepoSettings", true).set(syncSettings.extensionRepoSettings)
preferenceStore.getBoolean("sourceSettings", true).set(syncSettings.sourceSettings)
preferenceStore.getBoolean("privateSettings", true).set(syncSettings.privateSettings)
// SY -->
preferenceStore.getBoolean("customInfo", true).set(syncSettings.customInfo)
preferenceStore.getBoolean("readEntries", true).set(syncSettings.readEntries)
preferenceStore.getBoolean("savedSearches", true).set(syncSettings.savedSearches)
// SY <--
}
@@ -7,11 +7,13 @@ data class SyncSettings(
val tracking: Boolean = true,
val history: Boolean = true,
val appSettings: Boolean = true,
val extensionRepoSettings: Boolean = true,
val sourceSettings: Boolean = true,
val privateSettings: Boolean = false,
// SY -->
val customInfo: Boolean = true,
val readEntries: Boolean = true
val readEntries: Boolean = true,
val savedSearches: Boolean = true,
// SY <--
)
@@ -5,6 +5,7 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.EnhancedTracker
import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.TrackerManager
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
import logcat.LogPriority
@@ -14,17 +15,16 @@ import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.history.interactor.GetHistory
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.time.ZoneOffset
class AddTracks(
private val getTracks: GetTracks,
private val insertTrack: InsertTrack,
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
private val getChaptersByMangaId: GetChaptersByMangaId,
private val trackerManager: TrackerManager,
) {
// TODO: update all trackers based on common data
@@ -79,7 +79,7 @@ class AddTracks(
suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext {
withIOContext {
getTracks.await(manga.id)
trackerManager.loggedInTrackers()
.filterIsInstance<EnhancedTracker>()
.filter { it.accept(source) }
.forEach { service ->
@@ -87,11 +87,11 @@ class AddTracks(
service.match(manga)?.let { track ->
track.manga_id = manga.id
(service as Tracker).bind(track)
insertTrack.await(track.toDomainTrack()!!)
insertTrack.await(track.toDomainTrack(idRequired = false)!!)
syncChapterProgressWithTrack.await(
manga.id,
track.toDomainTrack()!!,
track.toDomainTrack(idRequired = false)!!,
service,
)
}
@@ -10,6 +10,7 @@ import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.domain.track.model.Track
import kotlin.math.max
class SyncChapterProgressWithTrack(
private val updateChapter: UpdateChapter,
@@ -36,7 +37,8 @@ class SyncChapterProgressWithTrack(
// only take into account continuous reading
val localLastRead = sortedChapters.takeWhile { it.read }.lastOrNull()?.chapterNumber ?: 0F
val updatedTrack = remoteTrack.copy(lastChapterRead = localLastRead.toDouble())
val lastRead = max(remoteTrack.lastChapterRead, localLastRead.toDouble())
val updatedTrack = remoteTrack.copy(lastChapterRead = lastRead)
try {
tracker.update(updatedTrack.toDbTrack())
@@ -0,0 +1,10 @@
package eu.kanade.domain.track.model
import dev.icerock.moko.resources.StringResource
import tachiyomi.i18n.MR
enum class AutoTrackState(val titleRes: StringResource) {
ALWAYS(MR.strings.lock_always),
ASK(MR.strings.default_category_summary),
NEVER(MR.strings.lock_never),
}
@@ -1,9 +1,11 @@
package eu.kanade.domain.track.service
import eu.kanade.domain.track.model.AutoTrackState
import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.anilist.Anilist
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.common.preference.getEnum
class TrackPreferences(
private val preferenceStore: PreferenceStore,
@@ -35,4 +37,9 @@ class TrackPreferences(
fun anilistScoreType() = preferenceStore.getString("anilist_score_type", Anilist.POINT_10)
fun autoUpdateTrack() = preferenceStore.getBoolean("pref_auto_update_manga_sync_key", true)
fun autoUpdateTrackOnMarkRead() = preferenceStore.getEnum(
"pref_auto_update_manga_on_mark_read",
AutoTrackState.ALWAYS,
)
}
@@ -18,12 +18,20 @@ class UiPreferences(
fun themeMode() = preferenceStore.getEnum(
"pref_theme_mode_key",
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { ThemeMode.SYSTEM } else { ThemeMode.LIGHT },
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ThemeMode.SYSTEM
} else {
ThemeMode.LIGHT
},
)
fun appTheme() = preferenceStore.getEnum(
"pref_app_theme",
if (DeviceUtil.isDynamicColorAvailable) { AppTheme.MONET } else { AppTheme.DEFAULT },
if (DeviceUtil.isDynamicColorAvailable) {
AppTheme.MONET
} else {
AppTheme.DEFAULT
},
)
fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
@@ -198,7 +198,7 @@ private fun ExtensionDetails(
key = { it.source.id },
) { source ->
SourceSwitchPreference(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
source = source,
onClickSourcePreferences = onClickSourcePreferences,
onClickSource = onClickSource,
@@ -240,7 +240,7 @@ private fun DetailsHeader(
Extension name: ${extension.name} (lang: ${extension.lang}; package: ${extension.pkgName})
Extension version: ${extension.versionName} (lib: ${extension.libVersion}; version code: ${extension.versionCode})
NSFW: ${extension.isNsfw}
""".trimIndent()
""".trimIndent(),
)
if (extension is Extension.Installed) {
@@ -250,8 +250,8 @@ private fun DetailsHeader(
Update available: ${extension.hasUpdate}
Obsolete: ${extension.isObsolete}
Shared: ${extension.isShared}
Repository: ${extension.repoUrl}
""".trimIndent()
Repository: ${extension.repoUrl}
""".trimIndent(),
)
}
}
@@ -58,7 +58,7 @@ private fun ExtensionFilterContent(
) {
items(state.languages) { language ->
SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
title = LocaleHelper.getSourceDisplayName(language, context),
checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) },
@@ -48,6 +48,7 @@ import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep
@@ -91,7 +92,7 @@ fun ExtensionScreen(
PullRefresh(
refreshing = state.isRefreshing,
onRefresh = onRefresh,
enabled = { !state.isLoading },
enabled = !state.isLoading,
) {
when {
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
@@ -188,14 +189,14 @@ private fun ExtensionContent(
}
ExtensionHeader(
textRes = header.textRes,
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
action = action,
)
}
is ExtensionUiModel.Header.Text -> {
ExtensionHeader(
text = header.text,
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
)
}
}
@@ -213,13 +214,15 @@ private fun ExtensionContent(
},
) { item ->
ExtensionItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
item = item,
onClickItem = {
when (it) {
is Extension.Available -> onInstallExtension(it)
is Extension.Installed -> onOpenExtension(it)
is Extension.Untrusted -> { trustState = it }
is Extension.Untrusted -> {
trustState = it
}
}
},
onLongClickItem = onLongClickItem,
@@ -241,7 +244,9 @@ private fun ExtensionContent(
onOpenExtension(it)
}
}
is Extension.Untrusted -> { trustState = it }
is Extension.Untrusted -> {
trustState = it
}
}
},
)
@@ -92,7 +92,7 @@ fun FeedScreen(
refreshing = true
onRefresh()
},
enabled = { !state.isLoadingItems },
enabled = !state.isLoadingItems,
) {
ScrollbarLazyColumn(
contentPadding = contentPadding + topSmallPaddingValues,
@@ -103,7 +103,6 @@ fun FeedScreen(
key = { it.feed.id },
) { item ->
GlobalSearchResultItem(
modifier = Modifier.animateItemPlacement(),
title = item.title,
subtitle = item.subtitle,
onLongClick = {
@@ -116,6 +115,7 @@ fun FeedScreen(
onClickSource(item.source)
}
},
modifier = Modifier.animateItem(),
) {
FeedItem(
item = item,
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
@@ -80,6 +81,7 @@ internal fun GlobalSearchContent(
} ?: source.name,
subtitle = LocaleHelper.getLocalizedDisplayName(source.lang),
onClick = { onClickSource(source) },
modifier = Modifier.animateItem(),
) {
when (result) {
SearchItemResult.Loading -> {
@@ -144,7 +144,7 @@ private fun MigrateSourceList(
key = { (source, _) -> "migrate-${source.id}" },
) { (source, count) ->
MigrateSourceItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
source = source,
count = count,
onClickItem = { onClickItem(source) },
@@ -28,6 +28,7 @@ import eu.kanade.presentation.browse.components.MigrationItem
import eu.kanade.presentation.browse.components.MigrationItemResult
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigratingManga
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@@ -95,7 +96,7 @@ fun MigrationListScreen(
Row(
Modifier
.fillMaxWidth()
.animateItemPlacement()
.animateItemFastScroll()
.padding(horizontal = 16.dp)
.height(IntrinsicSize.Min),
horizontalArrangement = Arrangement.SpaceBetween,
@@ -15,6 +15,7 @@ import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
import eu.kanade.presentation.browse.components.GlobalSearchResultItem
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.util.animateItemFastScroll
import kotlinx.collections.immutable.ImmutableList
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.FeedSavedSearch
@@ -153,7 +154,7 @@ fun SourceFeedList(
key = { it.id },
) { item ->
GlobalSearchResultItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
title = item.title,
subtitle = null,
onLongClick = if (item is SourceFeedUI.SourceSavedSearch) {
@@ -11,6 +11,7 @@ import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Source
@@ -79,7 +80,7 @@ private fun SourcesFilterContent(
contentType = "source-filter-header",
) {
SourcesFilterHeader(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
language = language,
enabled = enabled,
onClickItem = onClickLanguage,
@@ -95,7 +96,7 @@ private fun SourcesFilterContent(
sources.none { it.id.toString() in state.disabledSources }
}
SourcesFilterToggle(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
isEnabled = toggleEnabled,
onClickItem = {
onClickSources(!toggleEnabled, sources)
@@ -109,7 +110,7 @@ private fun SourcesFilterContent(
contentType = { "source-filter-item" },
) { source ->
SourcesFilterItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
source = source,
enabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource,
@@ -35,7 +35,7 @@ import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource
@@ -81,7 +81,7 @@ fun SourcesScreen(
when (model) {
is SourceUiModel.Header -> {
SourceHeader(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
language = model.language,
// SY -->
isCategory = model.isCategory,
@@ -89,7 +89,7 @@ fun SourcesScreen(
)
}
is SourceUiModel.Item -> SourceItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
source = model.source,
// SY -->
showLatest = state.showLatest,
@@ -179,7 +179,7 @@ private fun SourcePinButton(
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onBackground.copy(
alpha = SecondaryItemAlpha,
alpha = SECONDARY_ALPHA,
)
}
val description = if (isPinned) MR.strings.action_unpin else MR.strings.action_pin
@@ -127,7 +127,7 @@ private fun Extension.getIcon(density: Int = DisplayMetrics.DENSITY_DEFAULT): St
return produceState<Result<ImageBitmap>>(initialValue = Result.Loading, this) {
withIOContext {
value = try {
val appInfo = ExtensionLoader.getExtensionPackageInfoFromPkgName(context, pkgName)!!.applicationInfo
val appInfo = ExtensionLoader.getExtensionPackageInfoFromPkgName(context, pkgName)!!.applicationInfo!!
val appResources = context.packageManager.getResourcesForApplication(appInfo)
Result.Success(
appResources.getDrawableForDensity(appInfo.icon, density, null)!!
@@ -30,9 +30,6 @@ import tachiyomi.presentation.core.i18n.stringResource
@Composable
fun GlobalSearchResultItem(
// SY -->
modifier: Modifier = Modifier,
// SY <--
title: String,
// SY -->
subtitle: String?,
@@ -41,9 +38,10 @@ fun GlobalSearchResultItem(
// SY -->
onLongClick: (() -> Unit)? = null,
// SY <--
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Column(modifier) {
Column(modifier = modifier) {
Row(
modifier = Modifier
.padding(
@@ -107,7 +107,7 @@ private fun CategoryContent(
key = { _, category -> "category-${category.id}" },
) { index, category ->
CategoryListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
category = category,
canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex,
@@ -10,8 +10,7 @@ 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.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp
import tachiyomi.presentation.core.util.shouldExpandFAB
@Composable
fun CategoryFloatingActionButton(
@@ -23,7 +22,7 @@ fun CategoryFloatingActionButton(
text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
onClick = onCreate,
expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(),
expanded = lazyListState.shouldExpandFAB(),
modifier = modifier,
)
}
@@ -26,7 +26,7 @@ fun BiometricTimesContent(
) {
items(timeRanges, key = { it.formattedString }) { timeRange ->
BiometricTimesListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
timeRange = timeRange,
onDelete = { onClickDelete(timeRange) },
)
@@ -27,7 +27,7 @@ fun SortTagContent(
) {
itemsIndexed(tags, key = { _, tag -> tag }) { index, tag ->
SortTagListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
tag = tag,
canMoveUp = index != 0,
canMoveDown = index != tags.lastIndex,
@@ -26,7 +26,7 @@ fun SourceCategoryContent(
) {
items(categories, key = { it }) { category ->
SourceCategoryListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
category = category,
onRename = { onClickRename(category) },
onDelete = { onClickDelete(category) },
@@ -179,7 +179,7 @@ fun AppBarTitle(
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.basicMarquee(
delayMillis = 2_000,
repeatDelayMillis = 2_000,
),
)
}
@@ -79,7 +79,7 @@ fun TabbedDialog(
modifier = Modifier.animateContentSize(),
state = pagerState,
verticalAlignment = Alignment.Top,
pageContent = { page -> content(page) }
pageContent = { page -> content(page) },
)
}
}
@@ -18,6 +18,7 @@ import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.components.relativeDateText
import eu.kanade.presentation.history.components.HistoryItem
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@@ -114,14 +115,14 @@ private fun HistoryScreenContent(
when (item) {
is HistoryUiModel.Header -> {
ListGroupHeader(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
text = relativeDateText(item.date),
)
}
is HistoryUiModel.Item -> {
val value = item.item
HistoryItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItemFastScroll(),
history = value,
onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) },
@@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
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.Text
import androidx.compose.runtime.Composable
@@ -35,6 +37,7 @@ import tachiyomi.domain.library.model.sort
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.BaseSortItem
import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.IconItem
@@ -155,7 +158,7 @@ private fun ColumnScope.FilterPage(
)
// SY <--
val trackers = remember { screenModel.trackers }
val trackers by screenModel.trackersFlow.collectAsState()
when (trackers.size) {
0 -> {
// No trackers
@@ -188,6 +191,7 @@ private fun ColumnScope.SortPage(
category: Category?,
screenModel: LibrarySettingsScreenModel,
) {
val trackers by screenModel.trackersFlow.collectAsState()
// SY -->
val globalSortMode by screenModel.libraryPreferences.sortingMode().collectAsState()
val sortingMode = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
@@ -196,40 +200,58 @@ private fun ColumnScope.SortPage(
globalSortMode.type
}
val sortDescending = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
category.sort.isAscending
!category.sort.isAscending
} else {
globalSortMode.isAscending
}.not()
!globalSortMode.isAscending
}
val hasSortTags by remember {
screenModel.libraryPreferences.sortTagsForLibrary().changes()
.map { it.isNotEmpty() }
}.collectAsState(initial = screenModel.libraryPreferences.sortTagsForLibrary().get().isNotEmpty())
// SY <--
val trackerSortOption =
if (screenModel.trackers.isEmpty()) {
emptyList()
val options = remember(trackers.isEmpty()/* SY --> */, hasSortTags/* SY <-- */) {
val trackerMeanPair = if (trackers.isNotEmpty()) {
MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean
} else {
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
null
}
listOfNotNull(
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
MR.strings.action_sort_total to LibrarySort.Type.TotalChapters,
MR.strings.action_sort_last_read to LibrarySort.Type.LastRead,
MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount,
MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded,
// SY -->
if (hasSortTags) {
val tagSortPair = if (hasSortTags) {
SYMR.strings.tag_sorting to LibrarySort.Type.TagList
} else {
null
},
}
// SY <--
).plus(trackerSortOption).map { (titleRes, mode) ->
listOfNotNull(
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
MR.strings.action_sort_total to LibrarySort.Type.TotalChapters,
MR.strings.action_sort_last_read to LibrarySort.Type.LastRead,
MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate,
MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount,
MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter,
MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate,
MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded,
trackerMeanPair,
// SY -->
tagSortPair,
// SY <--
MR.strings.action_sort_random to LibrarySort.Type.Random,
)
}
options.map { (titleRes, mode) ->
if (mode == LibrarySort.Type.Random) {
BaseSortItem(
label = stringResource(titleRes),
icon = Icons.Default.Refresh
.takeIf { sortingMode == LibrarySort.Type.Random },
onClick = {
screenModel.setSort(category, mode, LibrarySort.Direction.Ascending)
},
)
return@map
}
SortItem(
label = stringResource(titleRes),
sortDescending = sortDescending.takeIf { sortingMode == mode },
@@ -241,7 +263,11 @@ private fun ColumnScope.SortPage(
} else {
LibrarySort.Direction.Descending
}
else -> if (sortDescending) LibrarySort.Direction.Descending else LibrarySort.Direction.Ascending
else -> if (sortDescending) {
LibrarySort.Direction.Descending
} else {
LibrarySort.Direction.Ascending
}
}
screenModel.setSort(category, mode, direction)
},
@@ -346,12 +372,13 @@ private fun ColumnScope.GroupPage(
screenModel: LibrarySettingsScreenModel,
hasCategories: Boolean,
) {
val groups = remember(hasCategories, screenModel.trackers) {
val trackers by screenModel.trackersFlow.collectAsState()
val groups = remember(hasCategories, trackers) {
buildList {
add(LibraryGroup.BY_DEFAULT)
add(LibraryGroup.BY_SOURCE)
add(LibraryGroup.BY_STATUS)
if (screenModel.trackers.isNotEmpty()) {
if (trackers.isNotEmpty()) {
add(LibraryGroup.BY_TRACK_STATUS)
}
if (hasCategories) {
@@ -35,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import eu.kanade.presentation.manga.components.MangaCover
@@ -42,19 +43,26 @@ import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.BadgeGroup
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground
import tachiyomi.domain.manga.model.MangaCover as MangaCoverModel
object CommonMangaItemDefaults {
val GridHorizontalSpacer = 4.dp
val GridVerticalSpacer = 4.dp
@Suppress("ConstPropertyName")
const val BrowseFavoriteCoverAlpha = 0.34f
}
private val ContinueReadingButtonSize = 28.dp
private val ContinueReadingButtonSizeSmall = 28.dp
private val ContinueReadingButtonSizeLarge = 32.dp
private val ContinueReadingButtonIconSizeSmall = 16.dp
private val ContinueReadingButtonIconSizeLarge = 20.dp
private val ContinueReadingButtonGridPadding = 6.dp
private val ContinueReadingButtonListSpacing = 8.dp
private const val GridSelectedCoverAlpha = 0.76f
private const val GRID_SELECTED_COVER_ALPHA = 0.76f
/**
* Layout of grid list item with title overlaying the cover.
@@ -62,7 +70,7 @@ private const val GridSelectedCoverAlpha = 0.76f
*/
@Composable
fun MangaCompactGridItem(
coverData: tachiyomi.domain.manga.model.MangaCover,
coverData: MangaCoverModel,
onClick: () -> Unit,
onLongClick: () -> Unit,
isSelected: Boolean = false,
@@ -82,7 +90,7 @@ fun MangaCompactGridItem(
MangaCover.Book(
modifier = Modifier
.fillMaxWidth()
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha),
.alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
data = coverData,
)
},
@@ -96,10 +104,12 @@ fun MangaCompactGridItem(
)
} else if (onClickContinueReading != null) {
ContinueReadingButton(
size = ContinueReadingButtonSizeLarge,
iconSize = ContinueReadingButtonIconSizeLarge,
onClick = onClickContinueReading,
modifier = Modifier
.padding(ContinueReadingButtonGridPadding)
.align(Alignment.BottomEnd),
onClickContinueReading = onClickContinueReading,
)
}
},
@@ -148,11 +158,13 @@ private fun BoxScope.CoverTextOverlay(
)
if (onClickContinueReading != null) {
ContinueReadingButton(
size = ContinueReadingButtonSizeSmall,
iconSize = ContinueReadingButtonIconSizeSmall,
onClick = onClickContinueReading,
modifier = Modifier.padding(
end = ContinueReadingButtonGridPadding,
bottom = ContinueReadingButtonGridPadding,
),
onClickContinueReading = onClickContinueReading,
)
}
}
@@ -163,7 +175,7 @@ private fun BoxScope.CoverTextOverlay(
*/
@Composable
fun MangaComfortableGridItem(
coverData: tachiyomi.domain.manga.model.MangaCover,
coverData: MangaCoverModel,
title: String,
onClick: () -> Unit,
onLongClick: () -> Unit,
@@ -185,7 +197,7 @@ fun MangaComfortableGridItem(
MangaCover.Book(
modifier = Modifier
.fillMaxWidth()
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha),
.alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
data = coverData,
)
},
@@ -194,10 +206,12 @@ fun MangaComfortableGridItem(
content = {
if (onClickContinueReading != null) {
ContinueReadingButton(
size = ContinueReadingButtonSizeLarge,
iconSize = ContinueReadingButtonIconSizeLarge,
onClick = onClickContinueReading,
modifier = Modifier
.padding(ContinueReadingButtonGridPadding)
.align(Alignment.BottomEnd),
onClickContinueReading = onClickContinueReading,
)
}
},
@@ -309,14 +323,14 @@ private fun GridItemSelectable(
private fun Modifier.selectedOutline(
isSelected: Boolean,
color: Color,
) = this then drawBehind { if (isSelected) drawRect(color = color) }
) = drawBehind { if (isSelected) drawRect(color = color) }
/**
* Layout of list item.
*/
@Composable
fun MangaListItem(
coverData: tachiyomi.domain.manga.model.MangaCover,
coverData: MangaCoverModel,
title: String,
onClick: () -> Unit,
onLongClick: () -> Unit,
@@ -354,8 +368,10 @@ fun MangaListItem(
BadgeGroup(content = badge)
if (onClickContinueReading != null) {
ContinueReadingButton(
size = ContinueReadingButtonSizeSmall,
iconSize = ContinueReadingButtonIconSizeSmall,
onClick = onClickContinueReading,
modifier = Modifier.padding(start = ContinueReadingButtonListSpacing),
onClickContinueReading = onClickContinueReading,
)
}
}
@@ -363,23 +379,25 @@ fun MangaListItem(
@Composable
private fun ContinueReadingButton(
size: Dp,
iconSize: Dp,
onClick: () -> Unit,
modifier: Modifier = Modifier,
onClickContinueReading: () -> Unit,
) {
Box(modifier = modifier) {
FilledIconButton(
onClick = onClickContinueReading,
modifier = Modifier.size(ContinueReadingButtonSize),
onClick = onClick,
shape = MaterialTheme.shapes.small,
colors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f),
contentColor = contentColorFor(MaterialTheme.colorScheme.primaryContainer),
),
modifier = Modifier.size(size),
) {
Icon(
imageVector = Icons.Filled.PlayArrow,
contentDescription = stringResource(MR.strings.action_resume),
modifier = Modifier.size(16.dp),
modifier = Modifier.size(iconSize),
)
}
}
@@ -95,7 +95,7 @@ fun LibraryContent(
isRefreshing = false
}
},
enabled = { notSelectionMode },
enabled = notSelectionMode,
) {
LibraryPager(
state = pagerState,
@@ -41,6 +41,7 @@ fun LibraryToolbar(
onClickSyncNow: () -> Unit,
// SY -->
onClickSyncExh: (() -> Unit)?,
isSyncEnabled: Boolean,
// SY <--
searchQuery: String?,
onSearchQueryChange: (String?) -> Unit,
@@ -64,6 +65,7 @@ fun LibraryToolbar(
onClickSyncNow = onClickSyncNow,
// SY -->
onClickSyncExh = onClickSyncExh,
isSyncEnabled = isSyncEnabled,
// SY <--
scrollBehavior = scrollBehavior,
)
@@ -82,6 +84,7 @@ private fun LibraryRegularToolbar(
onClickSyncNow: () -> Unit,
// SY -->
onClickSyncExh: (() -> Unit)?,
isSyncEnabled: Boolean,
// SY <--
scrollBehavior: TopAppBarScrollBehavior?,
) {
@@ -128,10 +131,6 @@ private fun LibraryRegularToolbar(
title = stringResource(MR.strings.action_open_random_manga),
onClick = onClickOpenRandomManga,
),
AppBar.OverflowAction(
title = stringResource(SYMR.strings.sync_library),
onClick = onClickSyncNow,
),
).builder().apply {
// SY -->
if (onClickSyncExh != null) {
@@ -142,6 +141,14 @@ private fun LibraryRegularToolbar(
),
)
}
if (isSyncEnabled) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.sync_library),
onClick = onClickSyncNow,
),
)
}
// SY <--
}.build(),
)
@@ -77,6 +77,7 @@ import eu.kanade.tachiyomi.source.online.english.Pururin
import eu.kanade.tachiyomi.source.online.english.Tsumino
import eu.kanade.tachiyomi.ui.manga.ChapterList
import eu.kanade.tachiyomi.ui.manga.MangaScreenModel
import eu.kanade.tachiyomi.ui.manga.MergedMangaData
import eu.kanade.tachiyomi.ui.manga.PagePreviewState
import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.metadata.MetadataUtil
@@ -102,8 +103,7 @@ import tachiyomi.presentation.core.components.material.ExtendedFloatingActionBut
import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrollingUp
import tachiyomi.presentation.core.util.shouldExpandFAB
import tachiyomi.source.local.isLocal
import java.time.Instant
import java.time.ZoneId
@@ -431,7 +431,7 @@ private fun MangaScreenSmallImpl(
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.isScrollingUp() || chapterListState.isScrolledToEnd(),
expanded = chapterListState.shouldExpandFAB(),
)
}
},
@@ -441,7 +441,7 @@ private fun MangaScreenSmallImpl(
PullRefresh(
refreshing = state.isRefreshingData,
onRefresh = onRefresh,
enabled = { !isAnySelected },
enabled = !isAnySelected,
indicatorPadding = PaddingValues(top = topPadding),
) {
val layoutDirection = LocalLayoutDirection.current
@@ -466,13 +466,9 @@ private fun MangaScreenSmallImpl(
MangaInfoBox(
isTabletUi = false,
appBarPadding = topPadding,
title = state.manga.title,
author = state.manga.author,
artist = state.manga.artist,
manga = state.manga,
sourceName = remember { state.source.getNameForMangaInfo(state.mergedData?.sources) },
isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked,
doSearch = onSearch,
)
@@ -578,6 +574,7 @@ private fun MangaScreenSmallImpl(
sharedChapterItems(
manga = state.manga,
mergedData = state.mergedData,
chapters = listItem,
isAnyChapterSelected = chapters.fastAny { it.selected },
chapterSwipeStartAction = chapterSwipeStartAction,
@@ -755,7 +752,7 @@ fun MangaScreenLargeImpl(
},
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading,
expanded = chapterListState.isScrollingUp() || chapterListState.isScrolledToEnd(),
expanded = chapterListState.shouldExpandFAB(),
)
}
},
@@ -763,7 +760,7 @@ fun MangaScreenLargeImpl(
PullRefresh(
refreshing = state.isRefreshingData,
onRefresh = onRefresh,
enabled = { !isAnySelected },
enabled = !isAnySelected,
indicatorPadding = PaddingValues(
start = insetPadding.calculateStartPadding(layoutDirection),
top = with(density) { topBarHeight.toDp() },
@@ -784,13 +781,9 @@ fun MangaScreenLargeImpl(
MangaInfoBox(
isTabletUi = true,
appBarPadding = contentPadding.calculateTopPadding(),
title = state.manga.title,
author = state.manga.author,
artist = state.manga.artist,
manga = state.manga,
sourceName = remember { state.source.getNameForMangaInfo(state.mergedData?.sources) },
isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked,
doSearch = onSearch,
)
@@ -880,6 +873,7 @@ fun MangaScreenLargeImpl(
sharedChapterItems(
manga = state.manga,
mergedData = state.mergedData,
chapters = listItem,
isAnyChapterSelected = chapters.fastAny { it.selected },
chapterSwipeStartAction = chapterSwipeStartAction,
@@ -944,6 +938,7 @@ private fun SharedMangaBottomActionMenu(
private fun LazyListScope.sharedChapterItems(
manga: Manga,
mergedData: MergedMangaData?,
chapters: List<ChapterList>,
isAnyChapterSelected: Boolean,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
@@ -995,7 +990,9 @@ private fun LazyListScope.sharedChapterItems(
// SY <--
},
readProgress = item.chapter.lastPageRead
.takeIf { /* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L }
.takeIf {
/* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L
}
?.let {
stringResource(
MR.strings.chapter_progress,
@@ -1011,7 +1008,8 @@ private fun LazyListScope.sharedChapterItems(
read = item.chapter.read,
bookmark = item.chapter.bookmark,
selected = item.selected,
downloadIndicatorEnabled = !isAnyChapterSelected && !manga.isLocal(),
downloadIndicatorEnabled =
!isAnyChapterSelected && !(mergedData?.manga?.get(item.chapter.mangaId) ?: manga).isLocal(),
downloadStateProvider = { item.downloadState },
downloadProgressProvider = { item.downloadProgress },
chapterSwipeStartAction = chapterSwipeStartAction,
@@ -12,7 +12,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
@@ -60,6 +60,6 @@ private fun MissingChaptersWarning(count: Int) {
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error.copy(alpha = SecondaryItemAlpha),
color = MaterialTheme.colorScheme.error.copy(alpha = SECONDARY_ALPHA),
)
}
@@ -30,7 +30,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
@@ -41,8 +40,8 @@ import eu.kanade.tachiyomi.data.download.model.Download
import me.saket.swipe.SwipeableActionsBox
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ReadItemAlpha
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground
@@ -69,9 +68,6 @@ fun MangaChapterListItem(
onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
modifier: Modifier = Modifier,
) {
val textAlpha = if (read) ReadItemAlpha else 1f
val textSubtitleAlpha = if (read) ReadItemAlpha else SecondaryItemAlpha
val start = getSwipeAction(
action = chapterSwipeStartAction,
read = read,
@@ -136,29 +132,39 @@ fun MangaChapterListItem(
Text(
text = title,
style = MaterialTheme.typography.bodyMedium,
color = LocalContentColor.current.copy(alpha = textAlpha),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
color = LocalContentColor.current.copy(alpha = if (read) DISABLED_ALPHA else 1f),
)
}
Row(modifier = Modifier.alpha(textSubtitleAlpha)) {
ProvideTextStyle(value = MaterialTheme.typography.bodySmall) {
Row {
val subtitleStyle = MaterialTheme.typography.bodySmall
.merge(
color = LocalContentColor.current
.copy(alpha = if (read) DISABLED_ALPHA else SECONDARY_ALPHA),
)
ProvideTextStyle(value = subtitleStyle) {
if (date != null) {
Text(
text = date,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
if (readProgress != null || scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText()
if (readProgress != null ||
scanlator != null/* SY --> */ ||
sourceName != null/* SY <-- */
) {
DotSeparatorText()
}
}
if (readProgress != null) {
Text(
text = readProgress,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = LocalContentColor.current.copy(alpha = ReadItemAlpha),
color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
)
if (scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText()
}
@@ -38,6 +38,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.core.view.updatePadding
import coil3.asDrawable
import coil3.imageLoader
import coil3.request.CachePolicy
import coil3.request.ImageRequest
@@ -56,7 +57,7 @@ import tachiyomi.presentation.core.util.clickableNoIndication
@Composable
fun MangaCoverDialog(
coverDataProvider: () -> Manga,
manga: Manga,
isCustomCover: Boolean,
snackbarHostState: SnackbarHostState,
onShareClick: () -> Unit,
@@ -166,7 +167,7 @@ fun MangaCoverDialog(
},
update = { view ->
val request = ImageRequest.Builder(view.context)
.data(coverDataProvider())
.data(manga)
.size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED)
.target { image ->
@@ -102,9 +102,12 @@ fun SetIntervalDialog(
),
),
)
Spacer(Modifier.height(MaterialTheme.padding.small))
} else {
Text(
stringResource(MR.strings.manga_interval_expected_update_null),
)
}
Spacer(Modifier.height(MaterialTheme.padding.small))
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
Text(stringResource(MR.strings.manga_interval_custom_amount))
@@ -2,6 +2,7 @@ package eu.kanade.presentation.manga.components
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
@@ -74,6 +75,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga
@@ -81,6 +84,7 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource
@@ -97,13 +101,9 @@ private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTIL
fun MangaInfoBox(
isTabletUi: Boolean,
appBarPadding: Dp,
title: String,
author: String?,
artist: String?,
manga: Manga,
sourceName: String,
isStubSource: Boolean,
coverDataProvider: () -> Manga,
status: Long,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
modifier: Modifier = Modifier,
@@ -115,7 +115,10 @@ fun MangaInfoBox(
MaterialTheme.colorScheme.background,
)
AsyncImage(
model = coverDataProvider(),
model = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
@@ -135,28 +138,20 @@ fun MangaInfoBox(
if (!isTabletUi) {
MangaAndSourceTitlesSmall(
appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
manga = manga,
sourceName = sourceName,
isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
)
} else {
MangaAndSourceTitlesLarge(
appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
manga = manga,
sourceName = sourceName,
isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
)
}
}
@@ -180,7 +175,7 @@ fun MangaActionRow(
// SY <--
modifier: Modifier = Modifier,
) {
val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = .38f)
val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = DISABLED_ALPHA)
// TODO: show something better when using custom interval
val nextUpdateDays = remember(nextUpdate) {
@@ -289,7 +284,8 @@ fun ExpandableMangaDescription(
modifier = Modifier
.padding(top = 8.dp)
.padding(vertical = 12.dp)
.animateContentSize(),
.animateContentSize(animationSpec = spring())
.fillMaxWidth(),
) {
var showMenu by remember { mutableStateOf(false) }
var tagSelected by remember { mutableStateOf("") }
@@ -374,15 +370,11 @@ fun ExpandableMangaDescription(
@Composable
private fun MangaAndSourceTitlesLarge(
appBarPadding: Dp,
coverDataProvider: () -> Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
manga: Manga,
sourceName: String,
isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) {
Column(
modifier = Modifier
@@ -392,19 +384,22 @@ private fun MangaAndSourceTitlesLarge(
) {
MangaCover.Book(
modifier = Modifier.fillMaxWidth(0.65f),
data = coverDataProvider(),
data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick,
)
Spacer(modifier = Modifier.height(16.dp))
MangaContentInfo(
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
title = manga.title,
author = manga.author,
artist = manga.artist,
status = manga.status,
sourceName = sourceName,
isStubSource = isStubSource,
doSearch = doSearch,
textAlign = TextAlign.Center,
)
}
@@ -413,15 +408,11 @@ private fun MangaAndSourceTitlesLarge(
@Composable
private fun MangaAndSourceTitlesSmall(
appBarPadding: Dp,
coverDataProvider: () -> Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
manga: Manga,
sourceName: String,
isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) {
Row(
modifier = Modifier
@@ -434,7 +425,10 @@ private fun MangaAndSourceTitlesSmall(
modifier = Modifier
.sizeIn(maxWidth = 100.dp)
.align(Alignment.Top),
data = coverDataProvider(),
data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick,
)
@@ -442,13 +436,13 @@ private fun MangaAndSourceTitlesSmall(
verticalArrangement = Arrangement.spacedBy(2.dp),
) {
MangaContentInfo(
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
title = manga.title,
author = manga.author,
artist = manga.artist,
status = manga.status,
sourceName = sourceName,
isStubSource = isStubSource,
doSearch = doSearch,
)
}
}
@@ -457,12 +451,12 @@ private fun MangaAndSourceTitlesSmall(
@Composable
private fun ColumnScope.MangaContentInfo(
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String,
isStubSource: Boolean,
doSearch: (query: String, global: Boolean) -> Unit,
textAlign: TextAlign? = LocalTextStyle.current.textAlign,
) {
val context = LocalContext.current
@@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SuggestionChip
import androidx.compose.material3.Surface
@@ -141,7 +141,7 @@ fun TagsChip(
border: ChipBorder? = SuggestionChipDefaults.suggestionChipBorder(),
borderM3: BorderStroke? = SuggestionChipDefaultsM3.suggestionChipBorder(enabled = true),
) {
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) {
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
if (onClick != null) {
SuggestionChip(
modifier = modifier,
@@ -44,7 +44,7 @@ import tachiyomi.presentation.core.i18n.stringResource
@Composable
private fun PagePreviewLoading(
setMaxWidth: (Dp) -> Unit
setMaxWidth: (Dp) -> Unit,
) {
val density = LocalDensity.current
Box(
@@ -63,7 +63,7 @@ private fun PagePreviewLoading(
@Composable
private fun PagePreviewRow(
onOpenPage: (Int) -> Unit,
items: ImmutableList<PagePreview>
items: ImmutableList<PagePreview>,
) {
Row(
modifier = Modifier
@@ -88,7 +88,7 @@ private fun PagePreviewMore(
) {
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center
contentAlignment = Alignment.Center,
) {
TextButton(onClick = onMorePreviewsClicked) {
Text(stringResource(SYMR.strings.more_previews))
@@ -116,7 +116,7 @@ fun PagePreviews(
pagePreviewState.pagePreviews.take(rowCount * itemPerRowCount).chunked(itemPerRowCount).forEach {
PagePreviewRow(
onOpenPage = onOpenPage,
items = remember(it) { it.toImmutableList() }
items = remember(it) { it.toImmutableList() },
)
}
@@ -153,7 +153,7 @@ fun LazyListScope.PagePreviewItems(
) {
PagePreviewRow(
onOpenPage = onOpenPage,
items = remember(it) { it.toImmutableList() }
items = remember(it) { it.toImmutableList() },
)
}
item(
@@ -32,8 +32,6 @@ import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
@Composable
fun ScanlatorFilterDialog(
@@ -97,8 +95,8 @@ fun ScanlatorFilterDialog(
}
}
}
if (!state.isScrolledToStart()) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (!state.isScrolledToEnd()) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
if (state.canScrollBackward) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (state.canScrollForward) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
}
},
properties = DialogProperties(
@@ -111,8 +109,14 @@ fun ScanlatorFilterDialog(
}
} else {
FlowRow {
TextButton(onClick = mutableExcludedScanlators::clear) {
Text(text = stringResource(MR.strings.action_reset))
if (mutableExcludedScanlators.isEmpty()) {
TextButton(onClick = { mutableExcludedScanlators.addAll(availableScanlators) }) {
Text(text = stringResource(MR.strings.action_select_all))
}
} else {
TextButton(onClick = mutableExcludedScanlators::clear) {
Text(text = stringResource(MR.strings.action_reset))
}
}
Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) {
@@ -75,7 +75,7 @@ private fun NewUpdateScreenPreview() {
changelogInfo = """
## Yay
Foobar
### More info
- Hello
- World
@@ -14,11 +14,13 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
@@ -28,19 +30,24 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.util.system.launchRequestPackageInstallsPermission
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.injectLazy
internal class PermissionStep : OnboardingStep {
private val privacyPreferences: PrivacyPreferences by injectLazy()
private var notificationGranted by mutableStateOf(false)
private var batteryGranted by mutableStateOf(false)
@@ -73,7 +80,7 @@ internal class PermissionStep : OnboardingStep {
}
Column {
PermissionItem(
PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_install_apps),
subtitle = stringResource(MR.strings.onboarding_permission_install_apps_description),
granted = installGranted,
@@ -89,7 +96,7 @@ internal class PermissionStep : OnboardingStep {
// no-op. resulting checks is being done on resume
},
)
PermissionItem(
PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_notifications),
subtitle = stringResource(MR.strings.onboarding_permission_notifications_description),
granted = notificationGranted,
@@ -97,7 +104,7 @@ internal class PermissionStep : OnboardingStep {
)
}
PermissionItem(
PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_ignore_battery_opts),
subtitle = stringResource(MR.strings.onboarding_permission_ignore_battery_opts_description),
granted = batteryGranted,
@@ -109,6 +116,29 @@ internal class PermissionStep : OnboardingStep {
context.startActivity(intent)
},
)
HorizontalDivider(
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
color = MaterialTheme.colorScheme.onPrimaryContainer,
)
val crashlyticsPref = privacyPreferences.crashlytics()
val crashlytics by crashlyticsPref.collectAsState()
PermissionSwitch(
title = stringResource(MR.strings.onboarding_permission_crashlytics),
subtitle = stringResource(MR.strings.onboarding_permission_crashlytics_description),
granted = crashlytics,
onToggleChange = crashlyticsPref::set,
)
val analyticsPref = privacyPreferences.analytics()
val analytics by analyticsPref.collectAsState()
PermissionSwitch(
title = stringResource(MR.strings.onboarding_permission_analytics),
subtitle = stringResource(MR.strings.onboarding_permission_analytics_description),
granted = analytics,
onToggleChange = analyticsPref::set,
)
}
}
@@ -127,7 +157,7 @@ internal class PermissionStep : OnboardingStep {
}
@Composable
private fun PermissionItem(
private fun PermissionCheckbox(
title: String,
subtitle: String,
granted: Boolean,
@@ -157,4 +187,26 @@ internal class PermissionStep : OnboardingStep {
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
)
}
@Composable
private fun PermissionSwitch(
title: String,
subtitle: String,
granted: Boolean,
modifier: Modifier = Modifier,
onToggleChange: (Boolean) -> Unit,
) {
ListItem(
modifier = modifier,
headlineContent = { Text(text = title) },
supportingContent = { Text(text = subtitle) },
trailingContent = {
Switch(
checked = granted,
onCheckedChange = onToggleChange,
)
},
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
)
}
}
@@ -7,12 +7,12 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.structuralEqualityPolicy
import androidx.compose.ui.unit.dp
import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
import eu.kanade.presentation.more.settings.widget.InfoWidget
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
@@ -23,8 +23,6 @@ import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp }
@@ -156,16 +154,14 @@ internal fun PreferenceItem(
)
}
is Preference.PreferenceItem.TrackerPreference -> {
val uName by Injekt.get<TrackPreferences>()
.trackUsername(item.tracker)
.collectAsState()
item.tracker.run {
TrackingPreferenceWidget(
tracker = this,
checked = uName.isNotEmpty(),
onClick = { if (isLoggedIn) item.logout() else item.login() },
)
val isLoggedIn by item.tracker.let { tracker ->
tracker.isLoggedInFlow.collectAsState(tracker.isLoggedIn)
}
TrackingPreferenceWidget(
tracker = item.tracker,
checked = isLoggedIn,
onClick = { if (isLoggedIn) item.logout() else item.login() },
)
}
is Preference.PreferenceItem.InfoPreference -> {
InfoWidget(text = item.title)
@@ -3,7 +3,6 @@ package eu.kanade.presentation.more.settings.screen
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Build
import android.provider.Settings
import android.webkit.WebStorage
import android.webkit.WebView
@@ -300,6 +299,7 @@ object SettingsAdvancedScreen : SearchableSettings {
try {
// OkHttp checks for valid values internally
Headers.Builder().add("User-Agent", it)
context.toast(MR.strings.requires_app_restart)
} catch (_: IllegalArgumentException) {
context.toast(MR.strings.error_user_agent_string_invalid)
return@EditTextPreference false
@@ -376,7 +376,7 @@ object SettingsAdvancedScreen : SearchableSettings {
chooseColorProfile.launch(arrayOf("*/*"))
},
),
)
),
)
}
@@ -180,11 +180,15 @@ object SettingsAppearanceScreen : SearchableSettings {
Preference.PreferenceItem.SliderPreference(
value = previewsRowCount,
title = stringResource(SYMR.strings.pref_previews_row_count),
subtitle = if (previewsRowCount > 0) pluralStringResource(
SYMR.plurals.row_count,
previewsRowCount,
previewsRowCount,
) else stringResource(MR.strings.disabled),
subtitle = if (previewsRowCount > 0) {
pluralStringResource(
SYMR.plurals.row_count,
previewsRowCount,
previewsRowCount,
)
} else {
stringResource(MR.strings.disabled)
},
min = 0,
max = 10,
onValueChanged = {
@@ -94,7 +94,7 @@ object SettingsBrowseScreen : SearchableSettings {
pref = uiPreferences.feedTabInFront(),
title = stringResource(SYMR.strings.pref_feed_position),
subtitle = stringResource(SYMR.strings.pref_feed_position_summery),
enabled = hideFeedTab.not()
enabled = hideFeedTab.not(),
),
),
),
@@ -127,7 +127,17 @@ object SettingsDataScreen : SearchableSettings {
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flags)
// For some reason InkBook devices do not implement the SAF properly. Persistable URI grants do not
// work. However, simply retrieving the URI and using it works fine for these devices. Access is not
// revoked after the app is closed or the device is restarted.
// This also holds for some Samsung devices. Thus, we simply execute inside of a try-catch block and
// ignore the exception if it is thrown.
try {
context.contentResolver.takePersistableUriPermission(uri, flags)
} catch (e: SecurityException) {
logcat(LogPriority.ERROR, e)
context.toast(MR.strings.file_picker_uri_permission_unsupported)
}
UniFile.fromUri(context, uri)?.let {
storageDirPref.set(it.uri.toString())
@@ -384,11 +394,23 @@ object SettingsDataScreen : SearchableSettings {
syncServiceType: SyncManager.SyncService,
syncPreferences: SyncPreferences,
): List<Preference> {
return when (syncServiceType) {
val navigator = LocalNavigator.currentOrThrow
val preferences = when (syncServiceType) {
SyncManager.SyncService.NONE -> emptyList()
SyncManager.SyncService.SYNCYOMI -> getSelfHostPreferences(syncPreferences)
SyncManager.SyncService.GOOGLE_DRIVE -> getGoogleDrivePreferences()
}
return if (syncServiceType != SyncManager.SyncService.NONE) {
preferences + Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.pref_choose_what_to_sync),
onClick = {
navigator.push(SyncSettingsSelector())
},
)
} else {
preferences
}
}
@Composable
@@ -505,7 +527,7 @@ object SettingsDataScreen : SearchableSettings {
@Composable
private fun getSyncNowPref(): Preference.PreferenceGroup {
val navigator = LocalNavigator.currentOrThrow
val context = LocalContext.current
return Preference.PreferenceGroup(
title = stringResource(SYMR.strings.pref_sync_now_group_title),
preferenceItems = persistentListOf(
@@ -514,7 +536,11 @@ object SettingsDataScreen : SearchableSettings {
title = stringResource(SYMR.strings.pref_sync_now),
subtitle = stringResource(SYMR.strings.pref_sync_now_subtitle),
onClick = {
navigator.push(SyncSettingsSelector())
if (!SyncDataJob.isRunning(context)) {
SyncDataJob.startNow(context)
} else {
context.toast(SYMR.strings.sync_in_progress)
}
},
),
),
@@ -15,7 +15,6 @@ import eu.kanade.presentation.more.settings.widget.TriStateListDialog
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.runBlocking
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.model.Category
import tachiyomi.domain.download.service.DownloadPreferences
@@ -35,7 +34,7 @@ object SettingsDownloadScreen : SearchableSettings {
@Composable
override fun getPreferences(): List<Preference> {
val getCategories = remember { Injekt.get<GetCategories>() }
val allCategories by getCategories.subscribe().collectAsState(initial = runBlocking { getCategories.await() })
val allCategories by getCategories.subscribe().collectAsState(initial = emptyList())
val downloadPreferences = remember { Injekt.get<DownloadPreferences>() }
return listOf(
@@ -120,6 +119,7 @@ object SettingsDownloadScreen : SearchableSettings {
allCategories: List<Category>,
): Preference.PreferenceGroup {
val downloadNewChaptersPref = downloadPreferences.downloadNewChapters()
val downloadNewUnreadChaptersOnlyPref = downloadPreferences.downloadNewUnreadChaptersOnly()
val downloadNewChapterCategoriesPref = downloadPreferences.downloadNewChapterCategories()
val downloadNewChapterCategoriesExcludePref = downloadPreferences.downloadNewChapterCategoriesExclude()
@@ -152,6 +152,11 @@ object SettingsDownloadScreen : SearchableSettings {
pref = downloadNewChaptersPref,
title = stringResource(MR.strings.pref_download_new),
),
Preference.PreferenceItem.SwitchPreference(
pref = downloadNewUnreadChaptersOnlyPref,
title = stringResource(MR.strings.pref_download_new_unread_chapters_only),
enabled = downloadNewChapters,
),
Preference.PreferenceItem.TextPreference(
title = stringResource(MR.strings.categories),
subtitle = getCategoriesLabel(
@@ -25,7 +25,6 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.ResetCategoryFlags
@@ -57,9 +56,7 @@ object SettingsLibraryScreen : SearchableSettings {
override fun getPreferences(): List<Preference> {
val getCategories = remember { Injekt.get<GetCategories>() }
val libraryPreferences = remember { Injekt.get<LibraryPreferences>() }
val allCategories by getCategories.subscribe().collectAsState(
initial = runBlocking { getCategories.await() },
)
val allCategories by getCategories.subscribe().collectAsState(initial = emptyList())
// SY -->
val unsortedPreferences = remember { Injekt.get<UnsortedPreferences>() }
// SY <--
@@ -84,9 +81,6 @@ object SettingsLibraryScreen : SearchableSettings {
val scope = rememberCoroutineScope()
val userCategoriesCount = allCategories.filterNot(Category::isSystemCategory).size
val defaultCategory by libraryPreferences.defaultCategory().collectAsState()
val selectedCategory = allCategories.find { it.id == defaultCategory.toLong() }
// For default category
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
allCategories.fastMap { it.id.toInt() }
@@ -108,7 +102,6 @@ object SettingsLibraryScreen : SearchableSettings {
Preference.PreferenceItem.ListPreference(
pref = libraryPreferences.defaultCategory(),
title = stringResource(MR.strings.default_category),
subtitle = selectedCategory?.visualName ?: stringResource(MR.strings.default_category_summary),
entries = ids.zip(labels).toMap().toImmutableMap(),
),
Preference.PreferenceItem.SwitchPreference(
@@ -17,6 +17,7 @@ import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
@@ -88,12 +89,8 @@ object SettingsReaderScreen : SearchableSettings {
title = stringResource(MR.strings.pref_page_transitions),
),
SY <-- */
Preference.PreferenceItem.SwitchPreference(
pref = readerPref.flashOnPageChange(),
title = stringResource(MR.strings.pref_flash_page),
subtitle = stringResource(MR.strings.pref_flash_page_summ),
),
getDisplayGroup(readerPreferences = readerPref),
getEInkGroup(readerPreferences = readerPref),
getReadingGroup(readerPreferences = readerPref),
getPagedGroup(readerPreferences = readerPref),
getWebtoonGroup(readerPreferences = readerPref),
@@ -156,6 +153,65 @@ object SettingsReaderScreen : SearchableSettings {
)
}
@Composable
private fun getEInkGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
val flashPageState by readerPreferences.flashOnPageChange().collectAsState()
val flashMillisPref = readerPreferences.flashDurationMillis()
val flashMillis by flashMillisPref.collectAsState()
val flashIntervalPref = readerPreferences.flashPageInterval()
val flashInterval by flashIntervalPref.collectAsState()
val flashColorPref = readerPreferences.flashColor()
return Preference.PreferenceGroup(
title = "E-Ink",
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
pref = readerPreferences.flashOnPageChange(),
title = stringResource(MR.strings.pref_flash_page),
subtitle = stringResource(MR.strings.pref_flash_page_summ),
),
Preference.PreferenceItem.SliderPreference(
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
min = 1,
max = 15,
title = stringResource(MR.strings.pref_flash_duration),
subtitle = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
onValueChanged = {
flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION)
true
},
enabled = flashPageState,
),
Preference.PreferenceItem.SliderPreference(
value = flashInterval,
min = 1,
max = 10,
title = stringResource(MR.strings.pref_flash_page_interval),
subtitle = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
onValueChanged = {
flashIntervalPref.set(it)
true
},
enabled = flashPageState,
),
Preference.PreferenceItem.ListPreference(
pref = flashColorPref,
title = stringResource(MR.strings.pref_flash_with),
entries = persistentMapOf(
ReaderPreferences.FlashColor.BLACK to stringResource(MR.strings.pref_flash_style_black),
ReaderPreferences.FlashColor.WHITE to stringResource(MR.strings.pref_flash_style_white),
ReaderPreferences.FlashColor.WHITE_BLACK
to stringResource(MR.strings.pref_flash_style_white_black),
),
enabled = flashPageState,
),
),
)
}
@Composable
private fun getReadingGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
@@ -13,8 +13,10 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.clearText
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material3.HorizontalDivider
@@ -28,11 +30,8 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
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.focus.FocusRequester
@@ -43,7 +42,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
@@ -88,9 +86,7 @@ class SettingsSearchScreen : Screen() {
focusRequester.requestFocus()
}
var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue())
}
val textFieldState = rememberTextFieldState()
Scaffold(
topBar = {
Column {
@@ -105,20 +101,19 @@ class SettingsSearchScreen : Screen() {
},
title = {
BasicTextField(
value = textFieldValue,
onValueChange = { textFieldValue = it },
state = textFieldState,
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester)
.runOnEnterKeyPressed(action = focusManager::clearFocus),
textStyle = MaterialTheme.typography.bodyLarge
.copy(color = MaterialTheme.colorScheme.onSurface),
singleLine = true,
lineLimits = TextFieldLineLimits.SingleLine,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardActions = KeyboardActions(onSearch = { focusManager.clearFocus() }),
onKeyboardAction = { focusManager.clearFocus() },
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
decorationBox = {
if (textFieldValue.text.isEmpty()) {
decorator = {
if (textFieldState.text.isEmpty()) {
Text(
text = stringResource(MR.strings.action_search_settings),
color = MaterialTheme.colorScheme.onSurfaceVariant,
@@ -130,8 +125,8 @@ class SettingsSearchScreen : Screen() {
)
},
actions = {
if (textFieldValue.text.isNotEmpty()) {
IconButton(onClick = { textFieldValue = TextFieldValue() }) {
if (textFieldState.text.isNotEmpty()) {
IconButton(onClick = { textFieldState.clearText() }) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = null,
@@ -146,7 +141,7 @@ class SettingsSearchScreen : Screen() {
},
) { contentPadding ->
SearchResult(
searchKey = textFieldValue.text,
searchKey = textFieldState.text.toString(),
listState = listState,
contentPadding = contentPadding,
) { result ->
@@ -45,6 +45,7 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import dev.icerock.moko.resources.StringResource
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
import eu.kanade.tachiyomi.ui.category.biometric.BiometricTimesScreen
@@ -70,10 +71,20 @@ object SettingsSecurityScreen : SearchableSettings {
@Composable
override fun getPreferences(): List<Preference> {
val context = LocalContext.current
val securityPreferences = remember { Injekt.get<SecurityPreferences>() }
val authSupported = remember { context.isAuthenticationSupported() }
val privacyPreferences = remember { Injekt.get<PrivacyPreferences>() }
return listOf(
getSecurityGroup(securityPreferences),
getFirebaseGroup(privacyPreferences),
)
}
@Composable
private fun getSecurityGroup(
securityPreferences: SecurityPreferences,
): Preference.PreferenceGroup {
val context = LocalContext.current
val authSupported = remember { context.isAuthenticationSupported() }
val useAuthPref = securityPreferences.useAuthenticator()
val useAuth by useAuthPref.collectAsState()
@@ -81,129 +92,132 @@ object SettingsSecurityScreen : SearchableSettings {
val isCbzPasswordSet by remember { CbzCrypto.isPasswordSetState(scope) }.collectAsState()
val passwordProtectDownloads by securityPreferences.passwordProtectDownloads().collectAsState()
return listOf(
Preference.PreferenceItem.SwitchPreference(
pref = useAuthPref,
title = stringResource(MR.strings.lock_with_biometrics),
enabled = authSupported,
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.stringResource(MR.strings.lock_with_biometrics),
)
},
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.lockAppAfter(),
title = stringResource(MR.strings.lock_when_idle),
enabled = authSupported && useAuth,
entries = LockAfterValues
.associateWith {
when (it) {
-1 -> stringResource(MR.strings.lock_never)
0 -> stringResource(MR.strings.lock_always)
else -> pluralStringResource(MR.plurals.lock_after_mins, count = it, it)
return Preference.PreferenceGroup(
title = stringResource(MR.strings.pref_security),
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
pref = useAuthPref,
title = stringResource(MR.strings.lock_with_biometrics),
enabled = authSupported,
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.stringResource(MR.strings.lock_with_biometrics),
)
},
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.lockAppAfter(),
title = stringResource(MR.strings.lock_when_idle),
enabled = authSupported && useAuth,
entries = LockAfterValues
.associateWith {
when (it) {
-1 -> stringResource(MR.strings.lock_never)
0 -> stringResource(MR.strings.lock_always)
else -> pluralStringResource(MR.plurals.lock_after_mins, count = it, it)
}
}
.toImmutableMap(),
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.stringResource(MR.strings.lock_when_idle),
)
},
),
Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.hideNotificationContent(),
title = stringResource(MR.strings.hide_notification_content),
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.secureScreen(),
title = stringResource(MR.strings.secure_screen),
entries = SecurityPreferences.SecureScreenMode.entries
.associateWith { stringResource(it.titleRes) }
.toImmutableMap(),
),
// SY -->
Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.passwordProtectDownloads(),
title = stringResource(SYMR.strings.password_protect_downloads),
subtitle = stringResource(SYMR.strings.password_protect_downloads_summary),
enabled = isCbzPasswordSet,
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.encryptionType(),
title = stringResource(SYMR.strings.encryption_type),
entries = SecurityPreferences.EncryptionType.entries
.associateWith { stringResource(it.titleRes) }
.toImmutableMap(),
enabled = passwordProtectDownloads,
),
kotlin.run {
var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) {
PasswordDialog(
onDismissRequest = { dialogOpen = false },
onReturnPassword = { password ->
dialogOpen = false
CbzCrypto.deleteKeyCbz()
securityPreferences.cbzPassword().set(CbzCrypto.encryptCbz(password.replace("\n", "")))
},
)
}
.toImmutableMap(),
onValueChanged = {
(context as FragmentActivity).authenticate(
title = context.stringResource(MR.strings.lock_when_idle),
)
},
),
Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.hideNotificationContent(),
title = stringResource(MR.strings.hide_notification_content),
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.secureScreen(),
title = stringResource(MR.strings.secure_screen),
entries = SecurityPreferences.SecureScreenMode.entries
.associateWith { stringResource(it.titleRes) }
.toImmutableMap(),
),
// SY -->
Preference.PreferenceItem.SwitchPreference(
pref = securityPreferences.passwordProtectDownloads(),
title = stringResource(SYMR.strings.password_protect_downloads),
subtitle = stringResource(SYMR.strings.password_protect_downloads_summary),
enabled = isCbzPasswordSet,
),
Preference.PreferenceItem.ListPreference(
pref = securityPreferences.encryptionType(),
title = stringResource(SYMR.strings.encryption_type),
entries = SecurityPreferences.EncryptionType.entries
.associateWith { stringResource(it.titleRes) }
.toImmutableMap(),
enabled = passwordProtectDownloads,
),
kotlin.run {
var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) {
PasswordDialog(
onDismissRequest = { dialogOpen = false },
onReturnPassword = { password ->
dialogOpen = false
CbzCrypto.deleteKeyCbz()
securityPreferences.cbzPassword().set(CbzCrypto.encryptCbz(password.replace("\n", "")))
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.set_cbz_zip_password),
onClick = {
dialogOpen = true
},
)
}
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.set_cbz_zip_password),
onClick = {
dialogOpen = true
},
)
},
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.delete_cbz_archive_password),
onClick = {
CbzCrypto.deleteKeyCbz()
securityPreferences.cbzPassword().set("")
},
enabled = isCbzPasswordSet,
),
kotlin.run {
val navigator = LocalNavigator.currentOrThrow
val count by securityPreferences.authenticatorTimeRanges().collectAsState()
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.action_edit_biometric_lock_times),
subtitle = pluralStringResource(
SYMR.plurals.num_lock_times,
count.size,
count.size,
),
title = stringResource(SYMR.strings.delete_cbz_archive_password),
onClick = {
navigator.push(BiometricTimesScreen())
CbzCrypto.deleteKeyCbz()
securityPreferences.cbzPassword().set("")
},
enabled = useAuth,
)
},
kotlin.run {
val selection by securityPreferences.authenticatorDays().collectAsState()
var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) {
SetLockedDaysDialog(
onDismissRequest = { dialogOpen = false },
initialSelection = selection,
onDaysSelected = {
dialogOpen = false
securityPreferences.authenticatorDays().set(it)
enabled = isCbzPasswordSet,
),
kotlin.run {
val navigator = LocalNavigator.currentOrThrow
val count by securityPreferences.authenticatorTimeRanges().collectAsState()
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.action_edit_biometric_lock_times),
subtitle = pluralStringResource(
SYMR.plurals.num_lock_times,
count.size,
count.size,
),
onClick = {
navigator.push(BiometricTimesScreen())
},
enabled = useAuth,
)
}
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.biometric_lock_days),
subtitle = stringResource(SYMR.strings.biometric_lock_days_summary),
onClick = { dialogOpen = true },
enabled = useAuth,
)
},
// SY <--
Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.secure_screen_summary)),
},
kotlin.run {
val selection by securityPreferences.authenticatorDays().collectAsState()
var dialogOpen by remember { mutableStateOf(false) }
if (dialogOpen) {
SetLockedDaysDialog(
onDismissRequest = { dialogOpen = false },
initialSelection = selection,
onDaysSelected = {
dialogOpen = false
securityPreferences.authenticatorDays().set(it)
},
)
}
Preference.PreferenceItem.TextPreference(
title = stringResource(SYMR.strings.biometric_lock_days),
subtitle = stringResource(SYMR.strings.biometric_lock_days_summary),
onClick = { dialogOpen = true },
enabled = useAuth,
)
},
// SY <--
Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.secure_screen_summary)),
),
)
}
@@ -361,6 +375,28 @@ object SettingsSecurityScreen : SearchableSettings {
)
}
// SY <--
@Composable
private fun getFirebaseGroup(
privacyPreferences: PrivacyPreferences,
): Preference.PreferenceGroup {
return Preference.PreferenceGroup(
title = stringResource(MR.strings.pref_firebase),
preferenceItems = persistentListOf(
Preference.PreferenceItem.SwitchPreference(
pref = privacyPreferences.crashlytics(),
title = stringResource(MR.strings.onboarding_permission_crashlytics),
subtitle = stringResource(MR.strings.onboarding_permission_crashlytics_description),
),
Preference.PreferenceItem.SwitchPreference(
pref = privacyPreferences.analytics(),
title = stringResource(MR.strings.onboarding_permission_analytics),
subtitle = stringResource(MR.strings.onboarding_permission_analytics_description),
),
Preference.PreferenceItem.InfoPreference(stringResource(MR.strings.firebase_summary)),
),
)
}
}
private val LockAfterValues = persistentListOf(
@@ -40,6 +40,7 @@ import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import dev.icerock.moko.resources.StringResource
import eu.kanade.domain.track.model.AutoTrackState
import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.presentation.more.settings.Preference
import eu.kanade.tachiyomi.data.track.EnhancedTracker
@@ -53,6 +54,7 @@ import eu.kanade.tachiyomi.util.system.openInBrowser
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toPersistentMap
import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.domain.source.service.SourceManager
@@ -85,6 +87,7 @@ object SettingsTrackingScreen : SearchableSettings {
val trackPreferences = remember { Injekt.get<TrackPreferences>() }
val trackerManager = remember { Injekt.get<TrackerManager>() }
val sourceManager = remember { Injekt.get<SourceManager>() }
val autoTrackStatePref = trackPreferences.autoUpdateTrackOnMarkRead()
var dialog by remember { mutableStateOf<Any?>(null) }
dialog?.run {
@@ -125,6 +128,13 @@ object SettingsTrackingScreen : SearchableSettings {
pref = trackPreferences.autoUpdateTrack(),
title = stringResource(MR.strings.pref_auto_update_manga_sync),
),
Preference.PreferenceItem.ListPreference(
pref = trackPreferences.autoUpdateTrackOnMarkRead(),
title = stringResource(MR.strings.pref_auto_update_manga_on_mark_read),
entries = AutoTrackState.entries
.associateWith { stringResource(it.titleRes) }
.toPersistentMap(),
),
Preference.PreferenceGroup(
title = stringResource(MR.strings.services),
preferenceItems = persistentListOf(
@@ -37,7 +37,7 @@ class OpenSourceLicensesScreen : Screen() {
name = it.name,
website = it.website,
license = it.licenses.firstOrNull()?.htmlReadyLicenseContent.orEmpty(),
)
),
)
},
)
@@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.AndroidXmlReader
import nl.adaptivity.xmlutil.core.AndroidXmlReader
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlSerialName
import nl.adaptivity.xmlutil.serialization.XmlValue
@@ -8,6 +8,7 @@ import androidx.compose.ui.platform.LocalContext
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoConfirmDialog
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoConflictDialog
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoCreateDialog
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoDeleteDialog
@@ -32,7 +33,7 @@ class ExtensionReposScreen(
val state by screenModel.state.collectAsState()
LaunchedEffect(url) {
url?.let { screenModel.createRepo(it) }
url?.let { screenModel.showDialog(RepoDialog.Confirm(it)) }
}
if (state is RepoScreenState.Loading) {
@@ -67,7 +68,6 @@ class ExtensionReposScreen(
repo = dialog.repo,
)
}
is RepoDialog.Conflict -> {
ExtensionRepoConflictDialog(
onDismissRequest = screenModel::dismissDialog,
@@ -76,6 +76,13 @@ class ExtensionReposScreen(
newRepo = dialog.newRepo,
)
}
is RepoDialog.Confirm -> {
ExtensionRepoConfirmDialog(
onDismissRequest = screenModel::dismissDialog,
onCreate = { screenModel.createRepo(dialog.url) },
repo = dialog.url,
)
}
}
LaunchedEffect(Unit) {
@@ -125,6 +125,7 @@ sealed class RepoDialog {
data object Create : RepoDialog()
data class Delete(val repo: String) : RepoDialog()
data class Conflict(val oldRepo: ExtensionRepo, val newRepo: ExtensionRepo) : RepoDialog()
data class Confirm(val url: String) : RepoDialog()
}
sealed class RepoScreenState {
@@ -46,7 +46,7 @@ fun ExtensionReposContent(
repos.forEach {
item {
ExtensionRepoListItem(
modifier = Modifier.animateItemPlacement(),
modifier = Modifier.animateItem(),
repo = it,
onOpenWebsite = { onOpenWebsite(it) },
onDelete = { onClickDelete(it.baseUrl) },
@@ -152,3 +152,35 @@ fun ExtensionRepoConflictDialog(
},
)
}
@Composable
fun ExtensionRepoConfirmDialog(
onDismissRequest: () -> Unit,
onCreate: () -> Unit,
repo: String,
) {
AlertDialog(
onDismissRequest = onDismissRequest,
title = {
Text(text = stringResource(MR.strings.action_add_repo))
},
text = {
Text(text = stringResource(MR.strings.add_repo_confirmation, repo))
},
confirmButton = {
TextButton(
onClick = {
onCreate()
onDismissRequest()
},
) {
Text(text = stringResource(MR.strings.action_add))
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(MR.strings.action_cancel))
}
},
)
}
@@ -6,7 +6,6 @@ import android.content.Intent
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collectAsState
@@ -27,7 +26,6 @@ import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.flow.update
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.components.LazyColumnWithAction
import tachiyomi.presentation.core.components.SectionCard
@@ -69,7 +67,7 @@ class CreateBackupScreen : Screen() {
LazyColumnWithAction(
contentPadding = contentPadding,
actionLabel = stringResource(MR.strings.action_create),
actionEnabled = state.options.anyEnabled(),
actionEnabled = state.options.canCreate(),
onClickAction = {
if (!BackupCreateJob.isManualJobRunning(context)) {
try {
@@ -104,7 +102,7 @@ class CreateBackupScreen : Screen() {
}
@Composable
private fun ColumnScope.Options(
private fun Options(
options: ImmutableList<BackupOptions.Entry>,
state: CreateBackupScreenModel.State,
model: CreateBackupScreenModel,
@@ -63,7 +63,7 @@ class RestoreBackupScreen(
LazyColumnWithAction(
contentPadding = contentPadding,
actionLabel = stringResource(MR.strings.action_restore),
actionEnabled = state.canRestore && state.options.anyEnabled(),
actionEnabled = state.canRestore && state.options.canRestore(),
onClickAction = {
model.startRestore()
navigator.pop()
@@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -16,7 +15,6 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.data.backup.create.BackupOptions
import eu.kanade.tachiyomi.data.sync.SyncDataJob
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.flow.update
import tachiyomi.i18n.MR
@@ -32,7 +30,6 @@ import uy.kohesive.injekt.api.get
class SyncSettingsSelector : Screen() {
@Composable
override fun Content() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow
val model = rememberScreenModel { SyncSettingsSelectorModel() }
val state by model.state.collectAsState()
@@ -48,15 +45,10 @@ class SyncSettingsSelector : Screen() {
) { contentPadding ->
LazyColumnWithAction(
contentPadding = contentPadding,
actionLabel = stringResource(SYMR.strings.label_sync),
actionEnabled = state.options.anyEnabled(),
actionLabel = stringResource(MR.strings.action_save),
actionEnabled = true,
onClickAction = {
if (!SyncDataJob.isRunning(context)) {
model.syncNow(context)
navigator.pop()
} else {
context.toast(SYMR.strings.sync_in_progress)
}
navigator.pop()
},
) {
item {
@@ -122,12 +114,14 @@ private class SyncSettingsSelectorModel(
tracking = syncSettings.tracking,
history = syncSettings.history,
appSettings = syncSettings.appSettings,
extensionRepoSettings = syncSettings.extensionRepoSettings,
sourceSettings = syncSettings.sourceSettings,
privateSettings = syncSettings.privateSettings,
// SY -->
customInfo = syncSettings.customInfo,
readEntries = syncSettings.readEntries,
savedSearches = syncSettings.savedSearches,
// SY <--
)
}
@@ -140,12 +134,14 @@ private class SyncSettingsSelectorModel(
tracking = backupOptions.tracking,
history = backupOptions.history,
appSettings = backupOptions.appSettings,
extensionRepoSettings = backupOptions.extensionRepoSettings,
sourceSettings = backupOptions.sourceSettings,
privateSettings = backupOptions.privateSettings,
// SY -->
customInfo = backupOptions.customInfo,
readEntries = backupOptions.readEntries,
savedSearches = backupOptions.savedSearches,
// SY <--
)
}
@@ -28,7 +28,7 @@ import tachiyomi.presentation.core.i18n.stringResource
class BackupSchemaScreen : Screen() {
companion object {
const val title = "Backup file schema"
const val TITLE = "Backup file schema"
}
@Composable
@@ -41,7 +41,7 @@ class BackupSchemaScreen : Screen() {
Scaffold(
topBar = {
AppBar(
title = title,
title = TITLE,
navigateUp = navigator::pop,
actions = {
AppBarActions(
@@ -50,7 +50,7 @@ class BackupSchemaScreen : Screen() {
title = stringResource(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,
onClick = {
context.copyToClipboard(title, schema)
context.copyToClipboard(TITLE, schema)
},
),
),
@@ -31,11 +31,11 @@ class DebugInfoScreen : Screen() {
itemsProvider = {
listOf(
Preference.PreferenceItem.TextPreference(
title = WorkerInfoScreen.title,
title = WorkerInfoScreen.TITLE,
onClick = { navigator.push(WorkerInfoScreen()) },
),
Preference.PreferenceItem.TextPreference(
title = BackupSchemaScreen.title,
title = BackupSchemaScreen.TITLE,
onClick = { navigator.push(BackupSchemaScreen()) },
),
getAppInfoGroup(),
@@ -49,7 +49,7 @@ import java.time.ZoneId
class WorkerInfoScreen : Screen() {
companion object {
const val title = "Worker info"
const val TITLE = "Worker info"
}
@Composable
@@ -65,7 +65,7 @@ class WorkerInfoScreen : Screen() {
Scaffold(
topBar = {
AppBar(
title = title,
title = TITLE,
navigateUp = navigator::pop,
actions = {
AppBarActions(
@@ -74,7 +74,7 @@ class WorkerInfoScreen : Screen() {
title = stringResource(MR.strings.action_copy_to_clipboard),
icon = Icons.Default.ContentCopy,
onClick = {
context.copyToClipboard(title, enqueued + finished + running)
context.copyToClipboard(TITLE, enqueued + finished + running)
},
),
),
@@ -159,7 +159,7 @@ class WorkerInfoScreen : Screen() {
Injekt.get<UiPreferences>().dateFormat().get(),
),
)
appendLine("Next scheduled run: $timestamp",)
appendLine("Next scheduled run: $timestamp")
appendLine("Attempt #${workInfo.runAttemptCount + 1}")
}
appendLine()
@@ -29,32 +29,24 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import androidx.core.app.ActivityCompat
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.domain.ui.model.AppTheme
import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import tachiyomi.core.common.preference.InMemoryPreferenceStore
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.fullType
@Composable
internal fun AppThemePreferenceWidget(
@@ -257,18 +249,18 @@ fun AppThemePreviewItem(
}
}
@PreviewLightDark
@Composable
private fun AppThemesListPreview() {
var appTheme by remember { mutableStateOf(AppTheme.DEFAULT) }
Injekt.addSingleton(fullType<UiPreferences>(), UiPreferences(InMemoryPreferenceStore()))
TachiyomiTheme(appTheme = appTheme) {
Surface {
AppThemesList(
currentTheme = appTheme,
amoled = false,
onItemClick = { appTheme = it },
)
}
}
}
// @PreviewLightDark
// @Composable
// private fun AppThemesListPreview() {
// var appTheme by remember { mutableStateOf(AppTheme.DEFAULT) }
// Injekt.addSingleton(fullType<UiPreferences>(), UiPreferences(InMemoryPreferenceStore()))
// TachiyomiTheme(appTheme = appTheme) {
// Surface {
// AppThemesList(
// currentTheme = appTheme,
// amoled = false,
// onItemClick = { appTheme = it },
// )
// }
// }
// }
@@ -26,8 +26,6 @@ import androidx.compose.ui.unit.dp
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
@Composable
fun <T> ListPreferenceWidget(
@@ -69,8 +67,8 @@ fun <T> ListPreferenceWidget(
}
}
}
if (!state.isScrolledToStart()) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (!state.isScrolledToEnd()) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
if (state.canScrollBackward) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (state.canScrollForward) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
}
},
confirmButton = {
@@ -30,11 +30,11 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
private enum class State {
CHECKED, INVERSED, UNCHECKED
CHECKED,
INVERSED,
UNCHECKED,
}
@Composable
@@ -115,16 +115,8 @@ fun <T> TriStateListDialog(
}
}
if (!listState.isScrolledToStart()) {
HorizontalDivider(
modifier = Modifier.align(Alignment.TopCenter),
)
}
if (!listState.isScrolledToEnd()) {
HorizontalDivider(
modifier = Modifier.align(Alignment.BottomCenter),
)
}
if (listState.canScrollBackward) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (listState.canScrollForward) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
}
}
},
@@ -15,7 +15,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
import tachiyomi.presentation.core.components.material.padding
@Composable
@@ -73,7 +73,7 @@ private fun RowScope.BaseStatsItem(
style = subtitleStyle
.copy(
color = MaterialTheme.colorScheme.onSurface
.copy(alpha = SecondaryItemAlpha),
.copy(alpha = SECONDARY_ALPHA),
),
textAlign = TextAlign.Center,
)
@@ -8,11 +8,13 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.manga.components.MangaChapterListItem
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterItem
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
@@ -20,8 +22,13 @@ import eu.kanade.tachiyomi.util.lang.toRelativeString
import exh.metadata.MetadataUtil
import exh.source.isEhBasedManga
import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
@@ -39,6 +46,8 @@ fun ChapterListDialog(
val manga by screenModel.mangaFlow.collectAsState()
val context = LocalContext.current
val state = rememberLazyListState(chapters.indexOfFirst { it.isCurrent }.coerceAtLeast(0))
val downloadManager: DownloadManager = remember { Injekt.get() }
val downloadQueueState by downloadManager.queueState.collectAsState()
AdaptiveSheet(
onDismissRequest = onDismissRequest,
@@ -52,6 +61,28 @@ fun ChapterListDialog(
items = chapters,
key = { "chapter-${it.chapter.id}" },
) { chapterItem ->
val activeDownload = downloadQueueState.find { it.chapter.id == chapterItem.chapter.id }
val progress = activeDownload?.let {
downloadManager.progressFlow()
.filter { it.chapter.id == chapterItem.chapter.id }
.map { it.progress }
.collectAsState(0).value
} ?: 0
val downloaded = if (chapterItem.manga.isLocal()) {
true
} else {
downloadManager.isChapterDownloaded(
chapterItem.chapter.name,
chapterItem.chapter.scanlator,
chapterItem.manga.ogTitle,
chapterItem.manga.source,
)
}
val downloadState = when {
activeDownload != null -> activeDownload.status
downloaded -> Download.State.DOWNLOADED
else -> Download.State.NOT_DOWNLOADED
}
MangaChapterListItem(
title = chapterItem.chapter.name,
date = chapterItem.chapter.dateUpload
@@ -76,8 +107,8 @@ fun ChapterListDialog(
bookmark = chapterItem.chapter.bookmark,
selected = false,
downloadIndicatorEnabled = false,
downloadStateProvider = { Download.State.NOT_DOWNLOADED },
downloadProgressProvider = { 0 },
downloadStateProvider = { downloadState },
downloadProgressProvider = { progress },
chapterSwipeStartAction = LibraryPreferences.ChapterSwipeAction.ToggleBookmark,
chapterSwipeEndAction = LibraryPreferences.ChapterSwipeAction.ToggleBookmark,
onLongClick = { /*TODO*/ },
@@ -226,7 +226,7 @@ private fun ChapterText(
Text(
text = buildAnnotatedString {
if (downloaded) {
appendInlineContent(DownloadedIconContentId)
appendInlineContent(DOWNLOADED_ICON_ID)
append(' ')
}
append(name)
@@ -236,7 +236,7 @@ private fun ChapterText(
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.titleLarge,
inlineContent = persistentMapOf(
DownloadedIconContentId to InlineTextContent(
DOWNLOADED_ICON_ID to InlineTextContent(
Placeholder(
width = 22.sp,
height = 22.sp,
@@ -273,7 +273,7 @@ private val CardColor: CardColors
)
private val VerticalSpacerSize = 24.dp
private const val DownloadedIconContentId = "downloaded"
private const val DOWNLOADED_ICON_ID = "downloaded"
private fun previewChapter(name: String, scanlator: String, chapterNumber: Double) = Chapter.create().copy(
id = 0L,
@@ -7,19 +7,42 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import kotlin.time.Duration.Companion.milliseconds
@Stable
class DisplayRefreshHost {
internal var currentDisplayRefresh by mutableStateOf(false)
private val readerPreferences = Injekt.get<ReaderPreferences>()
internal val flashMillis = readerPreferences.flashDurationMillis()
internal val flashMode = readerPreferences.flashColor()
internal val flashIntervalPref = readerPreferences.flashPageInterval()
// Internal State for Flash
private var flashInterval = flashIntervalPref.get()
private var timesCalled = 0
fun flash() {
currentDisplayRefresh = true
if (timesCalled % flashInterval == 0) {
currentDisplayRefresh = true
}
timesCalled += 1
}
fun setInterval(interval: Int) {
flashInterval = interval
timesCalled = 0
}
}
@@ -29,18 +52,39 @@ fun DisplayRefreshHost(
modifier: Modifier = Modifier,
) {
val currentDisplayRefresh = hostState.currentDisplayRefresh
val refreshDuration by hostState.flashMillis.collectAsState()
val flashMode by hostState.flashMode.collectAsState()
val flashInterval by hostState.flashIntervalPref.collectAsState()
var currentColor by remember { mutableStateOf<Color?>(null) }
LaunchedEffect(currentDisplayRefresh) {
if (currentDisplayRefresh) {
delay(1.5.seconds)
hostState.currentDisplayRefresh = false
if (!currentDisplayRefresh) {
currentColor = null
return@LaunchedEffect
}
val refreshDurationHalf = refreshDuration.milliseconds / 2
currentColor = if (flashMode == ReaderPreferences.FlashColor.BLACK) {
Color.Black
} else {
Color.White
}
delay(refreshDurationHalf)
if (flashMode == ReaderPreferences.FlashColor.WHITE_BLACK) {
currentColor = Color.Black
}
delay(refreshDurationHalf)
hostState.currentDisplayRefresh = false
}
LaunchedEffect(flashInterval) {
hostState.setInterval(flashInterval)
}
Canvas(
modifier = modifier.fillMaxSize(),
) {
if (currentDisplayRefresh) {
drawRect(Color.Black)
}
currentColor?.let { drawRect(it) }
}
}
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.Photo
import androidx.compose.material.icons.outlined.Save
import androidx.compose.material.icons.outlined.Share
@@ -31,9 +32,9 @@ fun ReaderPageActionsDialog(
onDismissRequest: () -> Unit,
// SY -->
onSetAsCover: (useExtraPage: Boolean) -> Unit,
onShare: (useExtraPage: Boolean) -> Unit,
onShare: (copy: Boolean, useExtraPage: Boolean) -> Unit,
onSave: (useExtraPage: Boolean) -> Unit,
onShareCombined: () -> Unit,
onShareCombined: (copy: Boolean) -> Unit,
onSaveCombined: () -> Unit,
hasExtraPage: Boolean,
// SY <--
@@ -62,6 +63,25 @@ fun ReaderPageActionsDialog(
icon = Icons.Outlined.Photo,
onClick = { showSetCoverDialog = true },
)
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(
// SY -->
if (hasExtraPage) {
SYMR.strings.action_copy_first_page
} else {
MR.strings.action_copy_to_clipboard
},
// SY <--
),
icon = Icons.Outlined.ContentCopy,
onClick = {
// SY -->
onShare(true, false)
// SY <--
onDismissRequest()
},
)
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(
@@ -76,7 +96,7 @@ fun ReaderPageActionsDialog(
icon = Icons.Outlined.Share,
onClick = {
// SY -->
onShare(false)
onShare(false, false)
// SY <--
onDismissRequest()
},
@@ -114,12 +134,21 @@ fun ReaderPageActionsDialog(
showSetCoverDialog = true
},
)
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_copy_second_page),
icon = Icons.Outlined.ContentCopy,
onClick = {
onShare(true, true)
onDismissRequest()
},
)
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_share_second_page),
icon = Icons.Outlined.Share,
onClick = {
onShare(true)
onShare(false, true)
onDismissRequest()
},
)
@@ -136,12 +165,21 @@ fun ReaderPageActionsDialog(
Row(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) {
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_copy_combined_page),
icon = Icons.Outlined.ContentCopy,
onClick = {
onShareCombined(true)
onDismissRequest()
},
)
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_share_combined_page),
icon = Icons.Outlined.Share,
onClick = {
onShareCombined()
onShareCombined(false)
onDismissRequest()
},
)
@@ -46,6 +46,7 @@ fun BottomReaderBar(
doublePages: Boolean,
onClickChapterList: () -> Unit,
onClickWebView: (() -> Unit)?,
onClickBrowser: (() -> Unit)?,
onClickShare: (() -> Unit)?,
onClickPageLayout: () -> Unit,
onClickShiftPage: () -> Unit,
@@ -78,6 +79,15 @@ fun BottomReaderBar(
}
}
if (ReaderBottomButton.Browser.isIn(enabledButtons) && onClickBrowser != null) {
IconButton(onClick = onClickBrowser) {
Icon(
imageVector = Icons.Outlined.Public,
contentDescription = stringResource(MR.strings.action_open_in_browser),
)
}
}
if (ReaderBottomButton.Share.isIn(enabledButtons) && onClickShare != null) {
IconButton(onClick = onClickShare) {
Icon(
@@ -63,7 +63,7 @@ fun ExhUtils(
modifier
.fillMaxWidth()
.background(backgroundColor),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
) {
AnimatedVisibility(visible = isVisible) {
Column {
@@ -84,7 +84,7 @@ fun ExhUtils(
) {
Column(
Modifier.weight(3f),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = stringResource(SYMR.strings.eh_autoscroll),
@@ -93,17 +93,17 @@ fun ExhUtils(
fontFamily = FontFamily.SansSerif,
style = MaterialTheme.typography.labelLarge,
modifier = Modifier.fillMaxWidth(0.75f),
textAlign = TextAlign.Center
textAlign = TextAlign.Center,
)
}
Column(
Modifier.weight(1f),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
) {
Switch(
checked = isAutoScroll,
onCheckedChange = null,
enabled = isAutoScrollEnabled
enabled = isAutoScrollEnabled,
)
}
}
@@ -114,7 +114,7 @@ fun ExhUtils(
) {
Column(
Modifier.weight(3f),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
) {
var autoScrollFrequencyState by remember {
mutableStateOf(autoScrollFrequency)
@@ -74,6 +74,7 @@ fun ReaderAppBars(
// bookmarked: Boolean,
// onToggleBookmarked: () -> Unit,
onOpenInWebView: (() -> Unit)?,
onOpenInBrowser: (() -> Unit)?,
onShare: (() -> Unit)?,
viewer: Viewer?,
@@ -83,7 +84,7 @@ fun ReaderAppBars(
enabledPrevious: Boolean,
currentPage: Int,
totalPages: Int,
onSliderValueChange: (Int) -> Unit,
onPageIndexChange: (Int) -> Unit,
readingMode: ReadingMode,
onClickReadingMode: () -> Unit,
@@ -153,7 +154,7 @@ fun ReaderAppBars(
enabledPrevious = enabledPrevious,
currentPage = currentPage,
totalPages = totalPages,
onSliderValueChange = onSliderValueChange,
onPageIndexChange = onPageIndexChange,
isVerticalSlider = true,
currentPageText = currentPageText,
)
@@ -181,7 +182,7 @@ fun ReaderAppBars(
enabledPrevious = enabledPrevious,
currentPage = currentPage,
totalPages = totalPages,
onSliderValueChange = onSliderValueChange,
onPageIndexChange = onPageIndexChange,
isVerticalSlider = true,
currentPageText = currentPageText,
)
@@ -284,7 +285,7 @@ fun ReaderAppBars(
enabledPrevious = enabledPrevious,
currentPage = currentPage,
totalPages = totalPages,
onSliderValueChange = onSliderValueChange,
onPageIndexChange = onPageIndexChange,
isVerticalSlider = false,
currentPageText = currentPageText,
)
@@ -308,6 +309,7 @@ fun ReaderAppBars(
doublePages = doublePages,
onClickChapterList = onClickChapterList,
onClickWebView = onOpenInWebView,
onClickBrowser = onOpenInBrowser,
onClickShare = onShare,
onClickPageLayout = onClickPageLayout,
onClickShiftPage = onClickShiftPage,
@@ -18,14 +18,15 @@ import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -36,13 +37,15 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.theme.TachiyomiPreviewTheme
import eu.kanade.presentation.util.isTabletUi
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.Slider
import tachiyomi.presentation.core.i18n.stringResource
import kotlin.math.roundToInt
@Composable
fun ChapterNavigator(
@@ -57,7 +60,7 @@ fun ChapterNavigator(
currentPageText: String,
// SY <--
totalPages: Int,
onSliderValueChange: (Int) -> Unit,
onPageIndexChange: (Int) -> Unit,
) {
// SY -->
if (isVerticalSlider) {
@@ -69,13 +72,13 @@ fun ChapterNavigator(
currentPage = currentPage,
currentPageText = currentPageText,
totalPages = totalPages,
onSliderValueChange = onSliderValueChange,
onPageIndexChange = onPageIndexChange,
)
return
}
// SY <--
val isTabletUi = isTabletUi()
val horizontalPadding = if (isTabletUi) 24.dp else 16.dp
val horizontalPadding = if (isTabletUi) 24.dp else 8.dp
val layoutDirection = if (isRtl) LayoutDirection.Rtl else LayoutDirection.Ltr
val haptic = LocalHapticFeedback.current
@@ -134,11 +137,11 @@ fun ChapterNavigator(
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp),
value = currentPage.toFloat(),
valueRange = 1f..totalPages.toFloat(),
steps = totalPages - 2,
onValueChange = {
onSliderValueChange(it.roundToInt() - 1)
value = currentPage,
valueRange = 1..totalPages,
onValueChange = f@{
if (it == currentPage) return@f
onPageIndexChange(it - 1)
},
interactionSource = interactionSource,
)
@@ -177,10 +180,10 @@ fun ChapterNavigatorVert(
currentPageText: String,
// SY <--
totalPages: Int,
onSliderValueChange: (Int) -> Unit,
onPageIndexChange: (Int) -> Unit,
) {
val isTabletUi = isTabletUi()
val verticalPadding = if (isTabletUi) 24.dp else 16.dp
val verticalPadding = if (isTabletUi) 24.dp else 8.dp
val haptic = LocalHapticFeedback.current
@@ -252,11 +255,11 @@ fun ChapterNavigatorVert(
}
}
.weight(1f),
value = currentPage.toFloat(),
valueRange = 1f..totalPages.toFloat(),
steps = totalPages,
onValueChange = {
onSliderValueChange(it.roundToInt() - 1)
value = currentPage,
valueRange = 1..totalPages,
onValueChange = f@{
if (it == currentPage) return@f
onPageIndexChange(it - 1)
},
interactionSource = interactionSource,
)
@@ -280,3 +283,25 @@ fun ChapterNavigatorVert(
}
}
}
@Preview
@Composable
private fun ChapterNavigatorPreview() {
var currentPage by remember { mutableIntStateOf(1) }
TachiyomiPreviewTheme {
ChapterNavigator(
isRtl = false,
onNextChapter = {},
enabledNext = true,
onPreviousChapter = {},
enabledPrevious = true,
currentPage = currentPage,
totalPages = 10,
onPageIndexChange = { currentPage = (it + 1) },
// SY -->
currentPageText = "1",
isVerticalSlider = false,
// SY <--
)
}
}
@@ -5,11 +5,14 @@ import androidx.compose.material3.FilterChip
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.SettingsChipRow
import tachiyomi.presentation.core.components.SliderItem
import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
@@ -20,9 +23,27 @@ private val themes = listOf(
MR.strings.automatic_background to 3,
)
private val flashColors = listOf(
MR.strings.pref_flash_style_black to ReaderPreferences.FlashColor.BLACK,
MR.strings.pref_flash_style_white to ReaderPreferences.FlashColor.WHITE,
MR.strings.pref_flash_style_white_black to ReaderPreferences.FlashColor.WHITE_BLACK,
)
@Composable
internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
val readerTheme by screenModel.preferences.readerTheme().collectAsState()
val flashPageState by screenModel.preferences.flashOnPageChange().collectAsState()
val flashMillisPref = screenModel.preferences.flashDurationMillis()
val flashMillis by flashMillisPref.collectAsState()
val flashIntervalPref = screenModel.preferences.flashPageInterval()
val flashInterval by flashIntervalPref.collectAsState()
val flashColorPref = screenModel.preferences.flashColor()
val flashColor by flashColorPref.collectAsState()
SettingsChipRow(MR.strings.pref_reader_theme) {
themes.map { (labelRes, value) ->
FilterChip(
@@ -95,6 +116,35 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
label = stringResource(MR.strings.pref_flash_page),
pref = screenModel.preferences.flashOnPageChange(),
)
if (flashPageState) {
SliderItem(
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
label = stringResource(MR.strings.pref_flash_duration),
valueText = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
onChange = { flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION) },
min = 1,
max = 15,
)
SliderItem(
value = flashInterval,
label = stringResource(MR.strings.pref_flash_page_interval),
valueText = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
onChange = {
flashIntervalPref.set(it)
},
min = 1,
max = 10,
)
SettingsChipRow(MR.strings.pref_flash_with) {
flashColors.map { (labelRes, value) ->
FilterChip(
selected = flashColor == value,
onClick = { flashColorPref.set(value) },
label = { Text(stringResource(labelRes)) },
)
}
}
}
// SY -->
CheckboxItem(
@@ -19,8 +19,8 @@ internal object NordColorScheme : BaseColorScheme() {
inversePrimary = Color(0xFF397E91),
secondary = Color(0xFF81A1C1), // Unread badge
onSecondary = Color(0xFF2E3440), // Unread badge text
secondaryContainer = Color(0xFF81A1C1), // Navigation bar selector pill & progress indicator (remaining)
onSecondaryContainer = Color(0xFF2E3440), // Navigation bar selector icon
secondaryContainer = Color(0xFF506275), // Navigation bar selector pill & progress indicator (remaining)
onSecondaryContainer = Color(0xFF88C0D0), // Navigation bar selector icon
tertiary = Color(0xFF5E81AC), // Downloaded badge
onTertiary = Color(0xFF000000), // Downloaded badge text
tertiaryContainer = Color(0xFF5E81AC),
@@ -54,7 +54,7 @@ internal object NordColorScheme : BaseColorScheme() {
inversePrimary = Color(0xFF8CA8CD),
secondary = Color(0xFF81A1C1), // Unread badge
onSecondary = Color(0xFF2E3440), // Unread badge text
secondaryContainer = Color(0xFF81A1C1), // Navigation bar selector pill & progress indicator (remaining)
secondaryContainer = Color(0xFF91B4D7), // Navigation bar selector pill & progress indicator (remaining)
onSecondaryContainer = Color(0xFF2E3440), // Navigation bar selector icon
tertiary = Color(0xFF88C0D0), // Downloaded badge
onTertiary = Color(0xFF2E3440), // Downloaded badge text
@@ -38,7 +38,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
@@ -58,8 +57,6 @@ import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import java.time.format.DateTimeFormatter
private const val UnsetStatusTextAlpha = 0.5F
@Composable
fun TrackInfoDialogHome(
trackItems: List<TrackItem>,
@@ -72,6 +69,7 @@ fun TrackInfoDialogHome(
onNewSearch: (TrackItem) -> Unit,
onOpenInBrowser: (TrackItem) -> Unit,
onRemoved: (TrackItem) -> Unit,
onCopyLink: (TrackItem) -> Unit,
) {
Column(
modifier = Modifier
@@ -116,6 +114,7 @@ fun TrackInfoDialogHome(
onNewSearch = { onNewSearch(item) },
onOpenInBrowser = { onOpenInBrowser(item) },
onRemoved = { onRemoved(item) },
onCopyLink = { onCopyLink(item) },
)
} else {
TrackInfoItemEmpty(
@@ -144,6 +143,7 @@ private fun TrackInfoItem(
onNewSearch: () -> Unit,
onOpenInBrowser: () -> Unit,
onRemoved: () -> Unit,
onCopyLink: () -> Unit,
) {
val context = LocalContext.current
Column {
@@ -153,6 +153,7 @@ private fun TrackInfoItem(
TrackLogoIcon(
tracker = tracker,
onClick = onOpenInBrowser,
onLongClick = onCopyLink,
)
Box(
modifier = Modifier
@@ -179,6 +180,7 @@ private fun TrackInfoItem(
TrackInfoItemMenu(
onOpenInBrowser = onOpenInBrowser,
onRemoved = onRemoved,
onCopyLink = onCopyLink,
)
}
@@ -206,10 +208,9 @@ private fun TrackInfoItem(
if (onScoreClick != null) {
VerticalDivider()
TrackDetailsItem(
modifier = Modifier
.weight(1f)
.alpha(if (score == null) UnsetStatusTextAlpha else 1f),
text = score ?: stringResource(MR.strings.score),
modifier = Modifier.weight(1f),
text = score,
placeholder = stringResource(MR.strings.score),
onClick = onScoreClick,
)
}
@@ -238,6 +239,8 @@ private fun TrackInfoItem(
}
}
private const val UNSET_TEXT_ALPHA = 0.5F
@Composable
private fun TrackDetailsItem(
text: String?,
@@ -258,7 +261,7 @@ private fun TrackDetailsItem(
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (text == null) UnsetStatusTextAlpha else 1f),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (text == null) UNSET_TEXT_ALPHA else 1f),
)
}
}
@@ -287,6 +290,7 @@ private fun TrackInfoItemEmpty(
private fun TrackInfoItemMenu(
onOpenInBrowser: () -> Unit,
onRemoved: () -> Unit,
onCopyLink: () -> Unit,
) {
var expanded by remember { mutableStateOf(false) }
Box(modifier = Modifier.wrapContentSize(Alignment.TopStart)) {
@@ -307,6 +311,13 @@ private fun TrackInfoItemMenu(
expanded = false
},
)
DropdownMenuItem(
text = { Text(stringResource(MR.strings.action_copy_link)) },
onClick = {
onCopyLink()
expanded = false
},
)
DropdownMenuItem(
text = { Text(stringResource(MR.strings.action_remove)) },
onClick = {

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