Compare commits

...

512 Commits

Author SHA1 Message Date
c550a81598 Update shizuku.version to v13.1.0 2024-10-22 03:18:35 +06:00
0be36a10c3 Update dependency com.google.firebase:firebase-bom to v33.5.0 (#1352) 2024-10-21 19:53:17 +00:00
e16c3953c7 Update dependency org.junit.jupiter:junit-jupiter to v5.11.3 (#1351) 2024-10-22 01:49:40 +06:00
f3a2f566c8 Pass uncaught exception to default handler in GlobalExceptionHandler
Fixes #1347
2024-10-19 22:51:01 +06:00
15e3f28aa3 Rework Firebase setup
Fixes #1332
Closes #1339
2024-10-19 21:22:04 +06:00
3bf70b230f Address deprecation, suggestion and spotless 2024-10-19 20:19:06 +06:00
eb3bea8150 Revert "Tweak Preference.collectAsState"
This reverts commit 3bddb55385.

Fixes #1341
2024-10-19 20:02:15 +06:00
5612ae0149 Update dependency androidx.compose:compose-bom to v2024.10.00 (#1338) 2024-10-19 20:00:56 +06:00
dbf6ad2ca7 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>
2024-10-19 20:00:30 +06:00
d2afbfe4ed Change "Invalidate downloads index" to "Reindex downloads" 2024-10-19 17:06:29 +06:00
337806d9e1 Update dependency androidx.annotation:annotation to v1.9.0 (#1336) 2024-10-19 16:19:39 +06:00
443f6e0ae5 Update dependency androidx.glance:glance-appwidget to v1.1.1 (#1335) 2024-10-19 16:19:07 +06:00
572ee2f02a Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.3 (#1334) 2024-10-19 16:18:38 +06:00
ba1343bed8 Update dependency androidx.activity:activity-compose to v1.9.3 (#1333) 2024-10-19 16:17:55 +06:00
9f3d5d13d4 [skip ci] Update i18n readme (#1328) 2024-10-15 19:14:52 +06:00
48166b9b52 Update dependency com.android.tools.build:gradle to v8.7.1 (#1326) 2024-10-15 05:02:45 +06:00
2e2c8d36c1 Make sure random library sort is at the bottom 2024-10-15 05:00:56 +06:00
788235feec Reorder reader menu overflow items 2024-10-15 03:57:58 +06:00
afa5002988 Cleanup .gitignore files 2024-10-15 03:39:48 +06:00
9503082d44 Fix PR build check 2024-10-15 02:13:37 +06:00
de36357da8 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>
2024-10-14 16:30:23 +00:00
eb6092bd0c Adjust expandable fab animation
Co-authored-by: p
2024-10-13 23:06:02 +06:00
32d2c2ac1b Refrain from running spotless on weblate files
Those are akin to generated files and are likely to not follow our formatting
2024-10-13 23:02:35 +06:00
4051f180a2 Run PR check when base strings are changed 2024-10-13 20:50:35 +06:00
3ed8a91c7b Fix EnhancedTracker not auto binding when adding manga to library (#1298) 2024-10-13 20:32:29 +06:00
87db3f90de Confirmation dialog when removing privately installed extensions (#1320)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-10-13 18:48:00 +06:00
0a4ad89b99 Update dependency me.zhanghai.android.libarchive:library to v1.1.3 (#1321) 2024-10-13 18:47:31 +06:00
a72db41bf1 Added random library sort (#1317)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-10-13 13:51:34 +06:00
6b2bba4e54 Add Quantity Badge to Upcoming Screen (#1250)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-10-12 17:51:34 +06:00
7c7af72f8c Add option to opt out of Analytics and Crashlytics (#1237) 2024-10-12 06:46:28 +06:00
c8bb78d91a Tweak profile compilation status output
Co-authored-by: p
2024-10-12 06:23:37 +06:00
2ba3f0612c Remove usage of deprecated accompanist SystemUiController
Co-authored-by: p
2024-10-12 06:22:34 +06:00
f84d9a08b4 ChapterNavigator: dispatch page change only when needed
Co-authored-by: p
2024-10-12 05:12:38 +06:00
37419cdc26 Bump compile sdk to 35
Co-authored-by: p
2024-10-12 05:11:58 +06:00
481cfedf08 Update resources exclusion rules
Co-authored-by: p
2024-10-12 05:11:16 +06:00
9b8ab6acc2 Adjust distinct checker in WidgetManager and run on default dispatcher
Co-authored-by: p
2024-10-12 05:09:51 +06:00
3bddb55385 Tweak Preference.collectAsState
Co-authored-by: p
2024-10-12 05:02:56 +06:00
2beb89d531 Cleanup LibraryScreenModel LibraryMap.applySort and some more 2024-10-12 05:00:56 +06:00
016f627fb0 Update kotlin monorepo to v2.0.21 (#1314) 2024-10-10 18:21:31 +06:00
44aab7a243 Retain remote last chapter read if it's higher than the local one for EnhancedTracker (#1301) 2024-10-10 18:15:06 +06:00
a2dc88965b Update dependency io.mockk:mockk to v1.13.13 (#1313) 2024-10-09 21:42:16 +06:00
aa998071a1 Update renovate configuration
- Remove package rule for "dev.chrisbanes.compose:compose-bom"
- Disable semantic commits
2024-10-09 03:31:25 +06:00
8113b77f1e fix(deps): update dependency io.coil-kt.coil3:coil-bom to v3.0.0-rc01 (#1308) 2024-10-08 19:57:20 +06:00
6adfa4fd0f chore(deps): update actions/checkout action to v4.2.1 (#1304) 2024-10-08 19:46:40 +06:00
76e0aba70c Fix AniList ALSearchItem.status nullibility (#1297) 2024-10-06 04:09:49 +06:00
f7fbc93833 fix(deps): update dependency androidx.compose:compose-bom to v2024.09.03 (#1288) 2024-10-05 06:16:01 +06:00
85ee9c6686 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.11.2 (#1294) 2024-10-05 06:13:10 +06:00
c72c07f355 fix(deps): update dependency androidx.profileinstaller:profileinstaller to v1.4.1 (#1289) 2024-10-05 06:11:51 +06:00
6984e0465b fix(deps): update dependency androidx.benchmark:benchmark-macro-junit4 to v1.3.2 (#1287) 2024-10-05 06:11:30 +06:00
3ca989eae8 fix(deps): update dependency com.google.firebase:firebase-bom to v33.4.0 (#1285) 2024-10-05 06:10:03 +06:00
cca33481dd fix(deps): update dependency com.android.tools.build:gradle to v8.7.0 (#1284) 2024-10-02 03:26:28 +06:00
f7c8f1801e 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>
2024-09-28 06:36:10 +06:00
112b68b782 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>
2024-09-28 06:16:34 +06:00
2dd02b73d6 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>
2024-09-26 02:42:04 +06:00
369df527b2 chore(deps): update actions/checkout action to v4.2.0 (#1266)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-26 02:41:54 +06:00
d04eeface9 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>
2024-09-25 01:22:43 +06:00
dde942df4e chore(deps): update actions/setup-java action to v4.4.0 (#1259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-25 01:22:21 +06:00
380787a310 fix(deps): update dependency androidx.profileinstaller:profileinstaller to v1.4.0 (#1242)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 13:18:53 +06:00
418ba30265 fix(deps): update lifecycle.version to v2.8.6 (#1241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 13:18:20 +06:00
b3867dd63c 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>
2024-09-20 13:16:17 +06:00
6dd93d70cc fix(deps): update serialization.version to v1.7.3 (#1246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-20 12:38:22 +06:00
2276abbb23 Change casing for Extention Repos String (#1248) 2024-09-20 12:37:22 +06:00
be671b42ce Move firebase permission removal to standard flavor
And disable some more stuff
2024-09-18 17:37:33 +06:00
0042cb6582 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>
2024-09-18 15:35:47 +06:00
1e570bc965 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>
2024-09-17 14:48:00 +06:00
9cc7d42dd9 Re-enable fetching chapters list for entries with licenced status (#1230)
Enable Licensed
2024-09-17 14:47:04 +06:00
f5c6d2e1a6 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.
2024-09-17 14:46:37 +06:00
339dc33f58 Fix WheelPicker Manual Input (#1209)
* Fix WheelPicker Manual Input

* Lambda

* inline

* Update WheelPicker.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-09-14 14:43:03 +00:00
223af5508f Fix: wrong calculation of nextUpdate when setting custom fetchInterval (#1206) 2024-09-14 19:58:24 +06:00
d42f776c5c 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>
2024-09-14 19:57:58 +06:00
5c0dc3e05a 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>
2024-09-14 19:57:44 +06:00
bebf80dfae 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>
2024-09-14 19:57:31 +06:00
86dd809f4d chore(deps): update gradle/actions action to v4.1.0 (#1219)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 19:57:14 +06:00
1ff88dd927 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>
2024-09-14 19:56:58 +06:00
be5d467955 chore(deps): update actions/setup-java action to v4.3.0 (#1212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-14 19:56:47 +06:00
fcb01b5bcf chore(deps): update dependency gradle to v8.10.1 (#1211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-09 17:29:31 +06:00
844dae1a4d 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>
2024-09-09 17:29:12 +06:00
83fd4746ed Use new library for injekt with inorichi patch 2024-09-08 20:09:45 +06:00
c8ad6cdf31 Show toast for app restart when User-Agent is changed (#1204) 2024-09-07 14:15:22 +06:00
fbcc48fefc Bump NDK version (#1203) 2024-09-07 14:14:59 +06:00
6f422745ba Reduce ChapterNavigator horizontal padding on small ui (#1202)
Co-authored-by: p
2024-09-07 14:14:42 +06:00
bec549cc44 Use TextFieldState in BasicTextField where applicable (#1201)
Co-authored-by: p
2024-09-07 08:11:14 +00:00
c4f235ae07 Use uy.kohesive.injekt instead of com.github.inorichi.injekt (#1205) 2024-09-07 08:01:49 +00:00
8fd1239bea spotlessApply my beloved (#1196) 2024-09-05 13:03:24 +00:00
b56a97bb8e Ignore "intent://" urls on webview (#1193)
ignore intent urls
2024-09-05 16:11:09 +06:00
52036e5664 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>
2024-09-05 16:08:40 +06:00
29a74509a4 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>
2024-09-05 16:08:27 +06:00
0e956cbb51 fix(deps): update lifecycle.version to v2.8.5 (#1190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-05 16:08:06 +06:00
2baffa62ca Switch to stable compose 2024-09-05 16:07:08 +06:00
bd7b354198 Move archive related code to :core:archive 2024-09-05 16:00:46 +06:00
70c1a842b2 Rename LocalesConfigPlugin file to LocalesConfigTask 2024-09-05 14:17:18 +06:00
001249a89d 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.
2024-09-05 10:56:58 +06:00
c4d2fffb12 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>
2024-09-04 16:20:22 +06:00
f22767d863 Fix mishap in 02af9b1acf 2024-09-03 17:32:19 +06:00
02af9b1acf Remove more unnecessary permissions from Firebase dependency 2024-09-03 17:22:39 +06:00
3c611b95fb Add crashlytics to standard builds 2024-09-03 15:45:19 +06:00
fc1c804bfd Migrate some classpaths to gradle plugins 2024-09-03 14:09:12 +06:00
abfb72c89c 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>
2024-09-03 03:41:44 +06:00
9c1905ede7 Enable 'Split Tall Images' by default (#1185) 2024-09-03 01:46:28 +06:00
9f99f038f3 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
2024-09-03 01:46:08 +06:00
6c6ea84509 spotlessApply my beloved 2024-09-02 22:35:00 +06:00
4ee31bfea5 Add stable marker to Manga data class
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
2024-09-02 21:54:53 +06:00
03eb756ecb Collect MangaScreen state with lifecycle
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
2024-09-02 21:22:21 +06:00
a45eb5e528 PagerPageHolder: lazy init loading indicator
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
2024-09-02 21:13:52 +06:00
8f9a325895 Use feature flags in compose compiler plugin
And slight cleanup
2024-08-30 13:55:11 +06:00
f74071ab0a 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>
2024-08-30 11:37:56 +06:00
7fb3ef48e4 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>
2024-08-30 11:37:38 +06:00
1837faa573 fix(deps): update serialization.version to v1.7.2 (#1173)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-30 11:37:22 +06:00
518abf032c Remove legacy broken source and history backup 2024-08-30 11:36:34 +06:00
7ca64a67c5 Hide keyboard when a Tracker SearchResultItem is clicked (#1168)
* Hide keyboard on select

* Code Review Suggestion
2024-08-27 18:26:55 +06:00
d26c010e57 chore(deps): update gradle/actions action to v4.0.1 (#1165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-27 18:02:08 +06:00
607e56a4ec 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>
2024-08-26 23:08:39 +06:00
952a98c180 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>
2024-08-26 19:31:02 +06:00
45628b14db Add confirmation when adding repo via URI (#1158)
* Add confirmation when adding repo via URI

* Blank lines

* Suggestions

* Reverting Changes

* Removing Unused Imports
2024-08-25 22:07:14 +06:00
5dc6569a68 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
2024-08-25 19:47:25 +06:00
fba9bacdc1 fix(deps): update aboutlib.version to v11.2.3 (#1151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-23 22:41:29 +06:00
ca968f162e 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>
2024-08-23 15:43:46 +06:00
379d587826 fix(deps): update moko to v0.24.2 (#1148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-23 13:08:49 +06:00
034ec4cb12 chore(deps): update kotlin monorepo to v2.0.20 (#1144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-23 07:23:52 +06:00
2481767532 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.08.00-alpha02 (#1143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-23 07:23:42 +06:00
ab2b734d49 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>
2024-08-23 07:22:55 +06:00
aac4d6e548 Add PR or commit refs to CHANGELOG.md (#1117)
* [skip ci] Add PR or commit refs to CHANGELOG.md

* [skip ci] Update CHANGELOG.md

* [skip ci] Make usernames, PRs, hashes clickable

GFM autolinking for those is not applied to all Markdown documents.

* Change commit style

* [skip ci] Add ref to #1057

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-08-22 04:36:43 +06:00
08ae51ea8c 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>
2024-08-22 00:27:56 +06:00
4387ae5ff3 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
2024-08-20 02:32:52 +06:00
d6252ab770 Address spotless lint errors (#1138)
* Add spotless (with ktlint)

* Run spotlessApply

* screaming case screaming case screaming case

* Update PagerViewerAdapter.kt

* Update ReaderTransitionView.kt
2024-08-19 18:11:39 +06:00
5ae8095ef1 Add spotless (with ktlint) (#1136) 2024-08-19 18:11:14 +06:00
ac41bffdc9 Generate locales_config.xml in build dir 2024-08-19 16:52:23 +06:00
777ae2461e Remove detekt (#1130)
Annoying. More annoying in this project.
2024-08-19 12:51:37 +06:00
b2f1719c50 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>
2024-08-19 10:59:11 +06:00
3f050a83dd chore(deps): update dependency gradle to v8.10 (#1122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 20:18:25 +06:00
6f4e3f776f 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>
2024-08-14 20:16:39 +06:00
1c47a6b9b3 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.
2024-08-13 22:03:10 +06:00
f4348df870 Remove WebViewClientCompat 2024-08-13 13:42:14 +06:00
9a34ace09c Sync compose theme with MDC theme 2024-08-13 12:42:32 +06:00
124a787cda Update CHANGELOG.md 2024-08-12 23:51:56 +06:00
b404a71e26 Create CHANGELOG.md 2024-08-12 23:34:46 +06:00
be124ebe86 Fix some migrations never running (#1114)
Both `SetupBackupCreateMigration` and `SetupLibraryUpdateMigration` were
trying to get the `App` class from Injekt which is never provided via
the `AppModule`. Using `Application` instead works since the
`workManager` property used by the respective `setupTask` functions is
an extension property on `Context`.

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-08-12 05:36:34 +06:00
fdb96179c6 Handle Android SDK 35 API collision 2024-08-12 05:22:56 +06:00
c5994e057b Add an "open in browser" button to reader menu (#1110)
* Add an "open in browser" button to reader menu

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

* fixup! Add an "open in browser" button to reader menu

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

---------

Signed-off-by: Catting <5874051+mm12@users.noreply.github.com>
2024-08-12 03:52:47 +06:00
3f1d28c383 Fix UI freeze after migration
Fixes #938
2024-08-12 03:21:17 +06:00
84b2164787 Add a button to select all scanlators
Resolves #943
Closes #1109
2024-08-12 02:51:13 +06:00
200d39e023 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>
2024-08-11 23:10:36 +06:00
b1b15a93ee 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>
2024-08-11 22:55:47 +06:00
97c81fadb4 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`.
2024-08-11 22:55:13 +06:00
9240eceedc Change Kitsu to kitsu.app domain (#1106)
cf. 244fdccca9
2024-08-11 22:40:28 +06:00
14ae57d78b 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>
2024-08-11 03:58:02 +06:00
4828c54245 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>
2024-08-09 09:51:28 +06:00
dca9bf1057 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.08.00-alpha01 (#1094)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-09 04:31:56 +06:00
e8b7c3e24b 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>
2024-08-09 04:29:35 +06:00
af77083660 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>
2024-08-09 04:23:36 +06:00
36b9caeea8 fix(deps): update dependency androidx.annotation:annotation to v1.8.2 (#1090)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-09 04:22:33 +06:00
fdc1423f3d chore(deps): update gradle/actions action to v4 (#1095)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-09 02:33:30 +06:00
8e40146f96 fix(deps): update paging.version to v3.3.2 (#1093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-09 01:44:48 +06:00
1c16fc79c2 ExpandableMangaDescription: Adjust size transform anim spec
Co-authored-by: ivan <12537387+ivaniskandar@users.noreply.github.com>
2024-08-07 14:30:39 +06:00
31263084ec 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>
2024-08-07 13:49:17 +06:00
2858ef835f Rename backup restore error log file 2024-08-07 12:02:49 +06:00
edb8201f74 chore(deps): update kotlin monorepo to v2.0.10 (#1085)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-06 20:41:28 +06:00
854474f85f Don't crash on ill-formed URLs (#1084) 2024-08-06 20:39:49 +06:00
04db46fe75 fix: drawScrollbar crash on list with 0 item but only sticky header (#1083) 2024-08-06 20:38:56 +06:00
3f6bd5f010 chore(deps): update actions/setup-java action to v4.2.2 (#1080)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-06 20:38:13 +06:00
a3dfd2efe6 Match extra layout space with scroll distance (#1076)
And increase recycler item view cache size.
2024-08-04 21:45:11 +06:00
de8ef6dad7 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
2024-07-31 20:39:41 +06:00
8160b47ff5 Bump default user agent string 2024-07-30 21:09:56 +06:00
c201b341a7 Cleanup backup/restore related code 2024-07-30 04:59:16 +06:00
56fb4f62a1 Fix library is backed up when disabled and make categories backup/restore independent 2024-07-30 04:47:57 +06:00
0af90999c8 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>
2024-07-27 02:59:59 +06:00
913ff22132 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
2024-07-27 01:01:32 +06:00
04aa5b36a5 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.07.00-alpha02 (#1051)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 19:23:23 +06:00
41e2dc7ae8 fix(deps): update paging.version to v3.3.1 (#1046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 22:00:41 +06:00
88efde8796 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>
2024-07-25 22:00:06 +06:00
b7849d7146 fix(deps): update lifecycle.version to v2.8.4 (#1045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 21:35:38 +06:00
602b58f364 fix(deps): update dependency androidx.annotation:annotation to v1.8.1 (#1043)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 01:15:21 +06:00
e48dbdbf23 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>
2024-07-25 01:14:44 +06:00
6ace423e18 chore(deps): update softprops/action-gh-release action to v2.0.8 (#1024)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-24 19:09:53 +06:00
51b68cd25f Remove obsolete workaround (#1021) 2024-07-24 19:09:29 +06:00
ca784cbe32 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>
2024-07-24 18:53:11 +06:00
4f61b2e4e8 fix(deps): update dependency io.mockk:mockk to v1.13.12 (#1016)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 16:19:27 +06:00
8c9d12a840 chore(deps): update gradle/actions action to v3.5.0 (#1018)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-16 16:19:14 +06:00
f63e950910 chore(deps): update dependency gradle to v8.9 (#1007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 06:04:57 +06:00
f3f2bd41c3 fix(deps): update dependency org.jsoup:jsoup to v1.18.1 (#999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 04:52:17 +06:00
14d687c5cd fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.07.00-alpha01 (#1002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 04:52:08 +06:00
e94c8dac94 chore(deps): update actions/dependency-review-action action to v4.3.4 (#1009)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 04:51:55 +06:00
7a2ca4bf4d 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>
2024-07-12 04:51:42 +06:00
4a7613d515 A Minor Milestone (#1000)
* Fixes README.md Alignment

* Adds parameter to both
2024-07-10 21:30:12 +06:00
e65634cb42 Bump coil version and some cleanup
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 01:24:32 +06:00
daa47e0493 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
2024-07-08 16:02:50 +06:00
cbcd8bd668 Fix login prompts despite being logged in to trackers in Manga screen 2024-07-08 09:20:58 +06:00
2092c81bad Observe tracker login state instead of fetching once (#987)
* Observe tracker login state instead of fetching once

* Review changes
2024-07-06 07:25:33 +06:00
5a61ca5535 Make global search "Has result" sticky
Closes #133
2024-07-03 06:00:04 +06:00
ddba71df37 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>
2024-07-02 18:08:33 +06:00
75b5d96601 Correct tako variable colours (#976) 2024-07-02 16:52:55 +06:00
77db8873f6 fix(deps): update lifecycle.version to v2.8.3 (#972)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-02 01:58:48 +06:00
bff6183cf3 Update image-decoder revision (#971) 2024-07-01 22:15:46 +06:00
e620665dda 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>
2024-06-30 19:57:29 +06:00
c0f9de88e7 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>
2024-06-30 01:44:17 +06:00
80cdebcdf4 fix(deps): update aboutlib.version to v11.2.2 (#965)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 23:26:00 +06:00
9e2f97eeb8 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>
2024-06-28 17:59:49 +06:00
e132cc405f Theme fixes (#963)
* Fix theme issue with download progress indicator

* Fix theme issue with download progress indicator + better contrast
2024-06-28 17:59:32 +06:00
2674b84974 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>
2024-06-27 11:50:30 +06:00
f34702d4fc 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>
2024-06-27 11:50:11 +06:00
7823966ddf 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>
2024-06-27 11:48:58 +06:00
2d41bf5589 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.06.00-alpha01 (#957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-27 03:42:32 +06:00
d8fe7d32ca fix(deps): update serialization.version to v1.7.1 (#951)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-27 03:30:34 +06:00
2f86f25d5b 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
2024-06-27 02:04:28 +06:00
239c38982c Refactor archive support with libarchive (#949)
* 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
2024-06-26 20:54:25 +06:00
36e40c0997 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>
2024-06-25 07:49:12 +06:00
40754659a9 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>
2024-06-25 07:05:44 +06:00
a41ea8a61d [skip ci] remove unused github workflow 2024-06-24 19:28:25 +06:00
5c249dd790 Upload build artifacts (#941)
To decode obfuscated stack traces and help debugging R8 issues.
2024-06-23 08:04:30 +06:00
e17f70f722 Cleanup in CommonMangaItem.kt
Closes #19

Co-authored-by: Roshan Varughese <40583749+Animeboynz@users.noreply.github.com>
2024-06-23 05:00:26 +06:00
e57638a49c 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
2024-06-23 04:05:44 +06:00
0ce1cf22cd Fix unexpected skips in strong skipping mode (#940) 2024-06-23 03:53:49 +06:00
4ed2062cab Update build_pull_request.yml paths-ignore 2024-06-23 03:40:17 +06:00
f6ec53cdde 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>
2024-06-23 03:35:12 +06:00
b37357f909 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>
2024-06-21 03:21:27 +06:00
f58a05e918 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>
2024-06-21 02:43:48 +06:00
cf02119da5 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>
2024-06-21 02:24:22 +06:00
5e2a3ee927 chore(deps): update softprops/action-gh-release action to v2.0.6 (#929)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-21 01:41:26 +06:00
3b8ed3059a chore(deps): update gradle/actions action to v3.4.2 (#924)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-18 05:08:07 +06:00
4182ae89a0 Fix R8 version configuration not working (#916)
This reverts commit f3226fb278.
2024-06-17 04:53:02 +06:00
f3226fb278 Update R8 to fix NoSuchMethodError crash (#914) 2024-06-16 14:48:02 +06:00
30a6e3a6a1 chore(deps): update gradle/actions action to v3.4.1 (#905)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 04:47:39 +06:00
2e78bceb30 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>
2024-06-14 05:06:11 +06:00
a5838387b1 chore(deps): update gradle/actions action to v3.4.0 (#902)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-14 05:05:57 +06:00
aa1714b2ac 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>
2024-06-13 03:34:04 +06:00
f696f209c6 Fix issue with creating and restoring backup
Fixes #881
2024-06-13 03:27:52 +06:00
9fa22f0b37 Migrate to gradle/actions/wrapper-validation (#892) 2024-06-13 02:45:55 +06:00
6d8cfd5f30 chore(deps): update actions/checkout action to v4.1.7 (#891)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-13 02:31:28 +06:00
af57e124f2 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>
2024-06-13 02:21:15 +06:00
8e8ee69bba 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>
2024-06-13 02:21:02 +06:00
e9d69a83fe 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>
2024-06-11 14:51:28 +06:00
6a80305d6c Fix chapter number parsing when number is after unwanted tag
Fixes #554

Co-authored-by: Naputt1 <94742489+Naputt1@users.noreply.github.com>
2024-06-08 07:07:47 +06:00
119bcbf8ed Check category order before restoring from backup
Closes #632

Co-authored-by: Cologler <10906962+Cologler@users.noreply.github.com>
2024-06-08 06:38:35 +06:00
87fe64468c 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>
2024-06-07 19:30:00 +06:00
bdce3c39f1 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>
2024-06-07 14:58:19 +06:00
15d999229f MangaChapterListItem: Don't use alpha modifier
Possibly fixes #822

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-06-07 04:31:42 +06:00
1edd55c981 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>
2024-06-07 04:26:25 +06:00
777a071f4a 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>
2024-06-07 04:23:27 +06:00
71b558cb34 fix(deps): update serialization.version to v1.7.0 (#870)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 03:58:55 +06:00
46003ec251 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>
2024-06-07 03:48:35 +06:00
e8fdfaad64 chore(deps): update actions/dependency-review-action action to v4.3.3 (#867)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 03:35:50 +06:00
1f7574bd4f 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>
2024-06-07 03:35:38 +06:00
da62c7a21a 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
2024-06-07 03:35:26 +06:00
0870cffba1 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>
2024-06-02 15:20:56 +06:00
8632ba85ee 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>
2024-06-02 01:25:58 +06:00
116579d38c chore(deps): update dependency gradle to v8.8 (#856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-02 01:23:39 +06:00
098f925519 fix(deps): update dependency androidx.test.ext:junit-ktx to v1.2.0-rc01 (#855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-02 01:23:31 +06:00
9f5db70572 fix(deps): update aboutlib.version to v11.2.1 (#846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 22:03:20 +06:00
1f286f1a35 fix(deps): update dependency com.google.firebase:firebase-analytics to v22.0.1 (#848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 22:03:10 +06:00
7ab7f5ac37 fix(deps): update dependency com.google.gms:google-services to v4.4.2 (#849)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 22:03:03 +06:00
e567250b17 fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.0-rc01 (#851)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 22:02:54 +06:00
095da924b9 fix(deps): update dependency androidx.appcompat:appcompat to v1.7.0 (#845)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-30 05:07:22 +06:00
b9da98b527 fix(deps): update lifecycle.version to v2.8.1 (#844)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-30 05:07:08 +06:00
af8696cb90 fix(deps): update paging.version to v3.3.0 (#810)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-27 02:05:53 +06:00
de5a64aa73 fix(deps): update dependency org.apache.commons:commons-compress to v1.26.2 (#826)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-27 02:05:40 +06:00
9b944092c7 fix(deps): update aboutlib.version to v11.2.0 (#823)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-27 02:05:26 +06:00
0cb1794a44 fix(deps): update dependency com.android.tools.build:gradle to v8.4.1 (#818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-22 13:45:53 +06:00
2f243fae11 chore(deps): update kotlin and compose compiler (#800)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:14:12 +06:00
d2e5c78074 fix(deps): update lifecycle.version to v2.8.0 (#809)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:12:27 +06:00
5912d6b08f fix(deps): update dependency androidx.annotation:annotation to v1.8.0 (#808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:12:16 +06:00
99b550ae0d fix(deps): update dependency io.mockk:mockk to v1.13.11 (#803)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:03:52 +06:00
8d187f7865 fix(deps): update dependency androidx.test.ext:junit-ktx to v1.2.0-beta01 (#801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:03:38 +06:00
653d5d3e25 fix(deps): update dependency com.google.android.material:material to v1.12.0 (#754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:03:05 +06:00
1dca9363a4 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.05.00-alpha02 (#802)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-18 23:02:46 +06:00
fffa6a462d Fix renovate config 2024-05-18 23:00:29 +06:00
ce497003e3 fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.0-beta01 (#797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-17 16:09:36 +06:00
84ea5166de chore(deps): update actions/checkout action to v4.1.6 (#796)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-17 16:09:21 +06:00
0392ef0d18 Update renovate config 2024-05-17 16:06:23 +06:00
16392adcbb Update themes to follow new compose update changes (#766)
* Update Green Apple theme

* Add some Green Apple theme comments

* Update Lavender theme

* Update Midnight Dusk theme

* Update Nord theme

* Update Strawberry Daiquiri theme

* Update Tako theme

* Update Teal & Turquoise theme

* Update Lavender secondaryContainer and onSecondaryContainer colour

* Update M.Dusk secondaryContainer and onSecondaryContainer colour

* Update Tako secondaryContainer and onSecondaryContainer colour

* Comments

* Update Tidal Wave theme

* Update Yin Yang theme

* Update Yotsuba theme

* Fix navbar tinted background on pure black

* Add surfaceContainer levels to Lavender theme

* Resolve detekt issues

* Add surfaceContainer levels to Midnight Dusk theme

* Add surfaceContainer levels to Nord theme

* Add surfaceContainer levels to Tako theme

* Add surfaceContainer levels to Teal & Turquoise theme

* Add surfaceContainer levels to Tidal Wave theme

* Add surfaceContainer levels to Yin Yang theme

* Add surfaceContainer levels to Yotsuba theme

* Add dark theme surfaceContainer levels to Yotsuba theme

* surfaceContainer tweaks to Yotsuba theme

* surfaceContainer tweaks to Strawberry Daiquiri theme

* surfaceContainer tweaks to Nord theme

* surfaceContainer tweaks to Lavender theme

* Update Tachiyomi theme

* Update Pure Black theme

* Resolve detekt issues

* Oopsie
2024-05-14 02:44:40 +06:00
f603db3f3f update r8 rules for MultipartBody.Builder in extensions (#783) 2024-05-11 15:15:02 +06:00
ab546e0884 fix(deps): update dependency org.jetbrains.kotlinx:kotlinx-coroutines-bom to v1.8.1 (#778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 20:25:59 +06:00
d3306e8cfe fix(deps): update dependency io.kotest:kotest-assertions-core to v5.9.0 (#774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 12:52:40 +06:00
aebb86794a chore(deps): update softprops/action-gh-release action to v2.0.5 (#773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 12:52:18 +06:00
9a62e4fba3 chore(deps): update actions/checkout action to v4.1.5 (#771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-10 12:52:05 +06:00
5955c9c311 Update project icon 2024-05-08 23:06:35 +06:00
fb9423028e Remove dependency on compose material 2 components 2024-05-07 15:53:58 +06:00
8e9396a9cf Fix tap control area shifting after zooming out (#767) 2024-05-07 15:13:43 +06:00
1df87eabf2 Use new SurfaceContainer color roles
Non-dynamic themes need to be updated

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-05-07 15:03:48 +06:00
ca7391bbf3 Fix search bar style 2024-05-07 15:03:32 +06:00
550f1197e8 Change keyboard type in extension repo dialog (#764) 2024-05-05 16:23:09 +06:00
dbcc4a7d71 Revert "Fix badge count getting cut off on tab title"
This reverts commit 263e467cde.
2024-05-05 03:31:50 +06:00
e473c7f09f Bump compose version
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-05-05 01:55:23 +06:00
263e467cde Fix badge count getting cut off on tab title
Fixes #335
2024-05-05 01:55:23 +06:00
7ec2108812 Massively improve findFile performance (#728)
* Massively improve findFile performance

* Update libs.versions.toml

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-05-04 22:40:41 +06:00
e55e5f6f64 Remove some legacy folder/file name lookup for download
Related to #705
2024-05-04 22:27:51 +06:00
28dca3b7b8 Address firebase ktx module deprecation 2024-05-04 16:31:08 +06:00
70cd688ac2 Trust extension by repo (#570) 2024-05-04 16:26:45 +06:00
21145144cd Fix some extension related issue and cleanups
- Extension being marked as not installed instead of untrusted after updating with private installer
- Extension update counter not updating due to extension being marked as untrusted
- Minimize `Key "extension-XXX-YYY" was already used` crash
2024-05-04 16:08:38 +06:00
134e4648a9 Revert "fix(deps): update dependency androidx.compose.compiler:compiler to v1.5.13 (#745)"
This reverts commit 4e5cbbc96b.
2024-05-04 13:33:12 +06:00
fa6dba6cc7 fix(deps): update leakcanary to v2.14 (#715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 19:34:33 +06:00
8a51d56c59 fix(deps): update dependency com.android.tools.build:gradle to v8.4.0 (#753)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 19:08:36 +06:00
47ee2b45a8 chore(deps): update actions/dependency-review-action action to v4.3.2 (#752)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:22:13 +06:00
a2f7d47a0a fix(deps): update dependency androidx.test.espresso:espresso-core to v3.6.0-alpha04 (#749)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:21:52 +06:00
4e5cbbc96b fix(deps): update dependency androidx.compose.compiler:compiler to v1.5.13 (#745)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:21:08 +06:00
b720f34267 fix(deps): update dependency androidx.core:core-ktx to v1.13.1 (#748)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:20:46 +06:00
c6a1412f18 fix(deps): update dependency androidx.test.ext:junit-ktx to v1.2.0-alpha04 (#751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:20:16 +06:00
6290cf222d fix(deps): update aboutlib.version to v11.1.4 (#744)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-03 14:19:59 +06:00
a3d438e2f5 Log app crash exceptions in dumped crash logs (#742) 2024-05-03 00:59:29 +06:00
w
80461d883f Update subsampling-scale-image-view (#687)
Update libs.versions.toml
2024-05-01 13:09:19 +06:00
c3e7bb12f4 Use Coil pipeline instead of SSIV for image decode (#692) 2024-05-01 13:07:30 +06:00
2ad98520aa Revert "fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.04.00-alpha02 (#714)"
This reverts commit f1ce205d00.
2024-04-26 19:04:49 +06:00
f1ce205d00 fix(deps): update dependency dev.chrisbanes.compose:compose-bom to v2024.04.00-alpha02 (#714)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 14:50:52 +06:00
5289830a84 chore(deps): update gradle/wrapper-validation-action action to v3.3.2 (#713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 14:50:41 +06:00
dd932e1362 chore(deps): update gradle/actions action to v3.3.2 (#711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 14:50:29 +06:00
e85ce6456a chore(deps): update actions/checkout action to v4.1.4 (#710)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-26 14:50:15 +06:00
9a3ffe2ea6 Add MyAnimeList issue autoclose (#703)
[skip ci] Add MyAnimeList issue autoclose

This rule is intended to automatically close issues that report
problems with linking MAL that would be solved with the standard
solution of updating & changing the default UA.

The RegEx might be too general, but there isn't any neat pattern in
the previously filed issues.
2024-04-23 11:38:16 +06:00
213effa169 fix(deps): update dependency androidx.compose.compiler:compiler to v1.5.12 (#685)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:54:26 +06:00
25570147a1 fix(deps): update dependency androidx.benchmark:benchmark-macro-junit4 to v1.2.4 (#684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:54:09 +06:00
e82a2f5f9f chore(deps): update gradle/wrapper-validation-action action to v3.3.1 (#683)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:53:55 +06:00
935c0c7e2e chore(deps): update gradle/actions action to v3.3.1 (#682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:53:35 +06:00
2ad462b4d8 fix(deps): update dependency androidx.activity:activity-compose to v1.9.0 (#689)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:53:19 +06:00
7fd8f65352 fix(deps): update dependency androidx.core:core-ktx to v1.13.0 (#690)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-20 10:52:56 +06:00
b152e3881b Use Okio instead of java.io for image processing (#691) 2024-04-20 10:52:40 +06:00
f27ca3b1b2 Use m3 ripple and clean up interactionSource usage (#675)
Also remove a leftover of scoped storage adaptation.
2024-04-17 13:21:24 +06:00
843daa5304 Update compose bom and fix renovate config for it (#674) 2024-04-17 13:21:09 +06:00
f080a4937e fix(deps): update dependency com.google.firebase:firebase-analytics-ktx to v21.6.2 (#656)
Update dependency com.google.firebase:firebase-analytics-ktx to v21.6.2

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 21:57:21 +06:00
8bba926891 chore(deps): update gradle/actions action to v3.3.0 (#659)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 21:56:30 +06:00
5378c4c5d6 chore(deps): update gradle/wrapper-validation-action action to v3 (#661)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 21:55:56 +06:00
c94d212ef4 chore(deps): update gradle/wrapper-validation-action action to v2.1.3 (#658)
Update gradle/wrapper-validation-action action to v2.1.3

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 13:21:30 +06:00
4c43a0ef66 Update aboutlib.version to v11.1.3 (#654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 12:57:35 +06:00
ea0fe2414e Update dependency com.android.tools.build:gradle to v8.3.2 (#655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 12:57:10 +06:00
015620711d Update gradle/actions action to v3.2.1 (#657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 12:56:45 +06:00
6d4267b3bb Merge branch 'release/v0.16.5' 2024-04-09 16:02:21 +06:00
2a01a2ac6b Release v0.16.5 2024-04-09 14:17:04 +06:00
9a6559b013 Remove unused imports 2024-04-09 14:17:04 +06:00
a7509b3a3c Fix build time zone in about screen
And slight cleanup
2024-04-09 14:17:04 +06:00
2755d1f35e chore(deps): update dependency gradle to v8.7 (#567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-09 14:17:04 +06:00
6a8a9c6bbf Address detekt issues 2024-04-09 14:17:04 +06:00
w
7862088b94 Update image-decoder, color management (#523)
* Update image-decoder, color management

* move display profile pref

* remove true color pref

* Move Display Profile settings to a new section

* Partially revert "remove true color pref"

This partially reverts commit e1a7581695.

* Tweak label

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-04-09 14:12:49 +06:00
35f8eda8c5 Switch to seconds for DATE_MODIFIED of saved pages (#552)
While most Android skins are seemingly able to handle the millisecond
format, the documentation technically specifies seconds. This seems to
be causing issues on Samsung devices using the Samsung Gallery app,
which renders the millisecond timestamps as if they were second ones,
causing the dates to be set at some point in the year 56189.

This change should fix that issue on Samsung devices and have no real
impact on the rest.
2024-04-09 14:04:22 +06:00
fa6fa1f53a Disable SerialVersionUIDInSerializableClass detekt rule 2024-04-09 14:04:21 +06:00
c348fac78f Fix crash in track date selection dialog
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-04-09 14:04:21 +06:00
ab06720966 Upgrade Compose 2024-04-09 13:23:43 +06:00
42ebf017e4 Fix some issues from 7ff95e2 (#415)
* Fixed extra header introduced in 7ff95e2

* Removed parentheses to make detekt happy

* Updated relative date display for dates in the future

* Small cleanup for header creation logic

* replaced "and" with "&&" for better formatting
2024-04-09 13:23:43 +06:00
3910ffdd9e Fix DelayedTrackingUpdateJob spam on update errors (#411)
* Fix DelayedTrackingUpdateJob spam on update errors

DelayedTrackingUpdateJob would start spamming when it encountered an
error (e.g. a tracker has an issue) and never stop.
This seems to stem from a circular dependency between the Job's
`doWork` and TrackChapter's `await`.

TrackChapter sets up a completely new instance of the
DelayedTrackingUpdateJob if any Exception was thrown during the track
update.

This causes the Job to get replaced (as per the WorkManager's set
ExistingWorkPolicy).

Because of this, the guard clause at the start of doWork would never
trigger, as all instances of the Job would report being the 0th try
(because they were completely new instances).

This simple fix introduces a boolean `isRetry` parameter to
TrackChapter's await method, which is set to `false` by default.
DelayedTrackingUpdateJob however sets this parameter to `true`, which
means TrackChapter won't try to set up the Job again.

* Rename isRetry parameter to setupJobOnFailure

This also inverts the logic, so true & false were swapped.
2024-04-09 13:23:43 +06:00
0bfacf5570 Tweak detekt config 2024-04-09 13:23:42 +06:00
1e28999e13 Revert a mishap in 7ff95e21ba 2024-04-09 13:23:42 +06:00
1ee54d74a4 Ignore detekt [LongParameterList] for composables 2024-04-09 13:23:42 +06:00
a1a52ae81a Refactor use of Java.util.date to Java.time.*, to fix localized date issues. (#402)
* Add support for localdate based relative times

* Update History Screen to use new localdate based relative times

* Update Updates Screen to use new localdate based relative times

* Cleaned up date util classes

* Updated build time display

* Code cleanup

* Fixed crash in settings

* Updated Preferences item

* Worker Info works

* Fixed Tracker date display

* Code changes to pass detekt
2024-04-09 13:23:42 +06:00
56e66e041d Revert "Update Scaffold fork (#10143)" + Cleanup
Causes delay of one frame before actual contentPadding is measured

This reverts commit ea15bc782a.

Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-04-08 17:12:56 +06:00
13656959ae MangaCoverFetcher: Small cleanups
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-04-08 17:12:56 +06:00
20e4cb26d6 Remove unused imports 2024-04-06 12:21:25 +06:00
e448e40406 Rework buildSrc and remove usage of subprojects 2024-04-06 12:18:10 +06:00
aed53d3bdc Fix build time zone in about screen
And slight cleanup
2024-04-06 11:41:39 +06:00
d77f2f429d fix(deps): update sqldelight to v2.0.2 (#544)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-06 09:47:44 +06:00
c3fd2df6f5 Disable mpp and agp compability warning 2024-04-06 08:39:32 +06:00
f5a41e9693 chore(deps): update gradle/actions action to v3.2.0 (#621)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 06:20:12 +06:00
34bf5c6f87 Translations update from Hosted Weblate (#609)
* Translated using Weblate (Greek)

Currently translated at 99.8% (793 of 794 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Persian)

Currently translated at 84.7% (673 of 794 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Greek)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Galician)

Currently translated at 95.9% (762 of 794 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Javanese)

Currently translated at 38.8% (7 of 18 strings)

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

* Translated using Weblate (Galician)

Currently translated at 96.5% (767 of 794 strings)

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

* Translated using Weblate (Galician)

Currently translated at 100.0% (18 of 18 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.7% (796 of 798 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.4% (794 of 798 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Czech)

Currently translated at 99.8% (797 of 798 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (18 of 18 strings)

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

* 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 (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Amharic)

Currently translated at 34.3% (276 of 803 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Belarusian)

Currently translated at 42.0% (338 of 803 strings)

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

* Translated using Weblate (Bulgarian)

Currently translated at 79.8% (641 of 803 strings)

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

* Translated using Weblate (Bengali)

Currently translated at 79.2% (636 of 803 strings)

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

* Translated using Weblate (Catalan)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Cebuano)

Currently translated at 55.0% (442 of 803 strings)

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

* Translated using Weblate (Czech)

Currently translated at 99.2% (797 of 803 strings)

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

* Translated using Weblate (Chuvash)

Currently translated at 74.5% (599 of 803 strings)

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

* Translated using Weblate (Danish)

Currently translated at 39.9% (321 of 803 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Greek)

Currently translated at 98.6% (792 of 803 strings)

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

* Translated using Weblate (Esperanto)

Currently translated at 64.2% (516 of 803 strings)

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

* 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 (Basque)

Currently translated at 74.4% (598 of 803 strings)

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

* Translated using Weblate (Persian)

Currently translated at 83.5% (671 of 803 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 84.0% (675 of 803 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (French)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Galician)

Currently translated at 95.2% (765 of 803 strings)

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

* Translated using Weblate (Hebrew)

Currently translated at 89.7% (721 of 803 strings)

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

* Translated using Weblate (Hindi)

Currently translated at 82.6% (664 of 803 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 98.7% (793 of 803 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 98.6% (792 of 803 strings)

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

* Translated using Weblate (Italian)

Currently translated at 99.3% (798 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Javanese)

Currently translated at 38.3% (308 of 803 strings)

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

* Translated using Weblate (Georgian)

Currently translated at 52.5% (422 of 803 strings)

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

* Translated using Weblate (Kazakh)

Currently translated at 86.1% (692 of 803 strings)

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

* Translated using Weblate (Khmer (Central))

Currently translated at 26.7% (215 of 803 strings)

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

* Translated using Weblate (Kannada)

Currently translated at 62.2% (500 of 803 strings)

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

* Translated using Weblate (Korean)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 84.9% (682 of 803 strings)

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

* Translated using Weblate (Latvian)

Currently translated at 93.3% (750 of 803 strings)

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

* Translated using Weblate (Marathi)

Currently translated at 26.6% (214 of 803 strings)

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

* Translated using Weblate (Malay)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 99.3% (798 of 803 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 92.9% (746 of 803 strings)

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

* Translated using Weblate (Norwegian Nynorsk)

Currently translated at 33.6% (270 of 803 strings)

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

* Translated using Weblate (Polish)

Currently translated at 98.6% (792 of 803 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.6% (792 of 803 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 88.6% (712 of 803 strings)

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

* Translated using Weblate (Romanian)

Currently translated at 97.8% (786 of 803 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Sanskrit)

Currently translated at 71.3% (573 of 803 strings)

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

* Translated using Weblate (Yakut)

Currently translated at 51.3% (412 of 803 strings)

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

* Translated using Weblate (Sardinian)

Currently translated at 93.3% (750 of 803 strings)

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

* Translated using Weblate (Kurdish (Southern))

Currently translated at 29.8% (240 of 803 strings)

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

* Translated using Weblate (Slovak)

Currently translated at 78.7% (632 of 803 strings)

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

* Translated using Weblate (Albanian)

Currently translated at 86.6% (696 of 803 strings)

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

* Translated using Weblate (Serbian)

Currently translated at 98.6% (792 of 803 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Telugu)

Currently translated at 24.5% (197 of 803 strings)

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

* Translated using Weblate (Thai)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 98.5% (791 of 803 strings)

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

* Translated using Weblate (Uzbek)

Currently translated at 44.4% (357 of 803 strings)

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

* Translated using Weblate (Vietnamese)

Currently translated at 96.3% (774 of 803 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (803 of 803 strings)

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

* Update translation files

Updated by "Remove blank strings" hook in Weblate.

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

---------

Co-authored-by: Syrodil Eventalious <giannis.yalanskyi@gmail.com>
Co-authored-by: NukeSource <dede48076@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Arash <ara.khoram95@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Mr. Fakezay <fakezaydev@gmail.com>
Co-authored-by: kevans <albapazpi@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: Matyáš Caras <matyas@caras.cafe>
Co-authored-by: Federico Pierantoni <federico.pieranton@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
2024-04-01 08:04:30 +06:00
6abaa47f5b Translations update from Hosted Weblate (#508)
* Translated using Weblate (Greek)

Currently translated at 99.8% (793 of 794 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Persian)

Currently translated at 84.7% (673 of 794 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Greek)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Galician)

Currently translated at 95.9% (762 of 794 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Javanese)

Currently translated at 38.8% (7 of 18 strings)

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

* Translated using Weblate (Galician)

Currently translated at 96.5% (767 of 794 strings)

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

* Translated using Weblate (Galician)

Currently translated at 100.0% (18 of 18 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (795 of 795 strings)

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

* Translated using Weblate (Russian)

Currently translated at 99.7% (796 of 798 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.4% (794 of 798 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Czech)

Currently translated at 99.8% (797 of 798 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (798 of 798 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (18 of 18 strings)

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

* 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 (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (803 of 803 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.7% (801 of 803 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (803 of 803 strings)

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

---------

Co-authored-by: Syrodil Eventalious <giannis.yalanskyi@gmail.com>
Co-authored-by: NukeSource <dede48076@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: Arash <ara.khoram95@gmail.com>
Co-authored-by: Pitpe11 <giorgos2550@gmail.com>
Co-authored-by: Mr. Fakezay <fakezaydev@gmail.com>
Co-authored-by: kevans <albapazpi@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: akir45 <akkn0708@gmail.com>
Co-authored-by: Matyáš Caras <matyas@caras.cafe>
Co-authored-by: Federico Pierantoni <federico.pieranton@gmail.com>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
2024-04-01 07:51:46 +06:00
c9fddf9e38 Moves upcoming requirement from existence to current day or later. (#606)
* Moves upcoming requirement from existence to current day or later.

* Suppress millis conversion warning
2024-03-31 13:49:06 +06:00
555d2f834f Add ProGuard rule to keep mihon namespace classes (#605)
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-31 05:35:12 +06:00
6b3423a12b Fix Migrator not doing work (#604) 2024-03-31 05:03:28 +06:00
7c6fd026a3 chore(deps): update actions/dependency-review-action action to v4.2.5 (#591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:52:47 +06:00
86fbd20665 fix(deps): update detekt to v1.23.6 (#595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:25:35 +06:00
8c8d65d3c7 fix(deps): update dependency io.github.kevinnzou:compose-webview to v0.33.6 (#594)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:25:28 +06:00
f1660beafc fix(deps): update aboutlib.version to v11.1.1 (#592)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 13:25:21 +06:00
72222ad86d New Feature: Introduce Upcoming page to Mihon (#420)
* Work in progress upcoming feature

* Checkpointing WIP upcoming feature

* Functional Upcoming Screen

* Rename UpdateCalendar to UpdateUpcoming

* Converted Strings to resources

* Cleanup

* Fixed detekt issues

* Removed Link icon per @AntsyLich's suggestion.

* Detekt

* Fixed Calendar display on wide form factor devices

* Added Key to upcoming lazycolumn

* Updated tablet mode UI to support two column view

* Updated header creation logic

* Updated header creation logic... again

* Moved stray string to resources

* Fixed PR Comments and query refactor

* Tweaks to query, refactored to flow, comments on calendar

* Switched to Date Formatter

* Cleaned up date formatter

* More Refactor work

* Updated Calendar to support localized week formats

* Fixed year format

* Refactored Header animation

* Moved upcoming FAQ

* Completed YearMonth Migration

* Replaced currentYearMonth with delegate

* Even more cleanup

* cleaned up alignment modifiers

* Click Handler and other refactors

* Removed Wrapped Content Height/Size/extra clips

* Huge Refactor for CalendarDay

* Another cleanup attempt

* Migrated to new mihon.feature.* module pattern

* changed access modifier

* A Bunch of changes from the next round of reviews

* Cleanups

* Cleanup 2

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-29 01:02:33 +06:00
0265c16eb2 Migrator improvements (#588) 2024-03-29 00:36:33 +06:00
666d6aa117 Rewrite Migrations (#577)
* Rewrite Migrations

* Fix Detekt errors

* Do migrations synchronous

* Filter and sort migrations

* Review changes

* Review changes 2

* Fix Detekt errors
2024-03-25 23:26:19 +06:00
6965e59a64 Fix mishap in e020ae5ed5 2024-03-24 05:54:27 +06:00
e020ae5ed5 Fix more TypeReference issues and cleanup 2024-03-24 05:16:31 +06:00
05071b4205 Fix extension repo crash with TypeReference issue (#574)
Fix by @AntsyLich.

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-24 04:21:19 +06:00
da20d00481 Fix repo name used for URL instead of baseUrl (#572)
* Fix repo name used for URL instead of baseUrl

This applies to both the item being shown in the screen as well as the
"copy to clipboard" button. Before, copying a repo url would return
"The Repo Name/index.json.min". This PR fixes that.

* Correct Misunderstanding

Passing the whole ExtensionRepo data class through now, using the name
for display purposes and the baseUrl for copying the URL.
2024-03-23 21:03:55 +06:00
8c437ceecf Refactor the ExtensionRepoService to use DTOs (#573)
* Refactor the ExtensionRepoService to use DTOs

Slightly refactored the `ExtensionRepoService` so it uses a DTO with
`parseAs` to avoid parsing the JSON response by hand.

The default Json instance Injekt provides here has
`ignoreUnknownKeys` enabled, so the `ExtensionRepoMetaDto` only
specifies the meta key of the response content.

The extension function `toExtensionRepo` allows for mapping the new
DTO to the `domain` `ExtensionRepo` data class.

* Implement feedback

- Removed SerialName of the ExtensionRepoMetaDto property and renamed
it `meta`, same as the incoming attribute.
- Added a more general catch clause that also logs the occurring
Exception

Detekt likes to complain about TooGenericExceptionCaught, hence the
Suppress annotation on the function.
2024-03-23 21:03:44 +06:00
9672ea8b1b Fix extension repo migration not triggering 2024-03-23 17:29:20 +06:00
ba9cfd867c Migrated from Accompanist Webview to KevinZou WebView (#569)
* Migrated from Accompanist Webview to KevinZou WebView to preempt deprecation

* Removed old webview from version library
2024-03-23 07:10:18 +06:00
4b4e468510 Grab extension repo detail from repo.json and include in DB (#506)
* WIP Extension Repo DB Support

* Wired in to extension screen, browse settings screen

* Detekt changes

* Ui tweaks and open in browser

* Migrate ExtensionRepos on Update

* Migration Cleanup

* Slight cleanup / error handling

* Update ExtensionRepo from Repo.json during extension search.
Added Manual refresh in extension repos page.

* Split repo fetching into separate API module, major refactor work

* Removed development strings

* Moved migration to #3

* Fixed rebase

* Detekt changes

* Added Replace Repository Dialog

* Cleanup, removed platform specific code, PR comments

* Removed extra function, reverted small change

* Detekt cleanup

* Apply suggestions from code review

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

* Fixed error introduced in cleanup

* Tweak for multiline when

* Moved getCount() to flow

* changed getCount to non-suspend, used property delegation

* Apply suggestions from code review

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

* Fixed formatting with updated comment string

* Big wave of PR comments, renaming/other tweaks

* onOpenWebsite changes

* onOpenWebsite changes

* trying to make single line

* Renamed ExtensionRepoApi.kt to ExtensionRepoService.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-23 04:58:35 +06:00
e75488f5d9 fix(deps): update aboutlib.version to v11 (major) (#473)
* fix(deps): update aboutlib.version to v11

* Fix build

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-23 02:00:24 +06:00
3838dbcf08 chore(deps): update dependency gradle to v8.7 (#567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 23:05:13 +06:00
b3ca097e5a chore(deps): update kotlin (#499)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 19:35:28 +06:00
70c2443e82 Add reference to compose compiler in compose.versions.toml so renovate can catch it 2024-03-22 19:24:41 +06:00
c0a888807b Rework Duplicate Dialog and Allow Migration (#492)
* (Mostly) Working Manga screen migration via duplicate dialog

* Fully working migrate from Browse Search

* Small tweaks for Antsy

* Update app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt

* Update app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-22 19:04:43 +06:00
34930920a5 Fix webtoon last visible item position calculation (#562)
Covers the case when image height > screen height.
2024-03-22 18:56:48 +06:00
6682b5dd39 fix(deps): update dependency com.google.firebase:firebase-analytics-ktx to v21.6.1 (#561)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 18:55:02 +06:00
3c5f4a317a chore(deps): update gradle/wrapper-validation-action action to v2.1.2 (#560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 18:54:50 +06:00
6a2bfd5e87 chore(deps): update actions/dependency-review-action action to v4.2.3 (#559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-22 18:54:38 +06:00
ef6cad58fe Fix recycled item's height being 0 in webtoon mode (#563)
Which will prevent the new image from being decoded until it's visible.
2024-03-22 18:52:01 +06:00
7e9340aa7f Address detekt issues 2024-03-22 18:43:36 +06:00
w
3f2c8e9ef6 Update image-decoder, color management (#523)
* Update image-decoder, color management

* move display profile pref

* remove true color pref

* Move Display Profile settings to a new section

* Partially revert "remove true color pref"

This partially reverts commit e1a7581695.

* Tweak label

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-21 13:20:29 +06:00
a29870c01e fix(deps): update dependency org.apache.commons:commons-compress to v1.26.1 (#502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 12:40:48 +06:00
583aa430ba fix(deps): update dependency com.android.tools.build:gradle to v8.3.1 (#543)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 11:37:36 +06:00
0ea0138a73 Switch to seconds for DATE_MODIFIED of saved pages (#552)
While most Android skins are seemingly able to handle the millisecond
format, the documentation technically specifies seconds. This seems to
be causing issues on Samsung devices using the Samsung Gallery app,
which renders the millisecond timestamps as if they were second ones,
causing the dates to be set at some point in the year 56189.

This change should fix that issue on Samsung devices and have no real
impact on the rest.
2024-03-21 11:37:17 +06:00
59bedb33ff Fix regression from coil3 migration
Fixes #495

Co-authored-by: jobobby04 <17078382+jobobby04@users.noreply.github.com>
2024-03-18 23:01:40 +06:00
ebee275110 fix(deps): update dependency io.kotest:kotest-assertions-core to v5.8.1 (#528)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-17 20:45:26 +06:00
015d9b3bd0 fix(deps): update dependency com.squareup.okio:okio to v3.9.0 (#529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-17 20:45:09 +06:00
f2ccfb0817 Typo in r0adkll/sign-android-release SHA 2024-03-17 20:25:51 +06:00
1b60c5f0f4 Check for dependency update every Friday 2024-03-17 20:22:08 +06:00
0a91b57f67 Use SHA for GitHub actions version 2024-03-17 20:21:05 +06:00
bcdf17fe27 Disable SerialVersionUIDInSerializableClass detekt rule 2024-03-17 19:44:23 +06:00
a08e03f5cb Fix multiple issues regarding sources loading too late 2024-03-17 19:44:22 +06:00
f087135876 Fix crash in track date selection dialog
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-14 03:28:48 +06:00
f66f52c244 Bump default user agent 2024-03-14 03:27:03 +06:00
0d6f426dbd Update dependency io.nlopez.compose.rules:detekt to v0.3.12 (#500)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 17:52:41 +06:00
edd7d0522c Translations update from Hosted Weblate (#445)
* Translated using Weblate (Esperanto)

Currently translated at 65.1% (517 of 794 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Croatian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Serbian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (794 of 794 strings)

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

* 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 (Croatian)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Serbian)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Filipino)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Russian)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (794 of 794 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (18 of 18 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 94.2% (748 of 794 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 94.4% (17 of 18 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (794 of 794 strings)

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

---------

Co-authored-by: Radoŝ Porka <animatorzPolski@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: David Katrinka <davidkatrinka1995@gmail.com>
Co-authored-by: gekka <1778962971@qq.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: Infy's Tagalog Translations <ced.paltep10@gmail.com>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
Co-authored-by: Dexroneum <Rozhenkov69@gmail.com>
Co-authored-by: TheKingTermux <achmadmaulana0233@gmail.com>
Co-authored-by: Tim Bolhoeve <bolhoevetim@gmail.com>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
2024-03-11 17:51:54 +06:00
4ae9dbe524 feat: db changes to accommodate new cross device syncing logic. (#450)
* feat: db changes to accommodate new syncing logic.

Using timestamp to sync is a bit skewed due to system clock etc and therefore there was a lot of issues with it such as removing a manga that shouldn't have been removed. Marking chapters as unread even though it was marked as a read. Hopefully by using versioning system it should eliminate those issues.

* chore: add new line.

* chore: remove isSyncing from Chapter/Manga model.

* chore: remove isSyncing leftover.

* chore: remove isSyncing.

* refactor: remove isSync guard.

Just use it directly to 1 now since we don't have the isSyncing field in Manga or Chapter.

* Lint and stuff

* Add missing ,

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-10 01:45:41 +06:00
402e579a69 Fix shizuku being buggy for multi user setups (#494)
* Fix #493

Fetch the current userid separately because shizuku always runs as the main user and would otherwise install and update for the main user

* Update app/src/main/java/eu/kanade/tachiyomi/extension/installer/ShizukuInstaller.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-03-10 00:48:43 +06:00
d0e64d3a66 Fix dual page split for local source (#485)
`InputStream.available()` is implementation-dependent, should never assume it will return the total number of bytes in the stream.
2024-03-09 21:09:06 +06:00
154f4d327c Update image-decoder (#466)
Use newer image-decoder lib

fixes crashing when trying to load corrupt images below 12 bytes in size
2024-03-09 21:08:57 +06:00
d8b9a9f593 Fix ChapterDownloadIndicator
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-04 02:04:33 +06:00
b7e091d5d0 Small cleanup 2024-03-04 02:04:33 +06:00
31e052ac15 Update dependency com.android.tools.build:gradle to v8.3.0 (#471)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-03 13:53:57 +06:00
60480686da Update dependency io.mockk:mockk to v1.13.10 (#470)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-03 13:53:47 +06:00
d6ba3c8249 Revert changes to gradle.properties 2024-03-02 20:25:38 +06:00
c56f4665ef detekt my beloved 2024-03-02 20:24:54 +06:00
b51a0a38bd Update dependency me.saket.swipe:swipe to v1.3.0 (#343)
* Update dependency me.saket.swipe:swipe to v1.3.0

* Update MangaChapterListItem.kt

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-02 20:11:03 +06:00
f72b6e4d7c Switch to Coil3
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-02 20:08:15 +06:00
84984ef7e1 Remove custom Pager
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-02 19:02:53 +06:00
9f48def1e2 Enable experimental Compose compiler optimization
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-02 19:00:27 +06:00
e83bfb0d35 ChapterDownloadIndicator: Remove composed modifier usage
Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com>
2024-03-02 18:41:59 +06:00
0301362430 Upgrade Compose 2024-03-02 18:41:59 +06:00
9d5978aca0 Address ZipFile deprecation warning 2024-03-02 18:27:19 +06:00
4bfc5e7b51 Made some changes to ComicInfo metadata (#459)
* Made some changes to ComicInfo metadata

The web field now contains a " " separated list of source and tracker urls.
The translator field will now use the source name if the scanlator field is empty.

* lint

* use already existing source instance

* made translator not nullable

* implemented requested changes

created new Mihon exclusive ComicInfo source field  and populated it with SourceName

reverted previous changes to translator field

* Update core-metadata/src/main/java/tachiyomi/core/metadata/comicinfo/ComicInfo.kt

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

* Update app/src/main/java/eu/kanade/domain/manga/model/Manga.kt

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

* Update app/src/main/java/eu/kanade/domain/manga/model/Manga.kt

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

* Update app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt

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

* Update app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-02-29 23:57:39 +06:00
5859a8bbf6 Revert "Update sqldelight to v2.0.1"
This reverts commit 1e40199b7d.
2024-02-27 15:22:40 +06:00
802a2c5c1e Update Kotlin (#422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:13:49 +06:00
c1c1746985 Update dependency io.coil-kt:coil-bom to v2.6.0 (#447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:13:36 +06:00
4fcbd80a8e Update dependency org.junit.jupiter:junit-jupiter to v5.10.2 (#419)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:13:08 +06:00
16969193c7 Update dependency com.google.firebase:firebase-analytics-ktx to v21.5.1 (#417)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:13:01 +06:00
55637ddfe1 Update dependency androidx.test.uiautomator:uiautomator to v2.3.0 (#416)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:12:51 +06:00
e50358dc4b Update detekt to v1.23.5 (#267)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 15:12:43 +06:00
1e40199b7d Update sqldelight to v2.0.1 2024-02-27 15:12:20 +06:00
410b918b77 Merge branch 'release/v0.16.4' 2024-02-27 00:11:15 +06:00
a4f5dfab1a Release v0.16.4 2024-02-26 22:19:23 +06:00
085147b15b Fix detekt issue 2024-02-26 22:19:23 +06:00
085ad8d446 Don't add custom User Agent for MAL
Closes #298
2024-02-26 22:08:11 +06:00
9254079957 Fix detekt issue 2024-02-26 21:54:24 +06:00
7974a1fc0c Don't add custom User Agent for MAL
Closes #298
2024-02-26 21:44:01 +06:00
1521c35941 Update dependency com.squareup.okio:okio to v3.8.0 (#423)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 18:19:22 +06:00
2247f6004a Update dependency org.apache.commons:commons-compress to v1.26.0 (#448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 18:18:24 +06:00
c15f3f2fd5 Allow disabling reader's zoom out (#302)
* Allow disabling reader's zoom out (#62)

* Renamed disable zoom out pref and string

* Zoom to default rate if the scale is inferior

* Fixed null value check and formatting

* Fixed detekt
2024-02-25 01:40:06 +06:00
21020e1797 Update dependency com.google.gms:google-services to v4.4.1 (#418)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 01:35:17 +06:00
7edecae57f Translations update from Hosted Weblate (#301)
* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chuvash)

Currently translated at 75.7% (601 of 793 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chuvash)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 97.3% (772 of 793 strings)

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

* Translated using Weblate (Hungarian)

Currently translated at 94.1% (16 of 17 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Romanian)

Currently translated at 99.3% (788 of 793 strings)

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

* Translated using Weblate (Romanian)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (French)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Esperanto)

Currently translated at 62.0% (492 of 793 strings)

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

* Translated using Weblate (Esperanto)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Esperanto)

Currently translated at 63.6% (505 of 793 strings)

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

---------

Co-authored-by: bapeey <90949336+bapeey@users.noreply.github.com>
Co-authored-by: Eji-san <ejierubani@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Swyter <swyterzone@gmail.com>
Co-authored-by: Radoŝ Porka <animatorzPolski@gmail.com>
Co-authored-by: Deniz <denizgezgin365@gmail.com>
Co-authored-by: Uzuki Shimamura <hzy980512@126.com>
Co-authored-by: sebastians17 <sebastians117.ss@gmail.com>
Co-authored-by: ɴᴇᴋᴏ <s99095lkjjim@gmail.com>
Co-authored-by: B4LiN7 <B4LiN7@users.noreply.hosted.weblate.org>
Co-authored-by: Saft Octavian <saftoctavian@gmail.com>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Naga <yz2000.pro@gmail.com>
2024-02-25 01:34:52 +06:00
07f963d5ae Fix some issues from 7ff95e2 (#415)
* Fixed extra header introduced in 7ff95e2

* Removed parentheses to make detekt happy

* Updated relative date display for dates in the future

* Small cleanup for header creation logic

* replaced "and" with "&&" for better formatting
2024-02-25 01:33:46 +06:00
ab02568ac6 [ExtensionLoader] Prioritize extension classpath over app classpath (#433) 2024-02-24 23:54:30 +06:00
617bf491ee Fix DelayedTrackingUpdateJob spam on update errors (#411)
* Fix DelayedTrackingUpdateJob spam on update errors

DelayedTrackingUpdateJob would start spamming when it encountered an
error (e.g. a tracker has an issue) and never stop.
This seems to stem from a circular dependency between the Job's
`doWork` and TrackChapter's `await`.

TrackChapter sets up a completely new instance of the
DelayedTrackingUpdateJob if any Exception was thrown during the track
update.

This causes the Job to get replaced (as per the WorkManager's set
ExistingWorkPolicy).

Because of this, the guard clause at the start of doWork would never
trigger, as all instances of the Job would report being the 0th try
(because they were completely new instances).

This simple fix introduces a boolean `isRetry` parameter to
TrackChapter's await method, which is set to `false` by default.
DelayedTrackingUpdateJob however sets this parameter to `true`, which
means TrackChapter won't try to set up the Job again.

* Rename isRetry parameter to setupJobOnFailure

This also inverts the logic, so true & false were swapped.
2024-02-19 00:57:50 +06:00
840b647b4b Address overridePendingTransition deprecation (#410)
This function is deprecated starting with API 34 "UpsideDownCake" and
should be replaced with `overrideActivityTransition`.
2024-02-17 21:26:47 +06:00
1b0bbb8440 Tweak detekt config 2024-02-17 04:25:41 +06:00
95d4df9ca8 Cleanup [BaseColorScheme.getColorScheme] 2024-02-17 04:07:06 +06:00
fb86c470f6 Update gradle.properties 2024-02-17 03:35:46 +06:00
5aec8f8018 Small cleanup in WorkerInfoScreen 2024-02-17 03:29:15 +06:00
e183cbb231 Revert a mishap in 7ff95e21ba 2024-02-17 03:28:48 +06:00
6bdb37be65 Ignore detekt [LongParameterList] for composables 2024-02-16 17:18:53 +06:00
7ff95e21ba Refactor use of Java.util.date to Java.time.*, to fix localized date issues. (#402)
* Add support for localdate based relative times

* Update History Screen to use new localdate based relative times

* Update Updates Screen to use new localdate based relative times

* Cleaned up date util classes

* Updated build time display

* Code cleanup

* Fixed crash in settings

* Updated Preferences item

* Worker Info works

* Fixed Tracker date display

* Code changes to pass detekt
2024-02-16 17:09:00 +06:00
96c236e5c3 Minor refactor of theming when expressions (#396)
* Minor refactor of theming when expressions

Avoids triggering detekt's CyclomaticComplexMethod warning because of
too many when branches, which would happen with one more theme being
added in these two locations.

In TachiyomiTheme, the Monet theme is separated because it requires
the current Compose context to function. The other themes do not and
are delegated to a Map.

* Implement requested changes

- moved themeResources out of the ThemingDelegate interface
- replaced single condition when with if expression
2024-02-15 02:35:16 +06:00
72f3756a3b Update dependency androidx.test.ext:junit-ktx to v1.2.0-alpha03 (#340)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:54:37 +06:00
0780385d2e Update dependency androidx.test.espresso:espresso-core to v3.6.0-alpha03 (#339)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:53:40 +06:00
31e9273b1f Update lifecycle.version to v2.7.0 (#268)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:53:30 +06:00
088e37b2d8 Update dependency com.github.requery:sqlite-android to v3.45.0 (#260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:53:22 +06:00
5b88f1bd94 Update dependency io.github.fornewid:material-motion-compose-core to v1.2.0 (#257)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:53:09 +06:00
18beb20aac Update dependency androidx.benchmark:benchmark-macro-junit4 to v1.2.3 (#255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:52:32 +06:00
d5d7065e75 [skip ci] Tweak README.md (#353)
* Center README license

* Clean up the drop-downs

* Change copyright modification location

* Add Bitmap repo
2024-02-07 13:54:37 +06:00
78271a54a4 [skip ci] Add Dependencies label to Renovate Dependencies (#354) 2024-02-07 03:18:04 +06:00
9bff20cb1a Update dependency gradle to v8.6 (#341)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-04 13:31:52 +06:00
2ccff8cdde Fix extracting ComicInfo.xml files in local source (#325) 2024-02-04 13:27:46 +06:00
0da7ad6f1a Don't copy archives to temp files when opening (#326) 2024-02-03 23:33:18 +06:00
170daf9fb2 Update workflow dependencies (#310)
* feat: updated build_pull_request actions version

* feat: updated build_push actions version

* feat: updated issue_moderator action version

* feat: updated deprecated arguments in build_pull_request

* feat: updated deprecated arguments in build_push

* feat: removed explicit declaration of gradle version
2024-02-02 02:20:28 +06:00
139663acfc Release v0.16.3 2024-01-30 02:31:45 +06:00
1581b876cf Remove old ISSUE_TEMPLATE.md 2024-01-30 02:31:45 +06:00
0f4de03d7a Don't throw MALTokenExpired whenever we fail to refresh MAL token
Also cleanup
2024-01-30 02:31:45 +06:00
ddbe8efbc5 [skip ci] Increase size of the message indicating which apk to download 2024-01-30 02:31:44 +06:00
63146e717b Translations update from Hosted Weblate (#269)
* Translated using Weblate (Persian)

Currently translated at 84.8% (673 of 793 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 85.3% (677 of 793 strings)

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

* Translated using Weblate (Chuvash)

Currently translated at 88.2% (15 of 17 strings)

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

---------

Co-authored-by: Arash <ara.khoram95@gmail.com>
Co-authored-by: A <ogloppi@mailbox.org>
Co-authored-by: C201 <derasetad@gmail.com>
2024-01-30 02:31:16 +06:00
b2d22f86c6 Lint 2024-01-29 23:09:09 +06:00
79f46b25f6 Fix new extension install not registering in app. (#275)
* Fix extension install not registering

* fix duplicate key compose error on extension update

* fix doubling of extension after update

* not needed
2024-01-29 23:08:28 +06:00
aa498360db Move :core to :core:common 2024-01-29 15:20:21 +06:00
f03f998b21 [skip ci] Delete ic_launcher-web.png 2024-01-29 14:31:48 +06:00
4811cf07cd Address build warning in :i18n
And small cleanup
2024-01-29 14:29:04 +06:00
b71c793fad Add click-to-copy extension debug info (#271)
* Add click-to-copy extension debug info

Adds some debug info about an extension to the user's clipboard when
tapping the logo/name/package name area at the top of the details
screen. Modeled after the debug info from the About screen.

Closes #168.

* Fix linting failure

* Slight cleanup

* Address detekt

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-01-29 13:57:23 +06:00
47e5421527 Upgrade combose-bom to latest 2024-01-29 13:25:01 +06:00
5dc6501688 Fix #197 - Scroll crashing (#272)
Updating compose bom.
2024-01-29 12:56:29 +06:00
cc09230e26 Adding Detekt in the project (#216)
* Removing ktlint

* Removing compose lint

* Adding initial Detekt config

* Setting up detekt config

* Adding detekt baseline

* Fixing workflows

* Moving to a module based solution

* Adding new line

* Adding new line

* Updating baseline

* Addressing PR suggestions

* Regenerating baseline.xml

* Cleanup

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-01-29 03:29:55 +06:00
9c4d2b087f [skip ci] Update issue templates 2024-01-29 02:03:00 +06:00
4bcba0503a Update dependency com.android.tools.build:gradle to v8.2.2 (#256)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-28 20:39:37 +06:00
cf33f250cc Change extension update error file name (#253) 2024-01-28 20:32:23 +06:00
915a967151 Fixing bottom sheet UI bug in non-tablet devices (#182)
* replace the windowInsetsPadding for navigationBarsPadding + statusBarsPadding

* Setting decorFitsSystemWindows = true to fix ui bug on Android 11
2024-01-28 20:31:59 +06:00
9cc0c4e035 Hide display cutout setting if fullscreen is off (#241)
- make it behave like the one on more -> setting -> reader

Co-authored-by: Riztard <16263232+Riztard@users.noreply.github.com>
2024-01-28 16:13:18 +06:00
222e111806 Release v0.16.2 2024-01-28 00:28:28 +06:00
8489b0dd8b [skip ci] Translations update from Hosted Weblate (#190)
* Translated using Weblate (Nepali)

Currently translated at 94.1% (747 of 793 strings)

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

* Translated using Weblate (Italian)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 98.3% (780 of 793 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 80.9% (642 of 793 strings)

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

* Translated using Weblate (Indonesian)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Nepali)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 100.0% (793 of 793 strings)

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

* Translated using Weblate (Persian)

Currently translated at 82.7% (656 of 793 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 80.9% (642 of 793 strings)

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

* Translated using Weblate (Arabic)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Chuvash)

Currently translated at 88.2% (15 of 17 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (17 of 17 strings)

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

---------

Co-authored-by: FateXBlood <zecrofelix@gmail.com>
Co-authored-by: Federico Pierantoni <federico.pieranton@gmail.com>
Co-authored-by: Zero O <godarms2010@live.com>
Co-authored-by: stevenlele <stevenlele@outlook.com>
Co-authored-by: Paweł Waresiak <pwaresia@redhat.com>
Co-authored-by: kret <cihanbeykoroglu@gmail.com>
Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: Lyfja <45209212+lyfja@users.noreply.github.com>
Co-authored-by: dan-malprod <diabolic0240@proton.me>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
Co-authored-by: A <ogloppi@mailbox.org>
Co-authored-by: Christian Elbrianno <crse@protonmail.ch>
Co-authored-by: abdelbasset jabrane <ribago9317@cubene.com>
Co-authored-by: Arash <ara.khoram95@gmail.com>
Co-authored-by: C201 <derasetad@gmail.com>
Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com>
2024-01-28 00:25:43 +06:00
88ed634978 Lint 2024-01-28 00:15:17 +06:00
32188f9f65 Refactor MAL code to not spam refresh token when it fails 2024-01-28 00:12:31 +06:00
05efc4ebeb Update types of legacy tracker model to match to domain one (#245)
* `score` to Double

* `tracker_id` to Long

* `last_chapter_read` to Double

* `total_chapters` to Long

* `status` to Long
2024-01-27 23:17:09 +06:00
65bfa083f2 Replace "tachiyomi" with "mihon" in crash log name (#234)
Closes #223.
2024-01-26 01:00:23 +06:00
b8a9998bbd [skip ci] Remove official extensions check from issue templates (#233)
* Update report_issue.yml

There are no official extensions anymore and the URL was for the tachiyomi repo anyway

* Update request_feature.yml

No more official extensions
2024-01-25 23:27:23 +06:00
d736bec003 Translations update from Hosted Weblate (#225)
* Translated using Weblate (Swedish)

Currently translated at 100.0% (17 of 17 strings)

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

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (17 of 17 strings)

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

---------

Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl>
Co-authored-by: Lzmxya <lzmxya@gmail.com>
2024-01-24 19:23:39 +06:00
348b23a9fd Fix refreshing from enhanced tracker (#219)
fix refreshing from enhanced tracker
2024-01-24 19:16:28 +06:00
121b2ec829 [skip ci] Removing extensions from config issues (#224) 2024-01-24 19:05:40 +06:00
1dd130df9e Fix #126: Inconsistent button height with some languages in "Data and storage" (#202)
* replace the windowInsetsPadding for navigationBarsPadding + statusBarsPadding

* Fixing bug in the MultiChoiceSegmentedButtonRow

* Rollback file
2024-01-23 18:47:05 +06:00
e17d87f357 Adding Type-safe project accessors (#194)
* replace the windowInsetsPadding for navigationBarsPadding + statusBarsPadding

* Enabling TYPESAFE_PROJECT_ACCESSORS

* Adding typesafe project accessors in the app module

* Adding typesafe project accessors in the core module

* Adding typesafe project accessors in the core-metadata module

* Adding typesafe project accessors in the data module

* Adding typesafe project accessors in the domain module

* Adding typesafe project accessors in the presentation-core module

* Adding typesafe project accessors in the presentation-widget module

* Adding typesafe project accessors in the source-local module

* Adding typesafe project accessors in the source-api module

* Rolling back

* Changing TYPESAFE_PROJECT_ACCESSORS line

* Removing extra spaces
2024-01-23 18:35:58 +06:00
de75561402 Change README to Markdown (#208)
* Change README to Markdown

Also fix license and add disclaimer

* Change some links to markdown as well
2024-01-23 14:14:05 +06:00
58085336a5 Lint 2024-01-22 20:20:11 +06:00
89ea0a271b Add translation widget (#195) 2024-01-22 20:12:39 +06:00
e3f33e24f5 Use own client for trackers + custom user agents
Closes #114
Closes #143

Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
2024-01-22 16:18:30 +06:00
9fd1419142 Translations (#189)
* Small fix on french translation. (#104)

Update fr/strings.xml

Remove mentions of "official" extensions repos. (On 18+ extensions warning)

Fixed a setting label who had the first letter in lowercase.

* Updated Turkish suffixes (#125)

Update strings.xml

* Fix zh-rTW Translation (#118)

fix zh-tw translate

* Update Filipino Plurals (#112)

Updated some Filipino Plurals to make sense grammatically

* Update Filipino Strings (#111)

Changed/updated a few grammatical strings for the Filipino Translation

---------

Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: NukeSource <123626751+NukeSource@users.noreply.github.com>
Co-authored-by: ɴᴇᴋᴏ <111511925+NeKoOuO@users.noreply.github.com>
Co-authored-by: InfinityDouki56 <31158494+infyProductions@users.noreply.github.com>
2024-01-22 15:45:37 +06:00
cb06898430 Fix issues when updating extensions 2024-01-22 02:27:45 +06:00
39407407f2 Remove usage of .not() where possible 2024-01-21 19:40:42 +06:00
a024218410 Fix faulty MangaUpdates score in db
Closes #117
2024-01-21 12:21:30 +06:00
26815c7356 Tweak app icon scaling 2024-01-21 11:55:25 +06:00
e0deeb8008 Backup and Restore Excluded scanlators (#166)
* Backup and Restore Excluded scanlators

* Improve performance

* This looks better
2024-01-21 11:38:36 +06:00
38d6ab80ce Fix "Flash on page change" gives black screen on page change
Fixes #108
2024-01-20 16:33:50 +06:00
78e66fd8d3 Tweak README (#154)
* update README.md

* Update README.md

---------

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
2024-01-20 15:59:18 +06:00
26aa126ecb Modernize README (#139)
* Prepare new Readme

* Modernize README

* Tweak wording
2024-01-20 01:33:42 +06:00
e4a65656e7 refactor: db changes for syncing. (#113)
fix: sync marking chapter unread when we do library update before syncing.

So this should have been 0 on insert instead of the current time on insert. Essentially this issue arises: https://discord.com/channels/1099009852791083058/1099009853864812708/1190022356060614756

Signed-off-by: KaiserBh <kaiserbh@proton.me>
2024-01-18 10:37:41 +06:00
6018aa99e2 Release v0.16.1 2024-01-18 01:30:03 +06:00
99fd2731f5 Fix score issue with MangaUpdates
Also add custom user agent

Potentially fix #17
2024-01-18 01:28:54 +06:00
e34043f1fe Fixed Serbian translation (#75) 2024-01-18 01:27:08 +06:00
3c3a1cd448 [skip ci] Refer to the preview build as beta 2024-01-17 16:01:26 +06:00
0a2df21c5b Fix Indonesian translation (#68)
Fix minor Indonesian translation
2024-01-17 14:05:06 +06:00
277be02682 Update project icon 2024-01-17 13:29:42 +06:00
1849715418 Fix icons not filled
Closes #3
2024-01-17 13:19:49 +06:00
dc6d4f9917 Fix minor grammatical errors in Finnish strings (#64) 2024-01-17 10:48:30 +06:00
a9d98e5048 [skip ci] Updated Issue and Feature Request templates (#41)
* Update version in issue template

* Update request_feature.yml
2024-01-16 23:20:37 +06:00
653940613d Replace some more Tachiyomi reference 2024-01-16 19:55:56 +06:00
23a2d816e4 [skip ci] Replaced mentions of Tachiyomi with Mihon in Issue Templates (#22)
Tachiyomi => Mihon in Issue Templates
2024-01-16 17:53:52 +06:00
8a3a9146db [skip ci] Remove inorichi's Funding.yml, and replace app-icon 2024-01-16 12:53:28 +06:00
789 changed files with 13198 additions and 7408 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +0,0 @@
ko_fi: inorichi

View File

@ -1,34 +0,0 @@
**PLEASE READ THIS**
I acknowledge that:
- I have updated:
- To the latest version of the app (stable is v0.15.3)
- All extensions
- I have gone through the FAQ (https://mihon.app/docs/faq/general) and troubleshooting guide (https://mihon.app/docs/guides/troubleshooting/)
- If this is an issue with an official extension, that I should be opening an issue in https://github.com/tachiyomiorg/extensions
- I have searched the existing issues and this is new ticket **NOT** a duplicate or related to another open or closed issue
- I will fill out the title and the information in this template
Note that the issue will be automatically closed if you do not fill out the title or requested information.
**DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT**
---
## Device information
* Tachiyomi version: ?
* Android version: ?
* Device: ?
## Steps to reproduce
1. First step
2. Second step
## Issue/Request
?
## Other details
Additional details and attachments.
If you're experiencing crashes, share the crash logs from More → Settings → Advanced → Dump crash logs.

View File

@ -1,11 +1,5 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: Extension/source issue - name: 🖥 Mihon website
url: https://github.com/tachiyomiorg/extensions/issues/new/choose
about: Issues and requests for official extensions and sources should be opened in the extensions repository instead
- name: 📦 Tachiyomi extensions
url: https://mihon.app/extensions/
about: List of all available extensions with download links
- name: 🖥️ Tachiyomi website
url: https://mihon.app/ url: https://mihon.app/
about: Guides, troubleshooting, and answers to common questions about: Guides, troubleshooting, and answers to common questions

View File

@ -1,5 +1,5 @@
name: 🐞 Issue report name: 🐞 Issue report
description: Report an issue in Tachiyomi description: Report an issue in Mihon
labels: [Bug] labels: [Bug]
body: body:
@ -48,12 +48,12 @@ body:
You can paste the crash logs in plain text or upload it as an attachment. You can paste the crash logs in plain text or upload it as an attachment.
- type: input - type: input
id: tachiyomi-version id: mihon-version
attributes: attributes:
label: Tachiyomi version label: Mihon version
description: You can find your Tachiyomi version in **More → About**. description: You can find your Mihon version in **More → About**.
placeholder: | placeholder: |
Example: "0.15.3" Example: "0.16.5"
validations: validations:
required: true required: true
@ -94,11 +94,9 @@ body:
required: true required: true
- label: I have written a short but informative title. - label: I have written a short but informative title.
required: true required: true
- label: If this is an issue with an official extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/extensions/issues/new/choose).
required: true
- label: I have gone through the [FAQ](https://mihon.app/docs/faq/general) and [troubleshooting guide](https://mihon.app/docs/guides/troubleshooting/). - label: I have gone through the [FAQ](https://mihon.app/docs/faq/general) and [troubleshooting guide](https://mihon.app/docs/guides/troubleshooting/).
required: true required: true
- label: I have updated the app to version **[0.15.3](https://github.com/mihonapp/mihon/releases/latest)**. - label: I have updated the app to version **[0.16.5](https://github.com/mihonapp/mihon/releases/latest)**.
required: true required: true
- label: I have updated all installed extensions. - label: I have updated all installed extensions.
required: true required: true

View File

@ -1,5 +1,5 @@
name: ⭐ Feature request name: ⭐ Feature request
description: Suggest a feature to improve Tachiyomi description: Suggest a feature to improve Mihon
labels: [Feature request] labels: [Feature request]
body: body:
@ -7,7 +7,7 @@ body:
id: feature-description id: feature-description
attributes: attributes:
label: Describe your suggested feature label: Describe your suggested feature
description: How can Tachiyomi be improved? description: How can Mihon be improved?
placeholder: | placeholder: |
Example: Example:
"It should work like this..." "It should work like this..."
@ -31,9 +31,7 @@ body:
required: true required: true
- label: I have written a short but informative title. - label: I have written a short but informative title.
required: true required: true
- label: If this is an issue with an official extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/extensions/issues/new/choose). - label: I have updated the app to version **[0.16.5](https://github.com/mihonapp/mihon/releases/latest)**.
required: true
- label: I have updated the app to version **[0.15.3](https://github.com/mihonapp/mihon/releases/latest)**.
required: true required: true
- label: I will fill out all of the requested information in this form. - label: I will fill out all of the requested information in this form.
required: true required: true

BIN
.github/assets/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

10
.github/mergify.yml vendored
View File

@ -1,10 +0,0 @@
#pull_request_rules:
# - name: Automatically merge translations
# conditions:
# - "author = weblate"
# - "-conflict"
# - "current-day-of-week = Sat"
# - "created-at < 1 day ago"
# actions:
# merge:
# method: squash

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,17 +1,6 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": ["config:base"],
"config:base" "labels": ["Dependencies"],
], "semanticCommits": "disabled"
"schedule": ["every sunday"],
"packageRules": [
{
// Compiler plugins are tightly coupled to Kotlin version
"groupName": "Kotlin",
"matchPackagePrefixes": [
"androidx.compose.compiler",
"org.jetbrains.kotlin",
],
}
]
} }

View File

@ -1,10 +1,13 @@
name: PR build check name: PR build check
on: on:
pull_request: pull_request:
paths-ignore: paths:
- '**.md' - '**'
- 'i18n/src/commonMain/resources/**/strings.xml' - '!**.md'
- 'i18n/src/commonMain/resources/**/plurals.xml' - '!i18n/src/commonMain/moko-resources/**/strings.xml'
- '!i18n/src/commonMain/moko-resources/**/plurals.xml'
- 'i18n/src/commonMain/moko-resources/base/strings.xml'
- 'i18n/src/commonMain/moko-resources/base/plurals.xml'
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }} group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
@ -20,21 +23,34 @@ jobs:
steps: steps:
- name: Clone repo - name: Clone repo
uses: actions/checkout@v4 uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/actions/wrapper-validation@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0
- name: Dependency Review - name: Dependency Review
uses: actions/dependency-review-action@v3 uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with: with:
java-version: 17 java-version: 17
distribution: adopt distribution: adopt
- name: Set up gradle
uses: gradle/actions/setup-gradle@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0
- name: Build app and run unit tests - name: Build app and run unit tests
uses: gradle/gradle-command-action@v2 run: ./gradlew spotlessCheck assembleStandardRelease testReleaseUnitTest testStandardReleaseUnitTest
- name: Upload APK
uses: actions/upload-artifact@v4
with: with:
arguments: ktlintCheck assembleStandardRelease testReleaseUnitTest name: arm64-v8a-${{ github.sha }}
path: app/build/outputs/apk/standard/release/app-standard-arm64-v8a-release-unsigned.apk
- name: Upload mapping
uses: actions/upload-artifact@v4
with:
name: mapping-${{ github.sha }}
path: app/build/outputs/mapping/standardRelease

View File

@ -17,25 +17,38 @@ jobs:
steps: steps:
- name: Clone repo - name: Clone repo
uses: actions/checkout@v4 uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/actions/wrapper-validation@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0
- name: Setup Android SDK - name: Setup Android SDK
run: | run: |
${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager "build-tools;29.0.3" ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager "build-tools;29.0.3"
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0
with: with:
java-version: 17 java-version: 17
distribution: adopt distribution: adopt
- name: Set up gradle
uses: gradle/actions/setup-gradle@d156388eb19639ec20ade50009f3d199ce1e2808 # v4.1.0
- name: Build app and run unit tests - name: Build app and run unit tests
uses: gradle/gradle-command-action@v2 run: ./gradlew spotlessCheck assembleStandardRelease testReleaseUnitTest testStandardReleaseUnitTest
- name: Upload APK
uses: actions/upload-artifact@v4
with: with:
arguments: ktlintCheck assembleStandardRelease testReleaseUnitTest name: arm64-v8a-${{ github.sha }}
path: app/build/outputs/apk/standard/release/app-standard-arm64-v8a-release-unsigned.apk
- name: Upload mapping
uses: actions/upload-artifact@v4
with:
name: mapping-${{ github.sha }}
path: app/build/outputs/mapping/standardRelease
# Sign APK and create release for tags # Sign APK and create release for tags
@ -47,7 +60,7 @@ jobs:
- name: Sign APK - name: Sign APK
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'mihonapp/mihon' if: startsWith(github.ref, 'refs/tags/') && github.repository == 'mihonapp/mihon'
uses: r0adkll/sign-android-release@v1 uses: r0adkll/sign-android-release@349ebdef58775b1e0d8099458af0816dc79b6407 # v1
with: with:
releaseDirectory: app/build/outputs/apk/standard/release releaseDirectory: app/build/outputs/apk/standard/release
signingKeyBase64: ${{ secrets.SIGNING_KEY }} signingKeyBase64: ${{ secrets.SIGNING_KEY }}
@ -82,7 +95,7 @@ jobs:
- name: Create Release - name: Create Release
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'mihonapp/mihon' if: startsWith(github.ref, 'refs/tags/') && github.repository == 'mihonapp/mihon'
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
with: with:
tag_name: ${{ env.VERSION_TAG }} tag_name: ${{ env.VERSION_TAG }}
name: Mihon ${{ env.VERSION_TAG }} name: Mihon ${{ env.VERSION_TAG }}
@ -99,7 +112,7 @@ jobs:
| x86 | ${{ env.APK_X86_SHA }} | | x86 | ${{ env.APK_X86_SHA }} |
| x86_64 | ${{ env.APK_X86_64_SHA }} | | x86_64 | ${{ env.APK_X86_64_SHA }} |
If you are unsure which version to choose then go with mihon-${{ env.VERSION_TAG }}.apk ## If you are unsure which version to choose then go with mihon-${{ env.VERSION_TAG }}.apk
files: | files: |
mihon-${{ env.VERSION_TAG }}.apk mihon-${{ env.VERSION_TAG }}.apk
mihon-arm64-v8a-${{ env.VERSION_TAG }}.apk mihon-arm64-v8a-${{ env.VERSION_TAG }}.apk

View File

@ -1,45 +0,0 @@
name: Issue moderator
on:
issues:
types: [opened, edited, reopened]
issue_comment:
types: [created]
jobs:
moderate:
runs-on: ubuntu-latest
steps:
- name: Moderate issues
uses: tachiyomiorg/issue-moderator-action@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
duplicate-label: Duplicate
auto-close-rules: |
[
{
"type": "body",
"regex": ".*DELETE THIS SECTION IF YOU HAVE READ AND ACKNOWLEDGED IT.*",
"message": "The acknowledgment section was not removed."
},
{
"type": "body",
"regex": ".*\\* (Tachiyomi version|Android version|Device): \\?.*",
"message": "Requested information in the template was not filled out."
},
{
"type": "both",
"regex": "^(?!.*myanimelist.*).*(aniyomi|anime).*$",
"ignoreCase": true,
"message": "Tachiyomi does not support anime, and has no plans to support anime. In addition Tachiyomi is not affiliated with Aniyomi https://github.com/jmir1/aniyomi"
},
{
"type": "both",
"regex": ".*(?:fail(?:ed|ure|s)?|can\\s*(?:no|')?t|(?:not|un).*able|(?<!n[o']?t )blocked by|error) (?:to )?(?:get past|by ?pass|penetrate)?.*cloud ?fl?are.*",
"ignoreCase": true,
"labels": ["Cloudflare protected"],
"message": "Refer to the **Solving Cloudflare issues** section at https://mihon.app/docs/guides/troubleshooting/#cloudflare. If it doesn't work, migrate to other sources or wait until they lower their protection."
}
]
auto-close-ignore-label: do-not-autoclose

View File

@ -12,7 +12,7 @@ jobs:
lock: lock:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v5 - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
with: with:
github-token: ${{ github.token }} github-token: ${{ github.token }}
issue-inactive-days: '2' issue-inactive-days: '2'

23
.gitignore vendored
View File

@ -1,17 +1,16 @@
# Build files
.gradle .gradle
/local.properties .kotlin
/.idea/workspace.xml build
.DS_Store
# IDE files
*.iml
.idea/* .idea/*
!.idea/icon.png !.idea/icon.png
*iml /captures
*.iml
# Built files # Configuration files
*/build local.properties
/build
*.apk
app/**/output.json
# Unnecessary file # macOS specific files
*.swp .DS_Store

BIN
.idea/icon.png generated

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 62 KiB

134
CHANGELOG.md Normal file
View File

@ -0,0 +1,134 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Option to disable reader zoom out ([@Splintorien](https://github.com/Splintorien)) ([#302](https://github.com/mihonapp/mihon/pull/302))
- Source name and tracker urls to app generated `ComicInfo.xml` file ([@Shamicen](https://github.com/Shamicen)) ([#459](https://github.com/mihonapp/mihon/pull/459))
- Option to migrate in Duplicate entry dialog ([@sirlag](https://github.com/sirlag)) ([#492](https://github.com/mihonapp/mihon/pull/492))
- Upcoming screen to visualize expected update dates ([@sirlag](https://github.com/sirlag)) ([#420](https://github.com/mihonapp/mihon/pull/420))
- Crash screen error message to the top of the crash log generated from that screen ([@FooIbar](https://github.com/FooIbar)) ([#742](https://github.com/mihonapp/mihon/pull/742))
- Support for 7Zip and RAR5 archives ([@FooIbar](https://github.com/FooIbar), [@null2264](https://github.com/null2264)) ([#949](https://github.com/mihonapp/mihon/pull/949), [#967](https://github.com/mihonapp/mihon/pull/967))
- Extra configuration options to e-ink page flashes ([@sirlag](https://github.com/sirlag)) ([#625](https://github.com/mihonapp/mihon/pull/625))
- 8-bit+ AVIF image support ([@WerctFourth](https://github.com/WerctFourth)) ([#971](https://github.com/mihonapp/mihon/pull/971))
- Smart update dialog message when no predicted released date exists ([@Animeboynz](https://github.com/Animeboynz)) ([#977](https://github.com/mihonapp/mihon/pull/977))
- Save global search "Has result" choice ([@AntsyLich](https://github.com/AntsyLich)) ([`5a61ca5`](https://github.com/mihonapp/mihon/commit/5a61ca5535fe0d9e8e7bcb9e665ba2f9cb0cf649))
- Option to copy reader panel to clipboard ([@Animeboynz](https://github.com/Animeboynz)) ([#1003](https://github.com/mihonapp/mihon/pull/1003))
- Copy Tracker URL option to tracker sheet ([@mm12](https://github.com/mm12)) ([#1101](https://github.com/mihonapp/mihon/pull/1101))
- A button to exclude all scanlators in exclude scanlators dialog ([@AntsyLich](https://github.com/AntsyLich)) ([`84b2164`](https://github.com/mihonapp/mihon/commit/84b2164787a795f3fd757c325cbfb6ef660ac3a3))
- Open in browser option to reader menu ([@mm12](https://github.com/mm12)) ([#1110](https://github.com/mihonapp/mihon/pull/1110))
- Option to skip downloading duplicate read chapters ([@shabnix](https://github.com/shabnix)) ([#1125](https://github.com/mihonapp/mihon/pull/1125))
### Changed
- Read archive files from memory instead of extracting files to internal storage ([@FooIbar](https://github.com/FooIbar)) ([#326](https://github.com/mihonapp/mihon/pull/326))
- Try to get resource from Extension before checking in the app ([@beer-psi](https://github.com/beer-psi)) ([#433](https://github.com/mihonapp/mihon/pull/433))
- Default user agent ([@AntsyLich](https://github.com/AntsyLich)) ([`8160b47`](https://github.com/mihonapp/mihon/commit/8160b47ff5fbbd9b32caeb462b5be881fabd3449))
- Wait for sources to be initialized before performing source related tasks ([@jobobby04](https://github.com/jobobby04)) ([`a08e03f`](https://github.com/mihonapp/mihon/commit/a08e03f5cbf3f4e6be1de35f97ef8ebb26a1210e))
- Duplicate entry dialog UI ([@sirlag](https://github.com/sirlag)) ([#492](https://github.com/mihonapp/mihon/pull/492))
- Extension trust system ([@AntsyLich](https://github.com/AntsyLich), [@Animeboynz](https://github.com/Animeboynz) ([#570](https://github.com/mihonapp/mihon/pull/570), [#1057](https://github.com/mihonapp/mihon/pull/1057))
- Make category backup/restore not dependant on library backup ([@AntsyLich](https://github.com/AntsyLich)) ([`56fb4f6`](https://github.com/mihonapp/mihon/commit/56fb4f62a152e87a71892aa68c78cac51a2c8596))
- Kitsu domain to `kitsu.app` ([@MajorTanya](https://github.com/MajorTanya)) ([#1106](https://github.com/mihonapp/mihon/pull/1106))
- Respect privacy settings in extension update notification ([@Animeboynz](https://github.com/Animeboynz)) ([#1156](https://github.com/mihonapp/mihon/pull/1156))
### Improvement
- Long strip reader performance ([@FooIbar](https://github.com/FooIbar), [@wwww-wwww](https://github.com/wwww-wwww)) ([#687](https://github.com/mihonapp/mihon/pull/687))
- Performance when looking up specific files ([@raxod502](https://github.com/raxod502)) ([#728](https://github.com/mihonapp/mihon/pull/728))
- Chapter number parsing ([@Naputt1](https://github.com/Naputt1)) ([`6a80305`](https://github.com/mihonapp/mihon/commit/6a80305d6c572da6c08c0c69f5c25ff26ecf7383))
- Error message on restoring if backup decoding fails ([@vetleledaal](https://github.com/vetleledaal)) ([#1056](https://github.com/mihonapp/mihon/pull/1056))
### Fixed
- Creating `ComicInfo.xml` file for local source ([@FooIbar](https://github.com/FooIbar)) ([#325](https://github.com/mihonapp/mihon/pull/325))
- Chapter download indicator ([@ivaniskandar](https://github.com/ivaniskandar)) ([`d8b9a9f`](https://github.com/mihonapp/mihon/commit/d8b9a9f593911569ff2bceb49b4f020978d0d2e1))
- Issues with shizuku in a multi user setup ([@Redjard](https://github.com/Redjard)) ([#494](https://github.com/mihonapp/mihon/pull/494))
- Occasional black bar when scrolling in long strip reader ([@FooIbar](https://github.com/FooIbar)) ([#563](https://github.com/mihonapp/mihon/pull/563))
- Extension being marked as not installed instead of untrusted after updating with private installer ([@AntsyLich](https://github.com/AntsyLich)) ([`2114514`](https://github.com/mihonapp/mihon/commit/21145144cdf550aa775047603e06e261951ebc42))
- Extension update counter not updating due to extension being marked as untrusted ([@AntsyLich](https://github.com/AntsyLich)) ([`2114514`](https://github.com/mihonapp/mihon/commit/21145144cdf550aa775047603e06e261951ebc42))
- `Key "extension-XXX-YYY" was already used` crash ([@AntsyLich](https://github.com/AntsyLich)) ([`2114514`](https://github.com/mihonapp/mihon/commit/21145144cdf550aa775047603e06e261951ebc42))
- Navigation layout tap zones shifting after zooming out in webtoon readers ([@FooIbar](https://github.com/FooIbar)) ([#767](https://github.com/mihonapp/mihon/pull/767))
- Some extension not loading due to missing classes ([@AwkwardPeak7](https://github.com/AwkwardPeak7)) ([#783](https://github.com/mihonapp/mihon/pull/783))
- Theme colors in accordance to upstream changes ([@CrepeTF](https://github.com/CrepeTF), [@AntsyLich](https://github.com/AntsyLich)) ([#766](https://github.com/mihonapp/mihon/pull/766), [#963](https://github.com/mihonapp/mihon/pull/963), [#976](https://github.com/mihonapp/mihon/pull/976))
- Crash when requesting folder access on non-conforming devices ([@mainrs](https://github.com/mainrs)) ([#726](https://github.com/mihonapp/mihon/pull/726))
- Bugged color for Date/Scanlator in chapter list for read chapters ([@ivaniskandar](https://github.com/ivaniskandar)) ([`15d9992`](https://github.com/mihonapp/mihon/commit/15d999229fcce865001d5fa77d0163e6e80e38db))
- Categories having same `order` after restoring backup ([@Cologler](https://github.com/Cologler)) ([`119bcbf`](https://github.com/mihonapp/mihon/commit/119bcbf8ed2415664922ea77fadf0da1165d1732))
- Filter by "Tracking" temporarily stuck after signing out of tracker ([@AntsyLich](https://github.com/AntsyLich)) ([#987](https://github.com/mihonapp/mihon/pull/987))
- JXL image downloading and loading ([@FooIbar](https://github.com/FooIbar)) ([#993](https://github.com/mihonapp/mihon/pull/993))
- Crash when using `%` in category name ([@Animeboynz](https://github.com/Animeboynz), [@FooIbar](https://github.com/FooIbar)) ([#1030](https://github.com/mihonapp/mihon/pull/1030))
- Library is backed up while being disabled ([@AntsyLich](https://github.com/AntsyLich)) ([`56fb4f6`](https://github.com/mihonapp/mihon/commit/56fb4f62a152e87a71892aa68c78cac51a2c8596))
- Crash on list with 0 item but only sticky header ([@cuong-tran](https://github.com/cuong-tran)) ([#1083](https://github.com/mihonapp/mihon/pull/1083))
- Crash when trying to clear cookies of some source ([@FooIbar](https://github.com/FooIbar)) ([#1084](https://github.com/mihonapp/mihon/pull/1084))
- MAL search results not showing start dates ([@MajorTanya](https://github.com/MajorTanya)) ([#1098](https://github.com/mihonapp/mihon/pull/1098))
- Android SDK 35 API collision ([@AntsyLich](https://github.com/AntsyLich)) ([`fdb9617`](https://github.com/mihonapp/mihon/commit/fdb96179c6373eb0a8e7d6daea671a315d5ce5f0))
## [v0.16.5] - 2024-04-09
### Added
- Setting to install custom color profiles to get true colors ([@wwww-wwww](https://github.com/wwww-wwww)) ([#523](https://github.com/mihonapp/mihon/pull/523))
### Changed
- Permanently enable 32-bit color mode ([@wwww-wwww](https://github.com/wwww-wwww)) ([#523](https://github.com/mihonapp/mihon/pull/523))
### Fixed
- Fix wrong dates in Updates and History tab due to time zone issues ([@sirlag](https://github.com/sirlag)) ([#402](https://github.com/mihonapp/mihon/pull/402), [#415](https://github.com/mihonapp/mihon/pull/415))
- Fix app infinitely retries tracker update instead of failing after 3 tries ([@MajorTanya](https://github.com/MajorTanya)) ([#411](https://github.com/mihonapp/mihon/pull/411))
- Fix crash on Pixel devices ([`ab06720`](https://github.com/mihonapp/mihon/commit/ab067209661eceefc04c65f6bdbfcaa8a1264651))
- Fix crash when opening some heif/heic images ([@az4521](https://github.com/az4521)) ([#466](https://github.com/mihonapp/mihon/pull/466))
- Fix crash in track date selection dialog ([@ivaniskandar](https://github.com/ivaniskandar)) ([`c348fac`](https://github.com/mihonapp/mihon/commit/c348fac78fac479fb123bd617c01c78b9ca851d5))
- Fix dates for saved images on Samsung devices ([@MajorTanya](https://github.com/MajorTanya)) ([#552](https://github.com/mihonapp/mihon/pull/552))
- Fix colors getting distorted when opening CMYK jpeg images ([@wwww-wwww](https://github.com/wwww-wwww)) ([#523](https://github.com/mihonapp/mihon/pull/523))
## [v0.16.4] - 2024-02-26
### Fixed
- Circumvent MAL block ([@AntsyLich](https://github.com/AntsyLich)) ([`085ad8d`](https://github.com/mihonapp/mihon/commit/085ad8d44637c375a8ed24aba3a6f75f5b0cc9ee))
## [v0.16.3] - 2024-01-30
### Added
- Copy extension debug info when clicking logo or name in the extension details screen ([@MajorTanya](https://github.com/MajorTanya)) ([#271](https://github.com/mihonapp/mihon/pull/271))
### Changed
- Rename extension update error file to `mihon_update_errors.txt` ([@mjishnu](https://github.com/mjishnu)) ([#253](https://github.com/mihonapp/mihon/pull/253))
- Hide display cutoff setting in reader settings sheet if fullscreen is off ([@Riztard](https://github.com/Riztard)) ([#241](https://github.com/mihonapp/mihon/pull/241))
### Fixed
- Fix bottom sheet display issues on non-Tablet UI ([@theolm](https://github.com/theolm)) ([#182](https://github.com/mihonapp/mihon/pull/182))
- Fix crash when switching screen while a list is scrolling ([@theolm](https://github.com/theolm)) ([#272](https://github.com/mihonapp/mihon/pull/272))
- Fix newly installed extensions not being recognized by Mihon ([@AwkwardPeak7](https://github.com/AwkwardPeak7)) ([#275](https://github.com/mihonapp/mihon/pull/275))
- Fix error handling when refreshing MAL OAuth token ([@AntsyLich](https://github.com/AntsyLich)) ([`0f4de03`](https://github.com/mihonapp/mihon/commit/0f4de03d7a77b52490dc9a95e96a308b93b26e4f))
## [v0.16.2] - 2024-01-28
### Added
- Scanlator filter is now part of Backup ([@jobobby04](https://github.com/jobobby04)) ([#166](https://github.com/mihonapp/mihon/pull/166))
### Changed
- Rename crash log filename to `mihon_crash_logs.txt` ([@MajorTanya](https://github.com/MajorTanya)) ([#234](https://github.com/mihonapp/mihon/pull/234))
### Fixed
- "Flash screen on page change" Making the screen goes blank ([@AntsyLich](https://github.com/AntsyLich)) ([`38d6ab8`](https://github.com/mihonapp/mihon/commit/38d6ab80ce868707829dbc81de4170afe3c2f2a5))
- App icon scaling ([@AntsyLich](https://github.com/AntsyLich)) ([`26815c7`](https://github.com/mihonapp/mihon/commit/26815c7356111394665467c1e81255ac9ee33c1a))
- Updating extension not reflecting correctly ([@AntsyLich](https://github.com/AntsyLich)) ([`cb06898`](https://github.com/mihonapp/mihon/commit/cb068984303f811692531bf6f14902ae118d8ac7))
- Inconsistent button height with some languages in "Data and storage" ([@theolm](https://github.com/theolm)) ([#202](https://github.com/mihonapp/mihon/pull/202))
- Fix chapter not being marked as read in some cases with Enhanced Trackers ([@Secozzi](https://github.com/Secozzi)) ([#219](https://github.com/mihonapp/mihon/pull/219))
- And various tracker related fixes ([@AntsyLich](https://github.com/AntsyLich), [@kitsumed](https://github.com/kitsumed), [@Secozzi](https://github.com/Secozzi)) ([`a024218`](https://github.com/mihonapp/mihon/commit/a024218410953a389b8af4880fa7ae6cc30124a2), [`e3f33e2`](https://github.com/mihonapp/mihon/commit/e3f33e24f5e928ac8a85d1f500fd42d4715fc6b5), [`32188f9`](https://github.com/mihonapp/mihon/commit/32188f9f65009a18250674ef1bd6e57d351c1fba))
## [v0.16.1] - 2024-01-18
### Fixed
- App Icon not filled ([@AntsyLich](https://github.com/AntsyLich)) ([`1849715`](https://github.com/mihonapp/mihon/commit/18497154183356bb0d469b27827f9f7d6b7a3130))
- MangaUpdates default score being set to -1.0 ([@AntsyLich](https://github.com/AntsyLich)) ([`99fd273`](https://github.com/mihonapp/mihon/commit/99fd2731f5d9d374700e89fa67d4d5bf611bbafa))
## [v0.16.0] - 2024-01-16
"The end of 立ち読み (Tachiyomi) is the beginning of みほん (Mihon)"
Credit to LinkCable, the icon designer, for this poetic quote.
What's New?
Well, nothing, except you now you need Android 8+ to install the app.
[unreleased]: https://github.com/mihonapp/mihon/compare/v0.16.5...HEAD
[v0.16.5]: https://github.com/mihonapp/mihon/compare/v0.16.4...v0.16.5
[v0.16.4]: https://github.com/mihonapp/mihon/compare/v0.16.3...v0.16.4
[v0.16.3]: https://github.com/mihonapp/mihon/compare/v0.16.2...v0.16.3
[v0.16.2]: https://github.com/mihonapp/mihon/compare/v0.16.1...v0.16.2
[v0.16.1]: https://github.com/mihonapp/mihon/compare/v0.16.0...v0.16.1
[v0.16.0]: https://github.com/mihonapp/mihon/releases/tag/v0.16.0

View File

@ -24,10 +24,6 @@ Before you start, please note that the ability to use following technologies is
- [Android Studio](https://developer.android.com/studio) - [Android Studio](https://developer.android.com/studio)
- Emulator or phone with developer options enabled to test changes. - Emulator or phone with developer options enabled to test changes.
## Linting
To auto-fix some linting errors, run the `ktlintFormat` Gradle task.
## Getting help ## Getting help
- Join [the Discord server](https://discord.gg/mihon) 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.

127
README.md
View File

@ -1,89 +1,86 @@
| Build | Stable | Weekly Preview | Support Server | <div align="center">
|-------|----------|---------|---------|
| [![CI](https://github.com/mihonapp/mihon/actions/workflows/build_push.yml/badge.svg)](https://github.com/mihonapp/mihon/actions/workflows/build_push.yml) | [![stable release](https://img.shields.io/github/release/mihonapp/mihon.svg?maxAge=3600&label=download)](https://github.com/mihonapp/mihon/releases) | [![latest preview build](https://img.shields.io/github/v/release/mihonapp/mihon-preview.svg?maxAge=3600&label=download)](https://github.com/mihonapp/mihon-preview/releases) | [![Discord](https://img.shields.io/discord/1195734228319617024.svg?label=discord&labelColor=7289da&color=2c2f33&style=flat)](https://discord.gg/mihon) |
# ![app icon](./.github/readme-images/app-icon.png)Mihon <a href="https://mihon.app">
Mihon is a free and open source manga reader for Android 8.0 and above. <img src="./.github/assets/logo.png" alt="Mihon logo" title="Mihon logo" width="80"/>
</a>
# Mihon [App](#)
### Full-featured reader
Discover and read manga, webtoons, comics, and more easier than ever on your Android device.
[![Discord server](https://img.shields.io/discord/1195734228319617024.svg?label=&labelColor=6A7EC2&color=7389D8&logo=discord&logoColor=FFFFFF)](https://discord.gg/mihon)
[![GitHub downloads](https://img.shields.io/github/downloads/mihonapp/mihon/total?label=downloads&labelColor=27303D&color=0D1117&logo=github&logoColor=FFFFFF&style=flat)](https://github.com/mihonapp/mihon/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/mihonapp/mihon/build_push.yml?labelColor=27303D)](https://github.com/mihonapp/mihon/actions/workflows/build_push.yml)
[![License: Apache-2.0](https://img.shields.io/github/license/mihonapp/mihon?labelColor=27303D&color=0877d2)](/LICENSE)
[![Translation status](https://img.shields.io/weblate/progress/mihon?labelColor=27303D&color=946300)](https://hosted.weblate.org/engage/mihon/)
## Download
[![Mihon Stable](https://img.shields.io/github/release/mihonapp/mihon.svg?maxAge=3600&label=Stable&labelColor=06599d&color=043b69)](https://github.com/mihonapp/mihon/releases)
[![Mihon Beta](https://img.shields.io/github/v/release/mihonapp/mihon-preview.svg?maxAge=3600&label=Beta&labelColor=2c2c47&color=1c1c39)](https://github.com/mihonapp/mihon-preview/releases)
*Requires Android 8.0 or higher.*
## Features ## Features
Features include: <div align="left">
* Online reading from a variety of sources
* Local reading of downloaded content * Local reading of content.
* A configurable reader with multiple viewers, reading directions and other settings. * 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 * Categories to organize your library.
* Light and dark themes * Light and dark themes.
* Schedule updating your library for new chapters * Schedule updating your library for new chapters.
* Create backups locally to read offline or to your desired cloud service * Create backups locally to read offline or to your desired cloud service.
* Plus much more...
## Download </div>
Get the app from our [releases page](https://github.com/mihonapp/mihon/releases).
If you want to try new features before they get to the stable release, you can download the preview version [here](https://github.com/mihonapp/mihon-preview/releases). ## Contributing
## Issues, Feature Requests and Contributing [Code of conduct](./CODE_OF_CONDUCT.md) · [Contributing guide](./CONTRIBUTING.md)
Please make sure to read the full guidelines. Your issue may be closed without warning if you do not. Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
<details><summary>Issues</summary> Before reporting a new issue, take a look at the [FAQ](https://mihon.app/docs/faq/general), the [changelog](https://mihon.app/changelogs/) and the already opened [issues](https://github.com/mihonapp/mihon/issues); if you got any questions, join our [Discord server](https://discord.gg/mihon).
1. **Before reporting a new issue, take a look at the [FAQ](https://mihon.app/docs/faq/general), the [changelog](https://mihon.app/changelogs/) and the already opened [issues](https://github.com/mihonapp/mihon/issues).**
2. If you are unsure, ask here: [![Discord](https://img.shields.io/discord/1195734228319617024.svg)](https://discord.gg/mihon)
</details> ### Repositories
<details><summary>Bugs</summary> [![mihonapp/website - GitHub](https://github-readme-stats.vercel.app/api/pin/?username=mihonapp&repo=website&bg_color=161B22&text_color=c9d1d9&title_color=0877d2&icon_color=0877d2&border_radius=8&hide_border=true&description_lines_count=2)](https://github.com/mihonapp/website/)
[![mihonapp/bitmap.kt - GitHub](https://github-readme-stats.vercel.app/api/pin/?username=mihonapp&repo=bitmap.kt&bg_color=161B22&text_color=c9d1d9&title_color=0877d2&icon_color=0877d2&border_radius=8&hide_border=true&description_lines_count=2)](https://github.com/mihonapp/bitmap.kt/)
* Include version (More → About → Version) ### Credits
* If not latest, try updating, it may have already been solved
* Preview version is equal to the number of commits as seen on the main page
* Include steps to reproduce (if not obvious from description)
* Include screenshot (if needed)
* If it could be device-dependent, try reproducing on another device (if possible)
* Don't group unrelated requests into one issue
</details> Thank you to all the people who have contributed!
<details><summary>Feature Requests</summary> <a href="https://github.com/mihonapp/mihon/graphs/contributors">
<img src="https://contrib.rocks/image?repo=mihonapp/mihon" alt="Mihon app contributors" title="Mihon app contributors" width="800"/>
</a>
* Write a detailed issue, explaining what it should do or how. Avoid writing just "like X app does" ### Disclaimer
* Include screenshot (if needed)
Source requests are not accepted. The developer(s) of this application does not have any affiliation with the content providers available, and this application hosts zero content.
</details>
<details><summary>Contributing</summary> ### License
See [CONTRIBUTING.md](./CONTRIBUTING.md). <pre>
</details> Copyright © 2015 Javier Tomás
Copyright © 2024 The Mihon Open Source Project
<details><summary>Code of Conduct</summary> Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). http://www.apache.org/licenses/LICENSE-2.0
</details>
## FAQ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</pre>
[See our website.](https://mihon.app/) </div>
You can also reach out to us on [Discord](https://discord.gg/mihon).
## License
Copyright 2015 Javier Tomás
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Disclaimer
The developer of this application does not have any affiliation with the content providers available.

3
app/.gitignore vendored
View File

@ -1,3 +0,0 @@
/build
*iml
*.iml

View File

@ -1,20 +1,26 @@
import mihon.buildlogic.getBuildTime
import mihon.buildlogic.getCommitCount
import mihon.buildlogic.getGitSha
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("com.android.application") id("mihon.android.application")
id("com.mikepenz.aboutlibraries.plugin") id("mihon.android.application.compose")
kotlin("android")
kotlin("plugin.serialization")
id("com.github.zellius.shortcut-helper") id("com.github.zellius.shortcut-helper")
kotlin("plugin.serialization")
alias(libs.plugins.aboutLibraries)
} }
if (gradle.startParameter.taskRequests.toString().contains("Standard")) { if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
apply<com.google.gms.googleservices.GoogleServicesPlugin>() pluginManager.apply {
apply(libs.plugins.google.services.get().pluginId)
apply(libs.plugins.firebase.crashlytics.get().pluginId)
}
} }
shortcutHelper.setFilePath("./shortcuts.xml") 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 { android {
namespace = "eu.kanade.tachiyomi" namespace = "eu.kanade.tachiyomi"
@ -22,8 +28,8 @@ android {
defaultConfig { defaultConfig {
applicationId = "app.mihon" applicationId = "app.mihon"
versionCode = 1 versionCode = 7
versionName = "0.16.0" versionName = "0.16.5"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"") buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
@ -32,7 +38,7 @@ android {
buildConfigField("boolean", "PREVIEW", "false") buildConfigField("boolean", "PREVIEW", "false")
ndk { ndk {
abiFilters += SUPPORTED_ABIS abiFilters += supportedAbis
} }
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@ -42,7 +48,7 @@ android {
abi { abi {
isEnable = true isEnable = true
reset() reset()
include(*SUPPORTED_ABIS.toTypedArray()) include(*supportedAbis.toTypedArray())
isUniversalApk = true isUniversalApk = true
} }
} }
@ -102,13 +108,16 @@ android {
packaging { packaging {
resources.excludes.addAll( resources.excludes.addAll(
listOf( listOf(
"kotlin-tooling-metadata.json",
"META-INF/DEPENDENCIES", "META-INF/DEPENDENCIES",
"LICENSE.txt", "LICENSE.txt",
"META-INF/LICENSE", "META-INF/LICENSE",
"META-INF/LICENSE.txt", "META-INF/**/LICENSE.txt",
"META-INF/*.properties",
"META-INF/**/*.properties",
"META-INF/README.md", "META-INF/README.md",
"META-INF/NOTICE", "META-INF/NOTICE",
"META-INF/*.kotlin_module", "META-INF/*.version",
), ),
) )
} }
@ -119,7 +128,6 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
compose = true
buildConfig = true buildConfig = true
// Disable some unused things // Disable some unused things
@ -132,38 +140,32 @@ android {
abortOnError = false abortOnError = false
checkReleaseBuilds = false checkReleaseBuilds = false
} }
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
} }
dependencies { dependencies {
implementation(project(":i18n")) implementation(projects.i18n)
implementation(project(":core")) implementation(projects.core.archive)
implementation(project(":core-metadata")) implementation(projects.core.common)
implementation(project(":source-api")) implementation(projects.coreMetadata)
implementation(project(":source-local")) implementation(projects.sourceApi)
implementation(project(":data")) implementation(projects.sourceLocal)
implementation(project(":domain")) implementation(projects.data)
implementation(project(":presentation-core")) implementation(projects.domain)
implementation(project(":presentation-widget")) implementation(projects.presentationCore)
implementation(projects.presentationWidget)
// Compose // Compose
implementation(platform(compose.bom))
implementation(compose.activity) implementation(compose.activity)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material3.core) implementation(compose.material3.core)
implementation(compose.material.core)
implementation(compose.material.icons) implementation(compose.material.icons)
implementation(compose.animation) implementation(compose.animation)
implementation(compose.animation.graphics) implementation(compose.animation.graphics)
debugImplementation(compose.ui.tooling) debugImplementation(compose.ui.tooling)
implementation(compose.ui.tooling.preview) implementation(compose.ui.tooling.preview)
implementation(compose.ui.util) implementation(compose.ui.util)
implementation(compose.accompanist.webview)
implementation(compose.accompanist.systemuicontroller) implementation(androidx.interpolator)
lintChecks(compose.lintchecks)
implementation(androidx.paging.runtime) implementation(androidx.paging.runtime)
implementation(androidx.paging.compose) implementation(androidx.paging.compose)
@ -209,13 +211,12 @@ dependencies {
// Disk // Disk
implementation(libs.disklrucache) implementation(libs.disklrucache)
implementation(libs.unifile) implementation(libs.unifile)
implementation(libs.junrar)
// Preferences // Preferences
implementation(libs.preferencektx) implementation(libs.preferencektx)
// Dependency injection // Dependency injection
implementation(libs.injekt.core) implementation(libs.injekt)
// Image loading // Image loading
implementation(platform(libs.coil.bom)) implementation(platform(libs.coil.bom))
@ -238,12 +239,16 @@ dependencies {
implementation(libs.bundles.voyager) implementation(libs.bundles.voyager)
implementation(libs.compose.materialmotion) implementation(libs.compose.materialmotion)
implementation(libs.swipe) implementation(libs.swipe)
implementation(libs.compose.webview)
implementation(libs.compose.grid)
// Logging // Logging
implementation(libs.logcat) implementation(libs.logcat)
// Crash reports/analytics // Crash reports/analytics
"standardImplementation"(platform(libs.firebase.bom))
"standardImplementation"(libs.firebase.analytics) "standardImplementation"(libs.firebase.analytics)
"standardImplementation"(libs.firebase.crashlytics)
// Shizuku // Shizuku
implementation(libs.bundles.shizuku) implementation(libs.bundles.shizuku)
@ -254,6 +259,8 @@ dependencies {
// For detecting memory leaks; see https://square.github.io/leakcanary/ // For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation(libs.leakcanary.android) // debugImplementation(libs.leakcanary.android)
implementation(libs.leakcanary.plumber) implementation(libs.leakcanary.plumber)
testImplementation(kotlinx.coroutines.test)
} }
androidComponents { androidComponents {
@ -275,7 +282,7 @@ androidComponents {
tasks { tasks {
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers) // See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> { withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs += listOf( compilerOptions.freeCompilerArgs.addAll(
"-Xcontext-receivers", "-Xcontext-receivers",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi", "-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi", "-opt-in=androidx.compose.material.ExperimentalMaterialApi",
@ -285,26 +292,12 @@ tasks {
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi", "-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi", "-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi", "-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
"-opt-in=coil.annotation.ExperimentalCoilApi", "-opt-in=coil3.annotation.ExperimentalCoilApi",
"-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview", "-opt-in=kotlinx.coroutines.FlowPreview",
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi", "-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi", "-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
) )
if (project.findProperty("tachiyomi.enableComposeCompilerMetrics") == "true") {
kotlinOptions.freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
project.layout.buildDirectory.dir("compose_metrics").get().asFile.absolutePath,
)
kotlinOptions.freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
project.layout.buildDirectory.dir("compose_metrics").get().asFile.absolutePath,
)
}
} }
} }

View File

@ -2,6 +2,7 @@
-keep,allowoptimization class eu.kanade.** -keep,allowoptimization class eu.kanade.**
-keep,allowoptimization class tachiyomi.** -keep,allowoptimization class tachiyomi.**
-keep,allowoptimization class mihon.**
# Keep common dependencies used in extensions # Keep common dependencies used in extensions
-keep,allowoptimization class androidx.preference.** { public protected *; } -keep,allowoptimization class androidx.preference.** { public protected *; }
@ -43,6 +44,10 @@
-dontnote rx.internal.util.PlatformDependent -dontnote rx.internal.util.PlatformDependent
##---------------End: proguard configuration for RxJava 1.x ---------- ##---------------End: proguard configuration for RxJava 1.x ----------
##---------------Begin: proguard configuration for okhttp ----------
-keepclasseswithmembers class okhttp3.MultipartBody$Builder { *; }
##---------------End: proguard configuration for okhttp ----------
##---------------Begin: proguard configuration for kotlinx.serialization ---------- ##---------------Begin: proguard configuration for kotlinx.serialization ----------
-keepattributes *Annotation*, InnerClasses -keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.** # core serialization annotations -dontnote kotlinx.serialization.** # core serialization annotations

View File

@ -3,18 +3,20 @@
android:height="108dp" android:height="108dp"
android:viewportWidth="432" android:viewportWidth="432"
android:viewportHeight="432"> android:viewportHeight="432">
<group android:scaleX="0.67" <group>
android:scaleY="0.67" <clip-path
android:translateX="71.28" android:pathData="M0,0h432v432h-432z"/>
android:translateY="71.28"> <path
android:pathData="M0,0h432v432h-432z"
android:fillColor="#FAFAFA"/>
<path <path
android:pathData="M0,0h432v432h-432z" android:pathData="M0,0h432v432h-432z"
android:fillColor="#2E3943"/> android:fillColor="#2E3943"/>
<path <path
android:pathData="M377,216C377,302.16 304.92,372 216,372C127.08,372 55,302.16 55,216C55,129.84 127.08,60 216,60C304.92,60 377,129.84 377,216Z" android:pathData="M322.13,215.5C322.13,272.66 274.64,319 216.07,319C157.49,319 110,272.66 110,215.5C110,158.34 157.49,112 216.07,112C274.64,112 322.13,158.34 322.13,215.5Z"
android:fillColor="#F2FAFF"/> android:fillColor="#F2FAFF"/>
<path <path
android:pathData="M216,342.75C288.25,342.75 346.81,286 346.81,216C346.81,146 288.25,89.25 216,89.25C143.75,89.25 85.19,146 85.19,216C85.19,286 143.75,342.75 216,342.75ZM216,372C304.92,372 377,302.16 377,216C377,129.84 304.92,60 216,60C127.08,60 55,129.84 55,216C55,302.16 127.08,372 216,372Z" android:pathData="M216.07,299.59C263.66,299.59 302.24,261.94 302.24,215.5C302.24,169.06 263.66,131.41 216.07,131.41C168.47,131.41 129.89,169.06 129.89,215.5C129.89,261.94 168.47,299.59 216.07,299.59ZM216.07,319C274.64,319 322.13,272.66 322.13,215.5C322.13,158.34 274.64,112 216.07,112C157.49,112 110,158.34 110,215.5C110,272.66 157.49,319 216.07,319Z"
android:fillColor="#7EBBED" android:fillColor="#7EBBED"
android:fillType="evenOdd"/> android:fillType="evenOdd"/>
</group> </group>

View File

@ -3,12 +3,7 @@
android:height="108dp" android:height="108dp"
android:viewportWidth="432" android:viewportWidth="432"
android:viewportHeight="432"> android:viewportHeight="432">
<group android:scaleX="0.67" <path
android:scaleY="0.67" android:pathData="M182.03,188.7L181.33,172.69C183.42,173.09 185.91,173.19 191.57,173.19C198.44,173.19 207.49,172.79 212.16,172.19C214.15,171.99 214.95,171.7 216.24,171L226.98,180.15C225.98,181.54 225.68,182.14 224.59,184.92C223.7,187.11 219.62,199.74 218.03,205.11C225.39,206.6 229.46,207.7 235.03,209.98C235.73,205.11 235.83,202.52 235.83,193.67C235.83,191.39 235.73,190.09 235.43,188.01L252.74,188.6C252.24,190.99 252.14,191.98 252.04,195.86C251.64,205.21 251.24,209.68 250.25,216.45C257.11,219.93 257.11,219.93 260.59,221.82C262.38,222.81 262.78,223.01 263.97,223.41L258.2,242.01C255.42,239.52 251.54,236.83 245.87,233.65C240.9,245.49 232.65,254.14 220.12,261C215.94,255.43 212.76,252.05 207.68,248.07C215.04,244.59 218.43,242.4 222.3,238.72C226.08,235.04 228.57,231.46 230.96,226.09C224.59,223.21 220.51,221.92 213.45,220.43C209.38,232.56 206.09,240.32 203.21,244.99C199.33,251.25 194.06,254.54 187.99,254.54C183.32,254.54 178.55,252.45 175.07,248.87C171.09,244.79 169,239.12 169,232.56C169,222.81 173.67,214.36 181.83,209.09C187.1,205.71 192.67,204.21 201.52,203.72C203.31,197.85 204.8,192.78 206.19,187.11C201.82,187.51 196.35,187.81 189.68,188.1C186.1,188.2 184.91,188.3 182.03,188.7ZM197.14,218.93C192.47,219.73 189.68,221.22 187.2,224.4C185.31,226.59 184.41,229.18 184.41,231.96C184.41,235.04 185.91,237.33 187.8,237.33C190.08,237.33 192.67,232.16 197.14,218.93Z"
android:translateX="71.28" android:fillColor="#031019"/>
android:translateY="71.28">
<path
android:pathData="M162.3,173.59L161.22,148.63C164.47,149.25 168.35,149.41 177.18,149.41C187.87,149.41 201.98,148.79 209.26,147.86C212.36,147.55 213.6,147.09 215.61,146L232.35,160.26C230.8,162.43 230.34,163.36 228.63,167.7C227.24,171.11 220.88,190.79 218.4,199.16C229.87,201.48 236.22,203.18 244.9,206.75C245.99,199.16 246.14,195.13 246.14,181.33C246.14,177.77 245.99,175.76 245.52,172.5L272.49,173.43C271.71,177.15 271.56,178.7 271.4,184.74C270.78,199.31 270.16,206.29 268.61,216.82C279.31,222.25 279.31,222.25 284.73,225.19C287.52,226.74 288.14,227.05 290,227.67L281.01,256.65C276.67,252.78 270.63,248.59 261.8,243.63C254.05,262.08 241.18,275.56 221.66,286.25C215.15,277.57 210.19,272.3 202.29,266.11C213.75,260.68 219.02,257.27 225.07,251.54C230.96,245.8 234.83,240.22 238.55,231.85C228.63,227.36 222.28,225.35 211.27,223.02C204.92,241.93 199.8,254.02 195.31,261.3C189.27,271.06 181.05,276.18 171.6,276.18C164.32,276.18 156.88,272.92 151.45,267.35C145.25,260.99 142,252.16 142,241.93C142,226.74 149.28,213.57 161.99,205.35C170.21,200.09 178.88,197.76 192.68,196.99C195.47,187.84 197.79,179.94 199.96,171.11C193.14,171.73 184.62,172.19 174.24,172.65C168.66,172.81 166.8,172.96 162.3,173.59ZM185.86,220.7C178.57,221.94 174.24,224.26 170.36,229.22C167.42,232.63 166.02,236.66 166.02,241C166.02,245.8 168.35,249.37 171.29,249.37C174.85,249.37 178.88,241.31 185.86,220.7Z"
android:fillColor="#031019"/>
</group>
</vector> </vector>

View File

@ -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
}

View File

@ -33,11 +33,6 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Remove permission from Firebase dependency -->
<uses-permission
android:name="com.google.android.gms.permission.AD_ID"
tools:node="remove" />
<application <application
android:name=".App" android:name=".App"
android:allowBackup="false" android:allowBackup="false"
@ -236,11 +231,6 @@
android:name="android.webkit.WebView.MetricsOptOut" android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" /> android:value="true" />
<!-- Disable advertising ID collection for Firebase -->
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
</application> </application>
</manifest> </manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,7 +1,7 @@
package eu.kanade.core.preference package eu.kanade.core.preference
import androidx.compose.ui.state.ToggleableState import androidx.compose.ui.state.ToggleableState
import tachiyomi.core.preference.CheckboxState import tachiyomi.core.common.preference.CheckboxState
fun <T> CheckboxState.TriState<T>.asToggleableState() = when (this) { fun <T> CheckboxState.TriState<T>.asToggleableState() = when (this) {
is CheckboxState.TriState.Exclude -> ToggleableState.Indeterminate is CheckboxState.TriState.Exclude -> ToggleableState.Indeterminate

View File

@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import tachiyomi.core.preference.Preference import tachiyomi.core.common.preference.Preference
class PreferenceMutableState<T>( class PreferenceMutableState<T>(
private val preference: Preference<T>, private val preference: Preference<T>,

View File

@ -5,7 +5,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
fun <T : R, R : Any> List<T>.insertSeparators( fun <T : R, R : Any> List<T>.insertSeparators(
generator: (T?, T?) -> R?, generator: (before: T?, after: T?) -> R?,
): List<R> { ): List<R> {
if (isEmpty()) return emptyList() if (isEmpty()) return emptyList()
val newList = mutableListOf<R>() val newList = mutableListOf<R>()
@ -19,6 +19,24 @@ fun <T : R, R : Any> List<T>.insertSeparators(
return newList 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) { fun <E> HashSet<E>.addOrRemove(value: E, shouldAdd: Boolean) {
if (shouldAdd) { if (shouldAdd) {
add(value) add(value)

View File

@ -0,0 +1,13 @@
package eu.kanade.core.util
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.remember
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@Composable
fun ifSourcesLoaded(): Boolean {
return remember { Injekt.get<SourceManager>().isInitialized }.collectAsState().value
}

View File

@ -4,10 +4,7 @@ import eu.kanade.domain.chapter.interactor.GetAvailableScanlators
import eu.kanade.domain.chapter.interactor.SetReadStatus import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.download.interactor.DeleteDownload import eu.kanade.domain.download.interactor.DeleteDownload
import eu.kanade.domain.extension.interactor.CreateExtensionRepo
import eu.kanade.domain.extension.interactor.DeleteExtensionRepo
import eu.kanade.domain.extension.interactor.GetExtensionLanguages import eu.kanade.domain.extension.interactor.GetExtensionLanguages
import eu.kanade.domain.extension.interactor.GetExtensionRepos
import eu.kanade.domain.extension.interactor.GetExtensionSources import eu.kanade.domain.extension.interactor.GetExtensionSources
import eu.kanade.domain.extension.interactor.GetExtensionsByType import eu.kanade.domain.extension.interactor.GetExtensionsByType
import eu.kanade.domain.extension.interactor.TrustExtension import eu.kanade.domain.extension.interactor.TrustExtension
@ -26,6 +23,17 @@ import eu.kanade.domain.track.interactor.AddTracks
import eu.kanade.domain.track.interactor.RefreshTracks import eu.kanade.domain.track.interactor.RefreshTracks
import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack import eu.kanade.domain.track.interactor.SyncChapterProgressWithTrack
import eu.kanade.domain.track.interactor.TrackChapter import eu.kanade.domain.track.interactor.TrackChapter
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
import mihon.domain.extensionrepo.interactor.GetExtensionRepoCount
import mihon.domain.extensionrepo.interactor.ReplaceExtensionRepo
import mihon.domain.extensionrepo.interactor.UpdateExtensionRepo
import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
import mihon.domain.extensionrepo.service.ExtensionRepoService
import mihon.domain.upcoming.interactor.GetUpcomingManga
import tachiyomi.data.category.CategoryRepositoryImpl import tachiyomi.data.category.CategoryRepositoryImpl
import tachiyomi.data.chapter.ChapterRepositoryImpl import tachiyomi.data.chapter.ChapterRepositoryImpl
import tachiyomi.data.history.HistoryRepositoryImpl import tachiyomi.data.history.HistoryRepositoryImpl
@ -111,6 +119,7 @@ class DomainModule : InjektModule {
addFactory { GetMangaByUrlAndSourceId(get()) } addFactory { GetMangaByUrlAndSourceId(get()) }
addFactory { GetManga(get()) } addFactory { GetManga(get()) }
addFactory { GetNextChapters(get(), get(), get()) } addFactory { GetNextChapters(get(), get(), get()) }
addFactory { GetUpcomingManga(get()) }
addFactory { ResetViewerFlags(get()) } addFactory { ResetViewerFlags(get()) }
addFactory { SetMangaChapterFlags(get()) } addFactory { SetMangaChapterFlags(get()) }
addFactory { FetchInterval(get()) } addFactory { FetchInterval(get()) }
@ -144,6 +153,7 @@ class DomainModule : InjektModule {
addFactory { ShouldUpdateDbChapter() } addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get()) } addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get()) }
addFactory { GetAvailableScanlators(get()) } addFactory { GetAvailableScanlators(get()) }
addFactory { FilterChaptersForDownload(get(), get(), get()) }
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) } addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
addFactory { GetHistory(get()) } addFactory { GetHistory(get()) }
@ -171,10 +181,15 @@ class DomainModule : InjektModule {
addFactory { ToggleLanguage(get()) } addFactory { ToggleLanguage(get()) }
addFactory { ToggleSource(get()) } addFactory { ToggleSource(get()) }
addFactory { ToggleSourcePin(get()) } addFactory { ToggleSourcePin(get()) }
addFactory { TrustExtension(get()) } addFactory { TrustExtension(get(), get()) }
addFactory { CreateExtensionRepo(get()) } addSingletonFactory<ExtensionRepoRepository> { ExtensionRepoRepositoryImpl(get()) }
addFactory { ExtensionRepoService(get(), get()) }
addFactory { GetExtensionRepo(get()) }
addFactory { GetExtensionRepoCount(get()) }
addFactory { CreateExtensionRepo(get(), get()) }
addFactory { DeleteExtensionRepo(get()) } addFactory { DeleteExtensionRepo(get()) }
addFactory { GetExtensionRepos(get()) } addFactory { ReplaceExtensionRepo(get()) }
addFactory { UpdateExtensionRepo(get(), get()) }
} }
} }

View File

@ -2,8 +2,8 @@ package eu.kanade.domain.base
import android.content.Context import android.content.Context
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource
import tachiyomi.core.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
class BasePreferences( class BasePreferences(
@ -28,4 +28,6 @@ class BasePreferences(
SHIZUKU(MR.strings.ext_installer_shizuku, false), SHIZUKU(MR.strings.ext_installer_shizuku, false),
PRIVATE(MR.strings.ext_installer_private, false), PRIVATE(MR.strings.ext_installer_private, false),
} }
fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "")
} }

View File

@ -5,9 +5,9 @@ import eu.kanade.domain.base.BasePreferences.ExtensionInstaller
import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
import eu.kanade.tachiyomi.util.system.isShizukuInstalled import eu.kanade.tachiyomi.util.system.isShizukuInstalled
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import tachiyomi.core.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.preference.getEnum import tachiyomi.core.common.preference.getEnum
class ExtensionInstallerPreference( class ExtensionInstallerPreference(
private val context: Context, private val context: Context,

View File

@ -2,8 +2,8 @@ package eu.kanade.domain.chapter.interactor
import eu.kanade.domain.download.interactor.DeleteDownload import eu.kanade.domain.download.interactor.DeleteDownload
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.lang.withNonCancellableContext import tachiyomi.core.common.util.lang.withNonCancellableContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.ChapterUpdate import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.chapter.repository.ChapterRepository import tachiyomi.domain.chapter.repository.ChapterRepository

View File

@ -110,7 +110,10 @@ class SyncChaptersWithSource(
if (shouldUpdateDbChapter.await(dbChapter, chapter)) { if (shouldUpdateDbChapter.await(dbChapter, chapter)) {
val shouldRenameChapter = downloadProvider.isChapterDirNameChanged(dbChapter, chapter) && val shouldRenameChapter = downloadProvider.isChapterDirNameChanged(dbChapter, chapter) &&
downloadManager.isChapterDownloaded( downloadManager.isChapterDownloaded(
dbChapter.name, dbChapter.scanlator, manga.title, manga.source, dbChapter.name,
dbChapter.scanlator,
manga.title,
manga.source,
) )
if (shouldRenameChapter) { if (shouldRenameChapter) {
@ -163,7 +166,7 @@ class SyncChaptersWithSource(
var updatedToAdd = newChapters.map { toAddItem -> var updatedToAdd = newChapters.map { toAddItem ->
var chapter = toAddItem.copy(dateFetch = nowMillis + itemCount--) var chapter = toAddItem.copy(dateFetch = nowMillis + itemCount--)
if (chapter.isRecognizedNumber.not() || chapter.chapterNumber !in deletedChapterNumbers) return@map chapter if (!chapter.isRecognizedNumber || chapter.chapterNumber !in deletedChapterNumbers) return@map chapter
chapter = chapter.copy( chapter = chapter.copy(
read = chapter.chapterNumber in deletedReadChapterNumbers, read = chapter.chapterNumber in deletedReadChapterNumbers,

View File

@ -1,7 +1,7 @@
package eu.kanade.domain.download.interactor package eu.kanade.domain.download.interactor
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import tachiyomi.core.util.lang.withNonCancellableContext import tachiyomi.core.common.util.lang.withNonCancellableContext
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager

View File

@ -1,25 +0,0 @@
package eu.kanade.domain.extension.interactor
import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.plusAssign
class CreateExtensionRepo(private val preferences: SourcePreferences) {
fun await(name: String): Result {
// Do not allow invalid formats
if (!name.matches(repoRegex)) {
return Result.InvalidUrl
}
preferences.extensionRepos() += name.removeSuffix("/index.min.json")
return Result.Success
}
sealed interface Result {
data object InvalidUrl : Result
data object Success : Result
}
}
private val repoRegex = """^https://.*/index\.min\.json$""".toRegex()

View File

@ -1,11 +0,0 @@
package eu.kanade.domain.extension.interactor
import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.minusAssign
class DeleteExtensionRepo(private val preferences: SourcePreferences) {
fun await(repo: String) {
preferences.extensionRepos() -= repo
}
}

View File

@ -1,11 +0,0 @@
package eu.kanade.domain.extension.interactor
import eu.kanade.domain.source.service.SourcePreferences
import kotlinx.coroutines.flow.Flow
class GetExtensionRepos(private val preferences: SourcePreferences) {
fun subscribe(): Flow<Set<String>> {
return preferences.extensionRepos().changes()
}
}

View File

@ -23,7 +23,7 @@ class GetExtensionSources(
ExtensionSourceItem( ExtensionSourceItem(
source = source, source = source,
enabled = source.isEnabled(), enabled = source.isEnabled(),
labelAsName = isMultiSource && isMultiLangSingleSource.not(), labelAsName = isMultiSource && !isMultiLangSingleSource,
) )
} }
} }

View File

@ -20,11 +20,11 @@ class GetExtensionsByType(
extensionManager.installedExtensionsFlow, extensionManager.installedExtensionsFlow,
extensionManager.untrustedExtensionsFlow, extensionManager.untrustedExtensionsFlow,
extensionManager.availableExtensionsFlow, extensionManager.availableExtensionsFlow,
) { _activeLanguages, _installed, _untrusted, _available -> ) { enabledLanguages, _installed, _untrusted, _available ->
val (updates, installed) = _installed val (updates, installed) = _installed
.filter { (showNsfwSources || it.isNsfw.not()) } .filter { (showNsfwSources || !it.isNsfw) }
.sortedWith( .sortedWith(
compareBy<Extension.Installed> { it.isObsolete.not() } compareBy<Extension.Installed> { !it.isObsolete }
.thenBy(String.CASE_INSENSITIVE_ORDER) { it.name }, .thenBy(String.CASE_INSENSITIVE_ORDER) { it.name },
) )
.partition { it.hasUpdate } .partition { it.hasUpdate }
@ -36,13 +36,13 @@ class GetExtensionsByType(
.filter { extension -> .filter { extension ->
_installed.none { it.pkgName == extension.pkgName } && _installed.none { it.pkgName == extension.pkgName } &&
_untrusted.none { it.pkgName == extension.pkgName } && _untrusted.none { it.pkgName == extension.pkgName } &&
(showNsfwSources || extension.isNsfw.not()) (showNsfwSources || !extension.isNsfw)
} }
.flatMap { ext -> .flatMap { ext ->
if (ext.sources.isEmpty()) { if (ext.sources.isEmpty()) {
return@flatMap if (ext.lang in _activeLanguages) listOf(ext) else emptyList() return@flatMap if (ext.lang in enabledLanguages) listOf(ext) else emptyList()
} }
ext.sources.filter { it.lang in _activeLanguages } ext.sources.filter { it.lang in enabledLanguages }
.map { .map {
ext.copy( ext.copy(
name = it.name, name = it.name,

View File

@ -3,15 +3,18 @@ package eu.kanade.domain.extension.interactor
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import androidx.core.content.pm.PackageInfoCompat import androidx.core.content.pm.PackageInfoCompat
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.getAndSet import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
import tachiyomi.core.common.preference.getAndSet
class TrustExtension( class TrustExtension(
private val extensionRepoRepository: ExtensionRepoRepository,
private val preferences: SourcePreferences, private val preferences: SourcePreferences,
) { ) {
fun isTrusted(pkgInfo: PackageInfo, signatureHash: String): Boolean { suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean {
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:$signatureHash" val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet()
return key in preferences.trustedExtensions().get() val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}"
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get()
} }
fun trust(pkgName: String, versionCode: Long, signatureHash: String) { fun trust(pkgName: String, versionCode: Long, signatureHash: String) {
@ -19,9 +22,7 @@ class TrustExtension(
// Remove previously trusted versions // Remove previously trusted versions
val removed = exts.filterNot { it.startsWith("$pkgName:") }.toMutableSet() val removed = exts.filterNot { it.startsWith("$pkgName:") }.toMutableSet()
removed.also { removed.also { it += "$pkgName:$versionCode:$signatureHash" }
it += "$pkgName:$versionCode:$signatureHash"
}
} }
} }

View File

@ -5,9 +5,9 @@ import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation
import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode import eu.kanade.tachiyomi.ui.reader.setting.ReadingMode
import tachiyomi.core.common.preference.TriState
import tachiyomi.core.metadata.comicinfo.ComicInfo import tachiyomi.core.metadata.comicinfo.ComicInfo
import tachiyomi.core.metadata.comicinfo.ComicInfoPublishingStatus import tachiyomi.core.metadata.comicinfo.ComicInfoPublishingStatus
import tachiyomi.core.preference.TriState
import tachiyomi.domain.chapter.model.Chapter import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -95,7 +95,13 @@ fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
/** /**
* Creates a ComicInfo instance based on the manga and chapter metadata. * Creates a ComicInfo instance based on the manga and chapter metadata.
*/ */
fun getComicInfo(manga: Manga, chapter: Chapter, chapterUrl: String, categories: List<String>?) = ComicInfo( fun getComicInfo(
manga: Manga,
chapter: Chapter,
urls: List<String>,
categories: List<String>?,
sourceName: String,
) = ComicInfo(
title = ComicInfo.Title(chapter.name), title = ComicInfo.Title(chapter.name),
series = ComicInfo.Series(manga.title), series = ComicInfo.Series(manga.title),
number = chapter.chapterNumber.takeIf { it >= 0 }?.let { number = chapter.chapterNumber.takeIf { it >= 0 }?.let {
@ -105,7 +111,7 @@ fun getComicInfo(manga: Manga, chapter: Chapter, chapterUrl: String, categories:
ComicInfo.Number(it.toString()) ComicInfo.Number(it.toString())
} }
}, },
web = ComicInfo.Web(chapterUrl), web = ComicInfo.Web(urls.joinToString(" ")),
summary = manga.description?.let { ComicInfo.Summary(it) }, summary = manga.description?.let { ComicInfo.Summary(it) },
writer = manga.author?.let { ComicInfo.Writer(it) }, writer = manga.author?.let { ComicInfo.Writer(it) },
penciller = manga.artist?.let { ComicInfo.Penciller(it) }, penciller = manga.artist?.let { ComicInfo.Penciller(it) },
@ -115,6 +121,7 @@ fun getComicInfo(manga: Manga, chapter: Chapter, chapterUrl: String, categories:
ComicInfoPublishingStatus.toComicInfoValue(manga.status), ComicInfoPublishingStatus.toComicInfoValue(manga.status),
), ),
categories = categories?.let { ComicInfo.CategoriesTachiyomi(it.joinToString()) }, categories = categories?.let { ComicInfo.CategoriesTachiyomi(it.joinToString()) },
source = ComicInfo.SourceMihon(sourceName),
inker = null, inker = null,
colorist = null, colorist = null,
letterer = null, letterer = null,

View File

@ -3,7 +3,7 @@ package eu.kanade.domain.source.interactor
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import tachiyomi.core.util.lang.compareToWithCollator import tachiyomi.core.common.util.lang.compareToWithCollator
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.domain.source.repository.SourceRepository import tachiyomi.domain.source.repository.SourceRepository
import tachiyomi.source.local.isLocal import tachiyomi.source.local.isLocal
@ -34,15 +34,15 @@ class GetSourcesWithFavoriteCount(
when (sorting) { when (sorting) {
SetMigrateSorting.Mode.ALPHABETICAL -> { SetMigrateSorting.Mode.ALPHABETICAL -> {
when { when {
a.first.isStub && b.first.isStub.not() -> -1 a.first.isStub && !b.first.isStub -> -1
b.first.isStub && a.first.isStub.not() -> 1 b.first.isStub && !a.first.isStub -> 1
else -> a.first.name.lowercase().compareToWithCollator(b.first.name.lowercase()) else -> a.first.name.lowercase().compareToWithCollator(b.first.name.lowercase())
} }
} }
SetMigrateSorting.Mode.TOTAL -> { SetMigrateSorting.Mode.TOTAL -> {
when { when {
a.first.isStub && b.first.isStub.not() -> -1 a.first.isStub && !b.first.isStub -> -1
b.first.isStub && a.first.isStub.not() -> 1 b.first.isStub && !a.first.isStub -> 1
else -> a.second.compareTo(b.second) else -> a.second.compareTo(b.second)
} }
} }

View File

@ -1,7 +1,7 @@
package eu.kanade.domain.source.interactor package eu.kanade.domain.source.interactor
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.getAndSet import tachiyomi.core.common.preference.getAndSet
class ToggleLanguage( class ToggleLanguage(
val preferences: SourcePreferences, val preferences: SourcePreferences,

View File

@ -1,7 +1,7 @@
package eu.kanade.domain.source.interactor package eu.kanade.domain.source.interactor
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.getAndSet import tachiyomi.core.common.preference.getAndSet
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
class ToggleSource( class ToggleSource(

View File

@ -1,7 +1,7 @@
package eu.kanade.domain.source.interactor package eu.kanade.domain.source.interactor
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import tachiyomi.core.preference.getAndSet import tachiyomi.core.common.preference.getAndSet
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
class ToggleSourcePin( class ToggleSourcePin(

View File

@ -2,9 +2,9 @@ package eu.kanade.domain.source.service
import eu.kanade.domain.source.interactor.SetMigrateSorting import eu.kanade.domain.source.interactor.SetMigrateSorting
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.core.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.preference.getEnum import tachiyomi.core.common.preference.getEnum
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
class SourcePreferences( class SourcePreferences(
@ -48,4 +48,9 @@ class SourcePreferences(
Preference.appStateKey("trusted_extensions"), Preference.appStateKey("trusted_extensions"),
emptySet(), emptySet(),
) )
fun globalSearchFilterState() = preferenceStore.getBoolean(
Preference.appStateKey("has_filters_toggle_state"),
false,
)
} }

View File

@ -5,26 +5,26 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.EnhancedTracker import eu.kanade.tachiyomi.data.track.EnhancedTracker
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.TrackerManager
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.util.lang.withNonCancellableContext import tachiyomi.core.common.util.lang.withNonCancellableContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.history.interactor.GetHistory import tachiyomi.domain.history.interactor.GetHistory
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack import tachiyomi.domain.track.interactor.InsertTrack
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.time.ZoneOffset import java.time.ZoneOffset
class AddTracks( class AddTracks(
private val getTracks: GetTracks,
private val insertTrack: InsertTrack, private val insertTrack: InsertTrack,
private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack, private val syncChapterProgressWithTrack: SyncChapterProgressWithTrack,
private val getChaptersByMangaId: GetChaptersByMangaId, private val getChaptersByMangaId: GetChaptersByMangaId,
private val trackerManager: TrackerManager,
) { ) {
// TODO: update all trackers based on common data // TODO: update all trackers based on common data
@ -79,7 +79,7 @@ class AddTracks(
suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext { suspend fun bindEnhancedTrackers(manga: Manga, source: Source) = withNonCancellableContext {
withIOContext { withIOContext {
getTracks.await(manga.id) trackerManager.loggedInTrackers()
.filterIsInstance<EnhancedTracker>() .filterIsInstance<EnhancedTracker>()
.filter { it.accept(source) } .filter { it.accept(source) }
.forEach { service -> .forEach { service ->
@ -87,11 +87,11 @@ class AddTracks(
service.match(manga)?.let { track -> service.match(manga)?.let { track ->
track.manga_id = manga.id track.manga_id = manga.id
(service as Tracker).bind(track) (service as Tracker).bind(track)
insertTrack.await(track.toDomainTrack()!!) insertTrack.await(track.toDomainTrack(idRequired = false)!!)
syncChapterProgressWithTrack.await( syncChapterProgressWithTrack.await(
manga.id, manga.id,
track.toDomainTrack()!!, track.toDomainTrack(idRequired = false)!!,
service, service,
) )
} }

View File

@ -30,9 +30,9 @@ class RefreshTracks(
.map { (track, service) -> .map { (track, service) ->
async { async {
return@async try { return@async try {
val updatedTrack = service!!.refresh(track.toDbTrack()) val updatedTrack = service!!.refresh(track.toDbTrack()).toDomainTrack()!!
insertTrack.await(updatedTrack.toDomainTrack()!!) insertTrack.await(updatedTrack)
syncChapterProgressWithTrack.await(mangaId, track, service) syncChapterProgressWithTrack.await(mangaId, updatedTrack, service)
null null
} catch (e: Throwable) { } catch (e: Throwable) {
service to e service to e

View File

@ -4,12 +4,13 @@ import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.tachiyomi.data.track.EnhancedTracker import eu.kanade.tachiyomi.data.track.EnhancedTracker
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.interactor.UpdateChapter import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.toChapterUpdate import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.track.interactor.InsertTrack import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.domain.track.model.Track import tachiyomi.domain.track.model.Track
import kotlin.math.max
class SyncChapterProgressWithTrack( class SyncChapterProgressWithTrack(
private val updateChapter: UpdateChapter, private val updateChapter: UpdateChapter,
@ -36,7 +37,8 @@ class SyncChapterProgressWithTrack(
// only take into account continuous reading // only take into account continuous reading
val localLastRead = sortedChapters.takeWhile { it.read }.lastOrNull()?.chapterNumber ?: 0F 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 { try {
tracker.update(updatedTrack.toDbTrack()) tracker.update(updatedTrack.toDbTrack())

View File

@ -9,8 +9,8 @@ import eu.kanade.tachiyomi.data.track.TrackerManager
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.lang.withNonCancellableContext import tachiyomi.core.common.util.lang.withNonCancellableContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.track.interactor.GetTracks import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack import tachiyomi.domain.track.interactor.InsertTrack
@ -21,7 +21,7 @@ class TrackChapter(
private val delayedTrackingStore: DelayedTrackingStore, private val delayedTrackingStore: DelayedTrackingStore,
) { ) {
suspend fun await(context: Context, mangaId: Long, chapterNumber: Double) { suspend fun await(context: Context, mangaId: Long, chapterNumber: Double, setupJobOnFailure: Boolean = true) {
withNonCancellableContext { withNonCancellableContext {
val tracks = getTracks.await(mangaId) val tracks = getTracks.await(mangaId)
if (tracks.isEmpty()) return@withNonCancellableContext if (tracks.isEmpty()) return@withNonCancellableContext
@ -43,7 +43,9 @@ class TrackChapter(
delayedTrackingStore.remove(track.id) delayedTrackingStore.remove(track.id)
} catch (e: Exception) { } catch (e: Exception) {
delayedTrackingStore.add(track.id, chapterNumber) delayedTrackingStore.add(track.id, chapterNumber)
DelayedTrackingUpdateJob.setupTask(context) if (setupJobOnFailure) {
DelayedTrackingUpdateJob.setupTask(context)
}
throw e throw e
} }
} }

View File

@ -19,30 +19,28 @@ fun Track.toDbTrack(): DbTrack = DbTrack.create(trackerId).also {
it.remote_id = remoteId it.remote_id = remoteId
it.library_id = libraryId it.library_id = libraryId
it.title = title it.title = title
it.last_chapter_read = lastChapterRead.toFloat() it.last_chapter_read = lastChapterRead
it.total_chapters = totalChapters.toInt() it.total_chapters = totalChapters
it.status = status.toInt() it.status = status
it.score = score.toFloat() it.score = score
it.tracking_url = remoteUrl it.tracking_url = remoteUrl
it.started_reading_date = startDate it.started_reading_date = startDate
it.finished_reading_date = finishDate it.finished_reading_date = finishDate
} }
fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? { fun DbTrack.toDomainTrack(idRequired: Boolean = true): Track? {
val trackId = id ?: if (idRequired.not()) -1 else return null val trackId = id ?: if (!idRequired) -1 else return null
return Track( return Track(
id = trackId, id = trackId,
mangaId = manga_id, mangaId = manga_id,
trackerId = tracker_id.toLong(), trackerId = tracker_id,
remoteId = remote_id, remoteId = remote_id,
libraryId = library_id, libraryId = library_id,
title = title, title = title,
lastChapterRead = last_chapter_read.toDouble(), lastChapterRead = last_chapter_read,
totalChapters = total_chapters.toLong(), totalChapters = total_chapters,
status = status.toLong(), status = status,
// Jank workaround due to precision issues while converting score = score,
// See https://github.com/tachiyomiorg/tachiyomi/issues/10343
score = score.toString().toDouble(),
remoteUrl = tracking_url, remoteUrl = tracking_url,
startDate = started_reading_date, startDate = started_reading_date,
finishDate = finished_reading_date, finishDate = finished_reading_date,

View File

@ -12,8 +12,8 @@ import eu.kanade.domain.track.interactor.TrackChapter
import eu.kanade.domain.track.store.DelayedTrackingStore import eu.kanade.domain.track.store.DelayedTrackingStore
import eu.kanade.tachiyomi.util.system.workManager import eu.kanade.tachiyomi.util.system.workManager
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.track.interactor.GetTracks import tachiyomi.domain.track.interactor.GetTracks
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -45,7 +45,7 @@ class DelayedTrackingUpdateJob(private val context: Context, workerParams: Worke
logcat(LogPriority.DEBUG) { logcat(LogPriority.DEBUG) {
"Updating delayed track item: ${track.mangaId}, last chapter read: ${track.lastChapterRead}" "Updating delayed track item: ${track.mangaId}, last chapter read: ${track.lastChapterRead}"
} }
trackChapter.await(context, track.mangaId, track.lastChapterRead) trackChapter.await(context, track.mangaId, track.lastChapterRead, setupJobOnFailure = false)
} }
} }

View File

@ -2,8 +2,8 @@ package eu.kanade.domain.track.service
import eu.kanade.tachiyomi.data.track.Tracker import eu.kanade.tachiyomi.data.track.Tracker
import eu.kanade.tachiyomi.data.track.anilist.Anilist import eu.kanade.tachiyomi.data.track.anilist.Anilist
import tachiyomi.core.preference.Preference import tachiyomi.core.common.preference.Preference
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
class TrackPreferences( class TrackPreferences(
private val preferenceStore: PreferenceStore, private val preferenceStore: PreferenceStore,
@ -19,9 +19,15 @@ class TrackPreferences(
"", "",
) )
fun trackAuthExpired(tracker: Tracker) = preferenceStore.getBoolean(
Preference.privateKey("pref_tracker_auth_expired_${tracker.id}"),
false,
)
fun setCredentials(tracker: Tracker, username: String, password: String) { fun setCredentials(tracker: Tracker, username: String, password: String) {
trackUsername(tracker).set(username) trackUsername(tracker).set(username)
trackPassword(tracker).set(password) trackPassword(tracker).set(password)
trackAuthExpired(tracker).set(false)
} }
fun trackToken(tracker: Tracker) = preferenceStore.getString(Preference.privateKey("track_token_${tracker.id}"), "") fun trackToken(tracker: Tracker) = preferenceStore.getString(Preference.privateKey("track_token_${tracker.id}"), "")

View File

@ -3,7 +3,7 @@ package eu.kanade.domain.track.store
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import logcat.LogPriority import logcat.LogPriority
import tachiyomi.core.util.system.logcat import tachiyomi.core.common.util.system.logcat
class DelayedTrackingStore(context: Context) { class DelayedTrackingStore(context: Context) {

View File

@ -5,10 +5,10 @@ import eu.kanade.domain.ui.model.TabletUiMode
import eu.kanade.domain.ui.model.ThemeMode import eu.kanade.domain.ui.model.ThemeMode
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
import tachiyomi.core.preference.PreferenceStore import tachiyomi.core.common.preference.PreferenceStore
import tachiyomi.core.preference.getEnum import tachiyomi.core.common.preference.getEnum
import java.text.DateFormat import java.time.format.DateTimeFormatter
import java.text.SimpleDateFormat import java.time.format.FormatStyle
import java.util.Locale import java.util.Locale
class UiPreferences( class UiPreferences(
@ -19,7 +19,11 @@ class UiPreferences(
fun appTheme() = preferenceStore.getEnum( fun appTheme() = preferenceStore.getEnum(
"pref_app_theme", "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) fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
@ -31,9 +35,9 @@ class UiPreferences(
fun tabletUiMode() = preferenceStore.getEnum("tablet_ui_mode", TabletUiMode.AUTOMATIC) fun tabletUiMode() = preferenceStore.getEnum("tablet_ui_mode", TabletUiMode.AUTOMATIC)
companion object { companion object {
fun dateFormat(format: String): DateFormat = when (format) { fun dateFormat(format: String): DateTimeFormatter = when (format) {
"" -> DateFormat.getDateInstance(DateFormat.SHORT) "" -> DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
else -> SimpleDateFormat(format, Locale.getDefault()) else -> DateTimeFormatter.ofPattern(format, Locale.getDefault())
} }
} }
} }

View File

@ -24,7 +24,7 @@ import eu.kanade.presentation.util.formattedMessage
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import tachiyomi.core.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource

View File

@ -5,7 +5,6 @@ import android.net.Uri
import android.provider.Settings import android.provider.Settings
import android.util.DisplayMetrics import android.util.DisplayMetrics
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
@ -53,6 +52,7 @@ import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import eu.kanade.tachiyomi.util.system.copyToClipboard
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
@ -190,7 +190,7 @@ private fun ExtensionDetails(
key = { it.source.id }, key = { it.source.id },
) { source -> ) { source ->
SourceSwitchPreference( SourceSwitchPreference(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
source = source, source = source,
onClickSourcePreferences = onClickSourcePreferences, onClickSourcePreferences = onClickSourcePreferences,
onClickSource = onClickSource, onClickSource = onClickSource,
@ -224,7 +224,31 @@ private fun DetailsHeader(
end = MaterialTheme.padding.medium, end = MaterialTheme.padding.medium,
top = MaterialTheme.padding.medium, top = MaterialTheme.padding.medium,
bottom = MaterialTheme.padding.small, bottom = MaterialTheme.padding.small,
), )
.clickable {
val extDebugInfo = buildString {
append(
"""
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(),
)
if (extension is Extension.Installed) {
append("\n\n")
append(
"""
Update available: ${extension.hasUpdate}
Obsolete: ${extension.isObsolete}
Shared: ${extension.isShared}
Repository: ${extension.repoUrl}
""".trimIndent(),
)
}
}
context.copyToClipboard("Extension Debug information", extDebugInfo)
},
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
ExtensionIcon( ExtensionIcon(
@ -329,10 +353,8 @@ private fun InfoText(
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge, primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
) { ) {
val interactionSource = remember { MutableInteractionSource() }
val clickableModifier = if (onClick != null) { val clickableModifier = if (onClick != null) {
Modifier.clickable(interactionSource, indication = null) { onClick() } Modifier.clickable(interactionSource = null, indication = null, onClick = onClick)
} else { } else {
Modifier Modifier
} }

View File

@ -58,7 +58,7 @@ private fun ExtensionFilterContent(
) { ) {
items(state.languages) { language -> items(state.languages) { language ->
SwitchPreferenceWidget( SwitchPreferenceWidget(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
title = LocaleHelper.getSourceDisplayName(language, context), title = LocaleHelper.getSourceDisplayName(language, context),
checked = language in state.enabledLanguages, checked = language in state.enabledLanguages,
onCheckedChanged = { onClickLang(language) }, onCheckedChanged = { onClickLang(language) },

View File

@ -48,6 +48,7 @@ import eu.kanade.presentation.browse.components.ExtensionIcon
import eu.kanade.presentation.components.WarningBanner import eu.kanade.presentation.components.WarningBanner
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
@ -90,7 +91,7 @@ fun ExtensionScreen(
PullRefresh( PullRefresh(
refreshing = state.isRefreshing, refreshing = state.isRefreshing,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = { !state.isLoading }, enabled = !state.isLoading,
) { ) {
when { when {
state.isLoading -> LoadingScreen(Modifier.padding(contentPadding)) state.isLoading -> LoadingScreen(Modifier.padding(contentPadding))
@ -187,14 +188,14 @@ private fun ExtensionContent(
} }
ExtensionHeader( ExtensionHeader(
textRes = header.textRes, textRes = header.textRes,
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
action = action, action = action,
) )
} }
is ExtensionUiModel.Header.Text -> { is ExtensionUiModel.Header.Text -> {
ExtensionHeader( ExtensionHeader(
text = header.text, text = header.text,
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
) )
} }
} }
@ -203,16 +204,24 @@ private fun ExtensionContent(
items( items(
items = items, items = items,
contentType = { "item" }, contentType = { "item" },
key = { "extension-${it.hashCode()}" }, key = { item ->
when (item.extension) {
is Extension.Untrusted -> "extension-untrusted-${item.hashCode()}"
is Extension.Installed -> "extension-installed-${item.hashCode()}"
is Extension.Available -> "extension-available-${item.hashCode()}"
}
},
) { item -> ) { item ->
ExtensionItem( ExtensionItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
item = item, item = item,
onClickItem = { onClickItem = {
when (it) { when (it) {
is Extension.Available -> onInstallExtension(it) is Extension.Available -> onInstallExtension(it)
is Extension.Installed -> onOpenExtension(it) is Extension.Installed -> onOpenExtension(it)
is Extension.Untrusted -> { trustState = it } is Extension.Untrusted -> {
trustState = it
}
} }
}, },
onLongClickItem = onLongClickItem, onLongClickItem = onLongClickItem,
@ -234,7 +243,9 @@ private fun ExtensionContent(
onOpenExtension(it) onOpenExtension(it)
} }
} }
is Extension.Untrusted -> { trustState = it } is Extension.Untrusted -> {
trustState = it
}
} }
}, },
) )

View File

@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import eu.kanade.presentation.browse.components.GlobalSearchCardRow import eu.kanade.presentation.browse.components.GlobalSearchCardRow
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
@ -79,6 +80,7 @@ internal fun GlobalSearchContent(
} ?: source.name, } ?: source.name,
subtitle = LocaleHelper.getLocalizedDisplayName(source.lang), subtitle = LocaleHelper.getLocalizedDisplayName(source.lang),
onClick = { onClickSource(source) }, onClick = { onClickSource(source) },
modifier = Modifier.animateItem(),
) { ) {
when (result) { when (result) {
SearchItemResult.Loading -> { SearchItemResult.Loading -> {

View File

@ -133,7 +133,7 @@ private fun MigrateSourceList(
key = { (source, _) -> "migrate-${source.id}" }, key = { (source, _) -> "migrate-${source.id}" },
) { (source, count) -> ) { (source, count) ->
MigrateSourceItem( MigrateSourceItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
source = source, source = source,
count = count, count = count,
onClickItem = { onClickItem(source) }, onClickItem = { onClickItem(source) },

View File

@ -10,6 +10,7 @@ import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.browse.components.BaseSourceItem import eu.kanade.presentation.browse.components.BaseSourceItem
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget 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.ui.browse.source.SourcesFilterScreenModel
import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.system.LocaleHelper
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
@ -68,7 +69,7 @@ private fun SourcesFilterContent(
contentType = "source-filter-header", contentType = "source-filter-header",
) { ) {
SourcesFilterHeader( SourcesFilterHeader(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
language = language, language = language,
enabled = enabled, enabled = enabled,
onClickItem = onClickLanguage, onClickItem = onClickLanguage,
@ -81,7 +82,7 @@ private fun SourcesFilterContent(
contentType = { "source-filter-item" }, contentType = { "source-filter-item" },
) { source -> ) { source ->
SourcesFilterItem( SourcesFilterItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
source = source, source = source,
enabled = "${source.id}" !in state.disabledSources, enabled = "${source.id}" !in state.disabledSources,
onClickItem = onClickSource, onClickItem = onClickSource,

View File

@ -28,7 +28,7 @@ import tachiyomi.domain.source.model.Pin
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn 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.padding
import tachiyomi.presentation.core.components.material.topSmallPaddingValues import tachiyomi.presentation.core.components.material.topSmallPaddingValues
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -74,12 +74,12 @@ fun SourcesScreen(
when (model) { when (model) {
is SourceUiModel.Header -> { is SourceUiModel.Header -> {
SourceHeader( SourceHeader(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
language = model.language, language = model.language,
) )
} }
is SourceUiModel.Item -> SourceItem( is SourceUiModel.Item -> SourceItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
source = model.source, source = model.source,
onClickItem = onClickItem, onClickItem = onClickItem,
onLongClickItem = onLongClickItem, onLongClickItem = onLongClickItem,
@ -148,7 +148,7 @@ private fun SourcePinButton(
MaterialTheme.colorScheme.primary MaterialTheme.colorScheme.primary
} else { } else {
MaterialTheme.colorScheme.onBackground.copy( MaterialTheme.colorScheme.onBackground.copy(
alpha = SecondaryItemAlpha, alpha = SECONDARY_ALPHA,
) )
} }
val description = if (isPinned) MR.strings.action_unpin else MR.strings.action_pin val description = if (isPinned) MR.strings.action_unpin else MR.strings.action_pin

View File

@ -25,13 +25,13 @@ import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.graphics.drawable.toBitmap import androidx.core.graphics.drawable.toBitmap
import coil.compose.AsyncImage import coil3.compose.AsyncImage
import eu.kanade.domain.source.model.icon import eu.kanade.domain.source.model.icon
import eu.kanade.presentation.util.rememberResourceBitmapPainter import eu.kanade.presentation.util.rememberResourceBitmapPainter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.util.ExtensionLoader import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import tachiyomi.core.util.lang.withIOContext import tachiyomi.core.common.util.lang.withIOContext
import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.Source
import tachiyomi.source.local.isLocal import tachiyomi.source.local.isLocal
@ -127,7 +127,7 @@ private fun Extension.getIcon(density: Int = DisplayMetrics.DENSITY_DEFAULT): St
return produceState<Result<ImageBitmap>>(initialValue = Result.Loading, this) { return produceState<Result<ImageBitmap>>(initialValue = Result.Loading, this) {
withIOContext { withIOContext {
value = try { value = try {
val appInfo = ExtensionLoader.getExtensionPackageInfoFromPkgName(context, pkgName)!!.applicationInfo val appInfo = ExtensionLoader.getExtensionPackageInfoFromPkgName(context, pkgName)!!.applicationInfo!!
val appResources = context.packageManager.getResourcesForApplication(appInfo) val appResources = context.packageManager.getResourcesForApplication(appInfo)
Result.Success( Result.Success(
appResources.getDrawableForDensity(appInfo.icon, density, null)!! appResources.getDrawableForDensity(appInfo.icon, density, null)!!

View File

@ -32,9 +32,10 @@ fun GlobalSearchResultItem(
title: String, title: String,
subtitle: String, subtitle: String,
onClick: () -> Unit, onClick: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
Column { Column(modifier = modifier) {
Row( Row(
modifier = Modifier modifier = Modifier
.padding( .padding(

View File

@ -2,7 +2,7 @@ package eu.kanade.presentation.category
import android.content.Context import android.content.Context
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import tachiyomi.core.i18n.stringResource import tachiyomi.core.common.i18n.stringResource
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource

View File

@ -107,7 +107,7 @@ private fun CategoryContent(
key = { _, category -> "category-${category.id}" }, key = { _, category -> "category-${category.id}" },
) { index, category -> ) { index, category ->
CategoryListItem( CategoryListItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItem(),
category = category, category = category,
canMoveUp = index != 0, canMoveUp = index != 0,
canMoveDown = index != categories.lastIndex, canMoveDown = index != categories.lastIndex,

View File

@ -30,7 +30,7 @@ import eu.kanade.presentation.category.visualName
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import tachiyomi.core.preference.CheckboxState import tachiyomi.core.common.preference.CheckboxState
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding

View File

@ -10,8 +10,7 @@ import androidx.compose.ui.Modifier
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.shouldExpandFAB
import tachiyomi.presentation.core.util.isScrollingUp
@Composable @Composable
fun CategoryFloatingActionButton( fun CategoryFloatingActionButton(
@ -23,7 +22,7 @@ fun CategoryFloatingActionButton(
text = { Text(text = stringResource(MR.strings.action_add)) }, text = { Text(text = stringResource(MR.strings.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) }, icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
onClick = onCreate, onClick = onCreate,
expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(), expanded = lazyListState.shouldExpandFAB(),
modifier = modifier, modifier = modifier,
) )
} }

View File

@ -7,8 +7,6 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith import androidx.compose.animation.togetherWith
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import cafe.adriel.voyager.core.annotation.InternalVoyagerApi import cafe.adriel.voyager.core.annotation.InternalVoyagerApi
@ -23,7 +21,6 @@ import tachiyomi.presentation.core.components.AdaptiveSheet as AdaptiveSheetImpl
@Composable @Composable
fun NavigatorAdaptiveSheet( fun NavigatorAdaptiveSheet(
screen: Screen, screen: Screen,
tonalElevation: Dp = 1.dp,
enableSwipeDismiss: (Navigator) -> Boolean = { true }, enableSwipeDismiss: (Navigator) -> Boolean = { true },
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
) { ) {
@ -31,7 +28,6 @@ fun NavigatorAdaptiveSheet(
screen = screen, screen = screen,
content = { sheetNavigator -> content = { sheetNavigator ->
AdaptiveSheet( AdaptiveSheet(
tonalElevation = tonalElevation,
enableSwipeDismiss = enableSwipeDismiss(sheetNavigator), enableSwipeDismiss = enableSwipeDismiss(sheetNavigator),
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
) { ) {
@ -73,7 +69,6 @@ fun NavigatorAdaptiveSheet(
fun AdaptiveSheet( fun AdaptiveSheet(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
tonalElevation: Dp = 1.dp,
enableSwipeDismiss: Boolean = true, enableSwipeDismiss: Boolean = true,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
@ -86,7 +81,6 @@ fun AdaptiveSheet(
AdaptiveSheetImpl( AdaptiveSheetImpl(
modifier = modifier, modifier = modifier,
isTabletUi = isTabletUi, isTabletUi = isTabletUi,
tonalElevation = tonalElevation,
enableSwipeDismiss = enableSwipeDismiss, enableSwipeDismiss = enableSwipeDismiss,
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
) { ) {
@ -97,5 +91,5 @@ fun AdaptiveSheet(
private val dialogProperties = DialogProperties( private val dialogProperties = DialogProperties(
usePlatformDefaultWidth = false, usePlatformDefaultWidth = false,
decorFitsSystemWindows = false, decorFitsSystemWindows = true,
) )

View File

@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Close import androidx.compose.material.icons.outlined.Close
@ -21,6 +20,7 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
@ -179,7 +179,7 @@ fun AppBarTitle(
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
modifier = Modifier.basicMarquee( modifier = Modifier.basicMarquee(
delayMillis = 2_000, repeatDelayMillis = 2_000,
), ),
) )
} }
@ -312,7 +312,7 @@ fun SearchToolbar(
visualTransformation = visualTransformation, visualTransformation = visualTransformation,
interactionSource = interactionSource, interactionSource = interactionSource,
decorationBox = { innerTextField -> decorationBox = { innerTextField ->
TextFieldDefaults.TextFieldDecorationBox( TextFieldDefaults.DecorationBox(
value = searchQuery, value = searchQuery,
innerTextField = innerTextField, innerTextField = innerTextField,
enabled = true, enabled = true,
@ -331,6 +331,7 @@ fun SearchToolbar(
), ),
) )
}, },
container = {},
) )
}, },
) )

View File

@ -9,20 +9,26 @@ import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
@Composable @Composable
fun relativeDateText( fun relativeDateText(
dateEpochMillis: Long, dateEpochMillis: Long,
): String { ): String {
return relativeDateText( return relativeDateText(
date = Date(dateEpochMillis).takeIf { dateEpochMillis > 0L }, localDate = LocalDate.ofInstant(
Instant.ofEpochMilli(dateEpochMillis),
ZoneId.systemDefault(),
)
.takeIf { dateEpochMillis > 0L },
) )
} }
@Composable @Composable
fun relativeDateText( fun relativeDateText(
date: Date?, localDate: LocalDate?,
): String { ): String {
val context = LocalContext.current val context = LocalContext.current
@ -30,11 +36,10 @@ fun relativeDateText(
val relativeTime = remember { preferences.relativeTime().get() } val relativeTime = remember { preferences.relativeTime().get() }
val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat().get()) } val dateFormat = remember { UiPreferences.dateFormat(preferences.dateFormat().get()) }
return date return localDate?.toRelativeString(
?.toRelativeString( context = context,
context = context, relative = relativeTime,
relative = relativeTime, dateFormat = dateFormat,
dateFormat = dateFormat, )
)
?: stringResource(MR.strings.not_applicable) ?: stringResource(MR.strings.not_applicable)
} }

View File

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@ -29,7 +30,6 @@ import androidx.compose.ui.util.fastForEachIndexed
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.components.material.TabText
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -58,6 +58,7 @@ fun TabbedDialog(
PrimaryTabRow( PrimaryTabRow(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
selectedTabIndex = pagerState.currentPage, selectedTabIndex = pagerState.currentPage,
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
divider = {}, divider = {},
) { ) {
tabTitles.fastForEachIndexed { index, tab -> tabTitles.fastForEachIndexed { index, tab ->
@ -78,9 +79,8 @@ fun TabbedDialog(
modifier = Modifier.animateContentSize(), modifier = Modifier.animateContentSize(),
state = pagerState, state = pagerState,
verticalAlignment = Alignment.Top, verticalAlignment = Alignment.Top,
) { page -> pageContent = { page -> content(page) },
content(page) )
}
} }
} }
} }

View File

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PrimaryTabRow import androidx.compose.material3.PrimaryTabRow
@ -24,7 +25,6 @@ import dev.icerock.moko.resources.StringResource
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.components.material.TabText
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource

View File

@ -37,7 +37,7 @@ fun CrashScreen(
acceptText = stringResource(MR.strings.pref_dump_crash_logs), acceptText = stringResource(MR.strings.pref_dump_crash_logs),
onAcceptClick = { onAcceptClick = {
scope.launch { scope.launch {
CrashLogUtil(context).dumpLogs() CrashLogUtil(context).dumpLogs(exception)
} }
}, },
rejectText = stringResource(MR.strings.crash_screen_restart_application), rejectText = stringResource(MR.strings.crash_screen_restart_application),

View File

@ -18,6 +18,7 @@ import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.components.relativeDateText import eu.kanade.presentation.components.relativeDateText
import eu.kanade.presentation.history.components.HistoryItem import eu.kanade.presentation.history.components.HistoryItem
import eu.kanade.presentation.theme.TachiyomiPreviewTheme import eu.kanade.presentation.theme.TachiyomiPreviewTheme
import eu.kanade.presentation.util.animateItemFastScroll
import eu.kanade.tachiyomi.ui.history.HistoryScreenModel import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.history.model.HistoryWithRelations import tachiyomi.domain.history.model.HistoryWithRelations
@ -28,7 +29,7 @@ import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.screens.LoadingScreen import tachiyomi.presentation.core.screens.LoadingScreen
import java.util.Date import java.time.LocalDate
@Composable @Composable
fun HistoryScreen( fun HistoryScreen(
@ -113,14 +114,14 @@ private fun HistoryScreenContent(
when (item) { when (item) {
is HistoryUiModel.Header -> { is HistoryUiModel.Header -> {
ListGroupHeader( ListGroupHeader(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
text = relativeDateText(item.date), text = relativeDateText(item.date),
) )
} }
is HistoryUiModel.Item -> { is HistoryUiModel.Item -> {
val value = item.item val value = item.item
HistoryItem( HistoryItem(
modifier = Modifier.animateItemPlacement(), modifier = Modifier.animateItemFastScroll(),
history = value, history = value,
onClickCover = { onClickCover(value) }, onClickCover = { onClickCover(value) },
onClickResume = { onClickResume(value) }, onClickResume = { onClickResume(value) },
@ -133,7 +134,7 @@ private fun HistoryScreenContent(
} }
sealed interface HistoryUiModel { sealed interface HistoryUiModel {
data class Header(val date: Date) : HistoryUiModel data class Header(val date: LocalDate) : HistoryUiModel
data class Item(val item: HistoryWithRelations) : HistoryUiModel data class Item(val item: HistoryWithRelations) : HistoryUiModel
} }

View File

@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.ui.history.HistoryScreenModel
import tachiyomi.domain.history.model.HistoryWithRelations import tachiyomi.domain.history.model.HistoryWithRelations
import tachiyomi.domain.manga.model.MangaCover import tachiyomi.domain.manga.model.MangaCover
import java.time.Instant import java.time.Instant
import java.time.LocalDate
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
import java.util.Date import java.util.Date
import kotlin.random.Random import kotlin.random.Random
@ -71,10 +72,10 @@ class HistoryScreenModelStateProvider : PreviewParameterProvider<HistoryScreenMo
private object HistoryUiModelExamples { private object HistoryUiModelExamples {
val headerToday = header() val headerToday = header()
val headerTomorrow = val headerTomorrow =
HistoryUiModel.Header(Date.from(Instant.now().plus(1, ChronoUnit.DAYS))) HistoryUiModel.Header(LocalDate.now().plusDays(1))
fun header(instantBuilder: (Instant) -> Instant = { it }) = fun header(instantBuilder: (Instant) -> Instant = { it }) =
HistoryUiModel.Header(Date.from(instantBuilder(Instant.now()))) HistoryUiModel.Header(LocalDate.from(instantBuilder(Instant.now())))
fun items() = sequence { fun items() = sequence {
var count = 1 var count = 1

View File

@ -10,7 +10,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.StringResource
import tachiyomi.core.preference.CheckboxState import tachiyomi.core.common.preference.CheckboxState
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource

View File

@ -6,9 +6,12 @@ import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll 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.FilterChip
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -19,13 +22,14 @@ import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel
import eu.kanade.tachiyomi.util.system.isDevFlavor import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPreviewBuildType import eu.kanade.tachiyomi.util.system.isPreviewBuildType
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState import tachiyomi.core.common.preference.TriState
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibrarySort import tachiyomi.domain.library.model.LibrarySort
import tachiyomi.domain.library.model.sort import tachiyomi.domain.library.model.sort
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.BaseSortItem
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.SettingsChipRow import tachiyomi.presentation.core.components.SettingsChipRow
@ -125,7 +129,7 @@ private fun ColumnScope.FilterPage(
) )
} }
val trackers = remember { screenModel.trackers } val trackers by screenModel.trackersFlow.collectAsState()
when (trackers.size) { when (trackers.size) {
0 -> { 0 -> {
// No trackers // No trackers
@ -158,26 +162,42 @@ private fun ColumnScope.SortPage(
category: Category?, category: Category?,
screenModel: LibrarySettingsScreenModel, screenModel: LibrarySettingsScreenModel,
) { ) {
val trackers by screenModel.trackersFlow.collectAsState()
val sortingMode = category.sort.type val sortingMode = category.sort.type
val sortDescending = !category.sort.isAscending val sortDescending = !category.sort.isAscending
val trackerSortOption = val options = remember(trackers.isEmpty()) {
if (screenModel.trackers.isEmpty()) { val trackerMeanPair = if (trackers.isNotEmpty()) {
emptyList() MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean
} else { } 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,
trackerMeanPair,
MR.strings.action_sort_random to LibrarySort.Type.Random,
)
}
listOf( options.map { (titleRes, mode) ->
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical, if (mode == LibrarySort.Type.Random) {
MR.strings.action_sort_total to LibrarySort.Type.TotalChapters, BaseSortItem(
MR.strings.action_sort_last_read to LibrarySort.Type.LastRead, label = stringResource(titleRes),
MR.strings.action_sort_last_manga_update to LibrarySort.Type.LastUpdate, icon = Icons.Default.Refresh
MR.strings.action_sort_unread_count to LibrarySort.Type.UnreadCount, .takeIf { sortingMode == LibrarySort.Type.Random },
MR.strings.action_sort_latest_chapter to LibrarySort.Type.LatestChapter, onClick = {
MR.strings.action_sort_chapter_fetch_date to LibrarySort.Type.ChapterFetchDate, screenModel.setSort(category, mode, LibrarySort.Direction.Ascending)
MR.strings.action_sort_date_added to LibrarySort.Type.DateAdded, },
).plus(trackerSortOption).map { (titleRes, mode) -> )
return@map
}
SortItem( SortItem(
label = stringResource(titleRes), label = stringResource(titleRes),
sortDescending = sortDescending.takeIf { sortingMode == mode }, sortDescending = sortDescending.takeIf { sortingMode == mode },

View File

@ -35,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import eu.kanade.presentation.manga.components.MangaCover 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.components.BadgeGroup
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground import tachiyomi.presentation.core.util.selectedBackground
import tachiyomi.domain.manga.model.MangaCover as MangaCoverModel
object CommonMangaItemDefaults { object CommonMangaItemDefaults {
val GridHorizontalSpacer = 4.dp val GridHorizontalSpacer = 4.dp
val GridVerticalSpacer = 4.dp val GridVerticalSpacer = 4.dp
@Suppress("ConstPropertyName")
const val BrowseFavoriteCoverAlpha = 0.34f 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 ContinueReadingButtonGridPadding = 6.dp
private val ContinueReadingButtonListSpacing = 8.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. * Layout of grid list item with title overlaying the cover.
@ -62,7 +70,7 @@ private const val GridSelectedCoverAlpha = 0.76f
*/ */
@Composable @Composable
fun MangaCompactGridItem( fun MangaCompactGridItem(
coverData: tachiyomi.domain.manga.model.MangaCover, coverData: MangaCoverModel,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
isSelected: Boolean = false, isSelected: Boolean = false,
@ -82,7 +90,7 @@ fun MangaCompactGridItem(
MangaCover.Book( MangaCover.Book(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha), .alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
data = coverData, data = coverData,
) )
}, },
@ -96,10 +104,12 @@ fun MangaCompactGridItem(
) )
} else if (onClickContinueReading != null) { } else if (onClickContinueReading != null) {
ContinueReadingButton( ContinueReadingButton(
size = ContinueReadingButtonSizeLarge,
iconSize = ContinueReadingButtonIconSizeLarge,
onClick = onClickContinueReading,
modifier = Modifier modifier = Modifier
.padding(ContinueReadingButtonGridPadding) .padding(ContinueReadingButtonGridPadding)
.align(Alignment.BottomEnd), .align(Alignment.BottomEnd),
onClickContinueReading = onClickContinueReading,
) )
} }
}, },
@ -148,11 +158,13 @@ private fun BoxScope.CoverTextOverlay(
) )
if (onClickContinueReading != null) { if (onClickContinueReading != null) {
ContinueReadingButton( ContinueReadingButton(
size = ContinueReadingButtonSizeSmall,
iconSize = ContinueReadingButtonIconSizeSmall,
onClick = onClickContinueReading,
modifier = Modifier.padding( modifier = Modifier.padding(
end = ContinueReadingButtonGridPadding, end = ContinueReadingButtonGridPadding,
bottom = ContinueReadingButtonGridPadding, bottom = ContinueReadingButtonGridPadding,
), ),
onClickContinueReading = onClickContinueReading,
) )
} }
} }
@ -163,7 +175,7 @@ private fun BoxScope.CoverTextOverlay(
*/ */
@Composable @Composable
fun MangaComfortableGridItem( fun MangaComfortableGridItem(
coverData: tachiyomi.domain.manga.model.MangaCover, coverData: MangaCoverModel,
title: String, title: String,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
@ -185,7 +197,7 @@ fun MangaComfortableGridItem(
MangaCover.Book( MangaCover.Book(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha), .alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
data = coverData, data = coverData,
) )
}, },
@ -194,10 +206,12 @@ fun MangaComfortableGridItem(
content = { content = {
if (onClickContinueReading != null) { if (onClickContinueReading != null) {
ContinueReadingButton( ContinueReadingButton(
size = ContinueReadingButtonSizeLarge,
iconSize = ContinueReadingButtonIconSizeLarge,
onClick = onClickContinueReading,
modifier = Modifier modifier = Modifier
.padding(ContinueReadingButtonGridPadding) .padding(ContinueReadingButtonGridPadding)
.align(Alignment.BottomEnd), .align(Alignment.BottomEnd),
onClickContinueReading = onClickContinueReading,
) )
} }
}, },
@ -309,14 +323,14 @@ private fun GridItemSelectable(
private fun Modifier.selectedOutline( private fun Modifier.selectedOutline(
isSelected: Boolean, isSelected: Boolean,
color: Color, color: Color,
) = this then drawBehind { if (isSelected) drawRect(color = color) } ) = drawBehind { if (isSelected) drawRect(color = color) }
/** /**
* Layout of list item. * Layout of list item.
*/ */
@Composable @Composable
fun MangaListItem( fun MangaListItem(
coverData: tachiyomi.domain.manga.model.MangaCover, coverData: MangaCoverModel,
title: String, title: String,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
@ -354,8 +368,10 @@ fun MangaListItem(
BadgeGroup(content = badge) BadgeGroup(content = badge)
if (onClickContinueReading != null) { if (onClickContinueReading != null) {
ContinueReadingButton( ContinueReadingButton(
size = ContinueReadingButtonSizeSmall,
iconSize = ContinueReadingButtonIconSizeSmall,
onClick = onClickContinueReading,
modifier = Modifier.padding(start = ContinueReadingButtonListSpacing), modifier = Modifier.padding(start = ContinueReadingButtonListSpacing),
onClickContinueReading = onClickContinueReading,
) )
} }
} }
@ -363,23 +379,25 @@ fun MangaListItem(
@Composable @Composable
private fun ContinueReadingButton( private fun ContinueReadingButton(
size: Dp,
iconSize: Dp,
onClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClickContinueReading: () -> Unit,
) { ) {
Box(modifier = modifier) { Box(modifier = modifier) {
FilledIconButton( FilledIconButton(
onClick = onClickContinueReading, onClick = onClick,
modifier = Modifier.size(ContinueReadingButtonSize),
shape = MaterialTheme.shapes.small, shape = MaterialTheme.shapes.small,
colors = IconButtonDefaults.filledIconButtonColors( colors = IconButtonDefaults.filledIconButtonColors(
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f), containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f),
contentColor = contentColorFor(MaterialTheme.colorScheme.primaryContainer), contentColor = contentColorFor(MaterialTheme.colorScheme.primaryContainer),
), ),
modifier = Modifier.size(size),
) { ) {
Icon( Icon(
imageVector = Icons.Filled.PlayArrow, imageVector = Icons.Filled.PlayArrow,
contentDescription = stringResource(MR.strings.action_resume), contentDescription = stringResource(MR.strings.action_resume),
modifier = Modifier.size(16.dp), modifier = Modifier.size(iconSize),
) )
} }
} }

View File

@ -93,7 +93,7 @@ fun LibraryContent(
isRefreshing = false isRefreshing = false
} }
}, },
enabled = { notSelectionMode }, enabled = notSelectionMode,
) { ) {
LibraryPager( LibraryPager(
state = pagerState, state = pagerState,

View File

@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -22,7 +23,6 @@ import eu.kanade.tachiyomi.ui.library.LibraryItem
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibraryManga import tachiyomi.domain.library.model.LibraryManga
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.HorizontalPager
import tachiyomi.presentation.core.screens.EmptyScreen import tachiyomi.presentation.core.screens.EmptyScreen
import tachiyomi.presentation.core.util.plus import tachiyomi.presentation.core.util.plus

View File

@ -31,7 +31,7 @@ import eu.kanade.domain.manga.model.forceDownloaded
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings import eu.kanade.presentation.components.TabbedDialogPaddings
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.core.preference.TriState import tachiyomi.core.common.preference.TriState
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.LabeledCheckbox import tachiyomi.presentation.core.components.LabeledCheckbox

View File

@ -1,16 +1,33 @@
package eu.kanade.presentation.manga package eu.kanade.presentation.manga
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.material3.AlertDialog import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Book
import androidx.compose.material.icons.outlined.SwapVert
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.more.settings.LocalPreferenceMinHeight
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@Composable @Composable
@ -18,42 +35,92 @@ fun DuplicateMangaDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
onConfirm: () -> Unit, onConfirm: () -> Unit,
onOpenManga: () -> Unit, onOpenManga: () -> Unit,
onMigrate: () -> Unit,
modifier: Modifier = Modifier,
) { ) {
AlertDialog( val minHeight = LocalPreferenceMinHeight.current
AdaptiveSheet(
modifier = modifier,
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
title = { ) {
Text(text = stringResource(MR.strings.are_you_sure)) Column(
}, modifier = Modifier
text = { .padding(
Text(text = stringResource(MR.strings.confirm_add_duplicate_manga)) vertical = TabbedDialogPaddings.Vertical,
}, horizontal = TabbedDialogPaddings.Horizontal,
confirmButton = { )
FlowRow( .fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall), ) {
Text(
modifier = Modifier.padding(TitlePadding),
text = stringResource(MR.strings.are_you_sure),
style = MaterialTheme.typography.headlineMedium,
)
Text(
text = stringResource(MR.strings.confirm_add_duplicate_manga),
style = MaterialTheme.typography.bodyMedium,
)
Spacer(Modifier.height(PaddingSize))
TextPreferenceWidget(
title = stringResource(MR.strings.action_show_manga),
icon = Icons.Outlined.Book,
onPreferenceClick = {
onDismissRequest()
onOpenManga()
},
)
HorizontalDivider()
TextPreferenceWidget(
title = stringResource(MR.strings.action_migrate_duplicate),
icon = Icons.Outlined.SwapVert,
onPreferenceClick = {
onDismissRequest()
onMigrate()
},
)
HorizontalDivider()
TextPreferenceWidget(
title = stringResource(MR.strings.action_add_anyway),
icon = Icons.Outlined.Add,
onPreferenceClick = {
onDismissRequest()
onConfirm()
},
)
Row(
modifier = Modifier
.sizeIn(minHeight = minHeight)
.clickable { onDismissRequest.invoke() }
.padding(ButtonPadding)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
) { ) {
TextButton( OutlinedButton(onClick = onDismissRequest, modifier = Modifier.fillMaxWidth()) {
onClick = { Text(
onDismissRequest() modifier = Modifier
onOpenManga() .padding(vertical = 8.dp),
}, text = stringResource(MR.strings.action_cancel),
) { color = MaterialTheme.colorScheme.primary,
Text(text = stringResource(MR.strings.action_show_manga)) style = MaterialTheme.typography.titleLarge,
} fontSize = 16.sp,
)
Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(MR.strings.action_cancel))
}
TextButton(
onClick = {
onDismissRequest()
onConfirm()
},
) {
Text(text = stringResource(MR.strings.action_add))
} }
} }
}, }
) }
} }
private val PaddingSize = 16.dp
private val ButtonPadding = PaddingValues(top = 16.dp, bottom = 16.dp)
private val TitlePadding = PaddingValues(bottom = 16.dp, top = 8.dp)

View File

@ -75,8 +75,7 @@ import tachiyomi.presentation.core.components.material.ExtendedFloatingActionBut
import tachiyomi.presentation.core.components.material.PullRefresh import tachiyomi.presentation.core.components.material.PullRefresh
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd import tachiyomi.presentation.core.util.shouldExpandFAB
import tachiyomi.presentation.core.util.isScrollingUp
import tachiyomi.source.local.isLocal import tachiyomi.source.local.isLocal
import java.time.Instant import java.time.Instant
@ -346,7 +345,7 @@ private fun MangaScreenSmallImpl(
}, },
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) }, icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading, onClick = onContinueReading,
expanded = chapterListState.isScrollingUp() || chapterListState.isScrolledToEnd(), expanded = chapterListState.shouldExpandFAB(),
) )
} }
}, },
@ -356,7 +355,7 @@ private fun MangaScreenSmallImpl(
PullRefresh( PullRefresh(
refreshing = state.isRefreshingData, refreshing = state.isRefreshingData,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = { !isAnySelected }, enabled = !isAnySelected,
indicatorPadding = PaddingValues(top = topPadding), indicatorPadding = PaddingValues(top = topPadding),
) { ) {
val layoutDirection = LocalLayoutDirection.current val layoutDirection = LocalLayoutDirection.current
@ -381,13 +380,9 @@ private fun MangaScreenSmallImpl(
MangaInfoBox( MangaInfoBox(
isTabletUi = false, isTabletUi = false,
appBarPadding = topPadding, appBarPadding = topPadding,
title = state.manga.title, manga = state.manga,
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() }, sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is StubSource }, isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )
@ -594,7 +589,7 @@ fun MangaScreenLargeImpl(
}, },
icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) }, icon = { Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null) },
onClick = onContinueReading, onClick = onContinueReading,
expanded = chapterListState.isScrollingUp() || chapterListState.isScrolledToEnd(), expanded = chapterListState.shouldExpandFAB(),
) )
} }
}, },
@ -602,7 +597,7 @@ fun MangaScreenLargeImpl(
PullRefresh( PullRefresh(
refreshing = state.isRefreshingData, refreshing = state.isRefreshingData,
onRefresh = onRefresh, onRefresh = onRefresh,
enabled = { !isAnySelected }, enabled = !isAnySelected,
indicatorPadding = PaddingValues( indicatorPadding = PaddingValues(
start = insetPadding.calculateStartPadding(layoutDirection), start = insetPadding.calculateStartPadding(layoutDirection),
top = with(density) { topBarHeight.toDp() }, top = with(density) { topBarHeight.toDp() },
@ -623,13 +618,9 @@ fun MangaScreenLargeImpl(
MangaInfoBox( MangaInfoBox(
isTabletUi = true, isTabletUi = true,
appBarPadding = contentPadding.calculateTopPadding(), appBarPadding = contentPadding.calculateTopPadding(),
title = state.manga.title, manga = state.manga,
author = state.manga.author,
artist = state.manga.artist,
sourceName = remember { state.source.getNameForMangaInfo() }, sourceName = remember { state.source.getNameForMangaInfo() },
isStubSource = remember { state.source is StubSource }, isStubSource = remember { state.source is StubSource },
coverDataProvider = { state.manga },
status = state.manga.status,
onCoverClick = onCoverClicked, onCoverClick = onCoverClicked,
doSearch = onSearch, doSearch = onSearch,
) )

View File

@ -2,7 +2,6 @@ package eu.kanade.presentation.manga.components
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
@ -10,13 +9,13 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.outlined.ArrowDownward import androidx.compose.material.icons.outlined.ArrowDownward
import androidx.compose.material.icons.outlined.ErrorOutline import androidx.compose.material.icons.outlined.ErrorOutline
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProgressIndicatorDefaults import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -24,8 +23,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@ -91,6 +91,7 @@ private fun NotDownloadedIndicator(
.size(IconButtonTokens.StateLayerSize) .size(IconButtonTokens.StateLayerSize)
.commonClickable( .commonClickable(
enabled = enabled, enabled = enabled,
hapticFeedback = LocalHapticFeedback.current,
onLongClick = { onClick(ChapterDownloadAction.START_NOW) }, onLongClick = { onClick(ChapterDownloadAction.START_NOW) },
onClick = { onClick(ChapterDownloadAction.START) }, onClick = { onClick(ChapterDownloadAction.START) },
) )
@ -120,6 +121,7 @@ private fun DownloadingIndicator(
.size(IconButtonTokens.StateLayerSize) .size(IconButtonTokens.StateLayerSize)
.commonClickable( .commonClickable(
enabled = enabled, enabled = enabled,
hapticFeedback = LocalHapticFeedback.current,
onLongClick = { onClick(ChapterDownloadAction.CANCEL) }, onLongClick = { onClick(ChapterDownloadAction.CANCEL) },
onClick = { isMenuExpanded = true }, onClick = { isMenuExpanded = true },
), ),
@ -136,6 +138,8 @@ private fun DownloadingIndicator(
modifier = IndicatorModifier, modifier = IndicatorModifier,
color = strokeColor, color = strokeColor,
strokeWidth = IndicatorStrokeWidth, strokeWidth = IndicatorStrokeWidth,
trackColor = Color.Transparent,
strokeCap = StrokeCap.Butt,
) )
} else { } else {
val animatedProgress by animateFloatAsState( val animatedProgress by animateFloatAsState(
@ -153,6 +157,9 @@ private fun DownloadingIndicator(
modifier = IndicatorModifier, modifier = IndicatorModifier,
color = strokeColor, color = strokeColor,
strokeWidth = IndicatorSize / 2, strokeWidth = IndicatorSize / 2,
trackColor = Color.Transparent,
strokeCap = StrokeCap.Butt,
gapSize = 0.dp,
) )
} }
DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) { DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) {
@ -192,6 +199,7 @@ private fun DownloadedIndicator(
.size(IconButtonTokens.StateLayerSize) .size(IconButtonTokens.StateLayerSize)
.commonClickable( .commonClickable(
enabled = enabled, enabled = enabled,
hapticFeedback = LocalHapticFeedback.current,
onLongClick = { isMenuExpanded = true }, onLongClick = { isMenuExpanded = true },
onClick = { isMenuExpanded = true }, onClick = { isMenuExpanded = true },
), ),
@ -226,6 +234,7 @@ private fun ErrorIndicator(
.size(IconButtonTokens.StateLayerSize) .size(IconButtonTokens.StateLayerSize)
.commonClickable( .commonClickable(
enabled = enabled, enabled = enabled,
hapticFeedback = LocalHapticFeedback.current,
onLongClick = { onClick(ChapterDownloadAction.START) }, onLongClick = { onClick(ChapterDownloadAction.START) },
onClick = { onClick(ChapterDownloadAction.START) }, onClick = { onClick(ChapterDownloadAction.START) },
), ),
@ -242,26 +251,23 @@ private fun ErrorIndicator(
private fun Modifier.commonClickable( private fun Modifier.commonClickable(
enabled: Boolean, enabled: Boolean,
hapticFeedback: HapticFeedback,
onLongClick: () -> Unit, onLongClick: () -> Unit,
onClick: () -> Unit, onClick: () -> Unit,
) = composed { ) = this.combinedClickable(
val haptic = LocalHapticFeedback.current enabled = enabled,
onLongClick = {
Modifier.combinedClickable( onLongClick()
enabled = enabled, hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
onLongClick = { },
onLongClick() onClick = onClick,
haptic.performHapticFeedback(HapticFeedbackType.LongPress) role = Role.Button,
}, interactionSource = null,
onClick = onClick, indication = ripple(
role = Role.Button, bounded = false,
interactionSource = remember { MutableInteractionSource() }, radius = IconButtonTokens.StateLayerSize / 2,
indication = rememberRipple( ),
bounded = false, )
radius = IconButtonTokens.StateLayerSize / 2,
),
)
}
private val IndicatorSize = 26.dp private val IndicatorSize = 26.dp
private val IndicatorPadding = 2.dp private val IndicatorPadding = 2.dp

View File

@ -12,7 +12,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import tachiyomi.i18n.MR 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.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource import tachiyomi.presentation.core.i18n.pluralStringResource
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
@ -60,6 +60,6 @@ private fun MissingChaptersWarning(count: Int) {
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error.copy(alpha = SecondaryItemAlpha), color = MaterialTheme.colorScheme.error.copy(alpha = SECONDARY_ALPHA),
) )
} }

View File

@ -8,7 +8,6 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -30,11 +29,11 @@ import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.DoneAll import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.Download import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.RemoveDone import androidx.compose.material.icons.outlined.RemoveDone
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
@ -82,7 +81,7 @@ fun MangaBottomActionMenu(
Surface( Surface(
modifier = modifier, modifier = modifier,
shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
tonalElevation = 3.dp, color = MaterialTheme.colorScheme.surfaceContainerHigh,
) { ) {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false, false, false) } val confirm = remember { mutableStateListOf(false, false, false, false, false, false, false) }
@ -191,8 +190,8 @@ private fun RowScope.Button(
.size(48.dp) .size(48.dp)
.weight(animatedWeight) .weight(animatedWeight)
.combinedClickable( .combinedClickable(
interactionSource = remember { MutableInteractionSource() }, interactionSource = null,
indication = rememberRipple(bounded = false), indication = ripple(bounded = false),
onLongClick = onLongClick, onLongClick = onLongClick,
onClick = onClick, onClick = onClick,
), ),
@ -238,7 +237,7 @@ fun LibraryBottomActionMenu(
Surface( Surface(
modifier = modifier, modifier = modifier,
shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
tonalElevation = 3.dp, color = MaterialTheme.colorScheme.surfaceContainerHigh,
) { ) {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false) } val confirm = remember { mutableStateListOf(false, false, false, false, false) }

View File

@ -24,36 +24,26 @@ import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.text.style.TextOverflow 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.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import me.saket.swipe.SwipeableActionsBox import me.saket.swipe.SwipeableActionsBox
import me.saket.swipe.rememberSwipeableActionsState
import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.ReadItemAlpha import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.selectedBackground import tachiyomi.presentation.core.util.selectedBackground
import kotlin.math.absoluteValue
@Composable @Composable
fun MangaChapterListItem( fun MangaChapterListItem(
@ -75,142 +65,119 @@ fun MangaChapterListItem(
onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit, onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val haptic = LocalHapticFeedback.current val start = getSwipeAction(
val density = LocalDensity.current action = chapterSwipeStartAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = MaterialTheme.colorScheme.primaryContainer,
onSwipe = { onChapterSwipe(chapterSwipeStartAction) },
)
val end = getSwipeAction(
action = chapterSwipeEndAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = MaterialTheme.colorScheme.primaryContainer,
onSwipe = { onChapterSwipe(chapterSwipeEndAction) },
)
val textAlpha = if (read) ReadItemAlpha else 1f SwipeableActionsBox(
val textSubtitleAlpha = if (read) ReadItemAlpha else SecondaryItemAlpha modifier = Modifier.clipToBounds(),
startActions = listOfNotNull(start),
// Increase touch slop of swipe action to reduce accidental trigger endActions = listOfNotNull(end),
val configuration = LocalViewConfiguration.current swipeThreshold = swipeActionThreshold,
CompositionLocalProvider( backgroundUntilSwipeThreshold = MaterialTheme.colorScheme.surfaceContainerLowest,
LocalViewConfiguration provides object : ViewConfiguration by configuration {
override val touchSlop: Float = configuration.touchSlop * 3f
},
) { ) {
val start = getSwipeAction( Row(
action = chapterSwipeStartAction, modifier = modifier
read = read, .selectedBackground(selected)
bookmark = bookmark, .combinedClickable(
downloadState = downloadStateProvider(), onClick = onClick,
background = MaterialTheme.colorScheme.primaryContainer, onLongClick = onLongClick,
onSwipe = { onChapterSwipe(chapterSwipeStartAction) }, )
) .padding(start = 16.dp, top = 12.dp, end = 8.dp, bottom = 12.dp),
val end = getSwipeAction(
action = chapterSwipeEndAction,
read = read,
bookmark = bookmark,
downloadState = downloadStateProvider(),
background = MaterialTheme.colorScheme.primaryContainer,
onSwipe = { onChapterSwipe(chapterSwipeEndAction) },
)
val swipeableActionsState = rememberSwipeableActionsState()
LaunchedEffect(Unit) {
// Haptic effect when swipe over threshold
val swipeActionThresholdPx = with(density) { swipeActionThreshold.toPx() }
snapshotFlow { swipeableActionsState.offset.value.absoluteValue > swipeActionThresholdPx }
.collect { if (it) haptic.performHapticFeedback(HapticFeedbackType.LongPress) }
}
SwipeableActionsBox(
modifier = Modifier.clipToBounds(),
state = swipeableActionsState,
startActions = listOfNotNull(start),
endActions = listOfNotNull(end),
swipeThreshold = swipeActionThreshold,
backgroundUntilSwipeThreshold = MaterialTheme.colorScheme.surfaceContainerLowest,
) { ) {
Row( Column(
modifier = modifier modifier = Modifier.weight(1f),
.selectedBackground(selected) verticalArrangement = Arrangement.spacedBy(6.dp),
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
)
.padding(start = 16.dp, top = 12.dp, end = 8.dp, bottom = 12.dp),
) { ) {
Column( Row(
modifier = Modifier.weight(1f), horizontalArrangement = Arrangement.spacedBy(2.dp),
verticalArrangement = Arrangement.spacedBy(6.dp), verticalAlignment = Alignment.CenterVertically,
) { ) {
Row( var textHeight by remember { mutableIntStateOf(0) }
horizontalArrangement = Arrangement.spacedBy(2.dp), if (!read) {
verticalAlignment = Alignment.CenterVertically, Icon(
) { imageVector = Icons.Filled.Circle,
var textHeight by remember { mutableIntStateOf(0) } contentDescription = stringResource(MR.strings.unread),
if (!read) { modifier = Modifier
Icon( .height(8.dp)
imageVector = Icons.Filled.Circle, .padding(end = 4.dp),
contentDescription = stringResource(MR.strings.unread), tint = MaterialTheme.colorScheme.primary,
modifier = Modifier
.height(8.dp)
.padding(end = 4.dp),
tint = MaterialTheme.colorScheme.primary,
)
}
if (bookmark) {
Icon(
imageVector = Icons.Filled.Bookmark,
contentDescription = stringResource(MR.strings.action_filter_bookmarked),
modifier = Modifier
.sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }),
tint = MaterialTheme.colorScheme.primary,
)
}
Text(
text = title,
style = MaterialTheme.typography.bodyMedium,
color = LocalContentColor.current.copy(alpha = textAlpha),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
) )
} }
if (bookmark) {
Icon(
imageVector = Icons.Filled.Bookmark,
contentDescription = stringResource(MR.strings.action_filter_bookmarked),
modifier = Modifier
.sizeIn(maxHeight = with(LocalDensity.current) { textHeight.toDp() - 2.dp }),
tint = MaterialTheme.colorScheme.primary,
)
}
Text(
text = title,
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
onTextLayout = { textHeight = it.size.height },
color = LocalContentColor.current.copy(alpha = if (read) DISABLED_ALPHA else 1f),
)
}
Row { Row {
ProvideTextStyle( val subtitleStyle = MaterialTheme.typography.bodySmall
value = MaterialTheme.typography.bodyMedium.copy( .merge(
fontSize = 12.sp, color = LocalContentColor.current
color = LocalContentColor.current.copy(alpha = textSubtitleAlpha), .copy(alpha = if (read) DISABLED_ALPHA else SECONDARY_ALPHA),
), )
) { ProvideTextStyle(value = subtitleStyle) {
if (date != null) { if (date != null) {
Text( Text(
text = date, text = date,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
if (readProgress != null || scanlator != null) DotSeparatorText() if (readProgress != null || scanlator != null) DotSeparatorText()
} }
if (readProgress != null) { if (readProgress != null) {
Text( Text(
text = readProgress, text = readProgress,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
color = LocalContentColor.current.copy(alpha = ReadItemAlpha), color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
) )
if (scanlator != null) DotSeparatorText() if (scanlator != null) DotSeparatorText()
} }
if (scanlator != null) { if (scanlator != null) {
Text( Text(
text = scanlator, text = scanlator,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
}
} }
} }
} }
ChapterDownloadIndicator(
enabled = downloadIndicatorEnabled,
modifier = Modifier.padding(start = 4.dp),
downloadStateProvider = downloadStateProvider,
downloadProgressProvider = downloadProgressProvider,
onClick = { onDownloadClick?.invoke(it) },
)
} }
ChapterDownloadIndicator(
enabled = downloadIndicatorEnabled,
modifier = Modifier.padding(start = 4.dp),
downloadStateProvider = downloadStateProvider,
downloadProgressProvider = downloadProgressProvider,
onClick = { onDownloadClick?.invoke(it) },
)
} }
} }
} }

View File

@ -11,7 +11,7 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import coil.compose.AsyncImage import coil3.compose.AsyncImage
import eu.kanade.presentation.util.rememberResourceBitmapPainter import eu.kanade.presentation.util.rememberResourceBitmapPainter
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R

View File

@ -37,10 +37,11 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import coil.imageLoader import coil3.asDrawable
import coil.request.CachePolicy import coil3.imageLoader
import coil.request.ImageRequest import coil3.request.CachePolicy
import coil.size.Size import coil3.request.ImageRequest
import coil3.size.Size
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
@ -55,7 +56,7 @@ import tachiyomi.presentation.core.util.clickableNoIndication
@Composable @Composable
fun MangaCoverDialog( fun MangaCoverDialog(
coverDataProvider: () -> Manga, manga: Manga,
isCustomCover: Boolean, isCustomCover: Boolean,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
onShareClick: () -> Unit, onShareClick: () -> Unit,
@ -165,10 +166,12 @@ fun MangaCoverDialog(
}, },
update = { view -> update = { view ->
val request = ImageRequest.Builder(view.context) val request = ImageRequest.Builder(view.context)
.data(coverDataProvider()) .data(manga)
.size(Size.ORIGINAL) .size(Size.ORIGINAL)
.memoryCachePolicy(CachePolicy.DISABLED) .memoryCachePolicy(CachePolicy.DISABLED)
.target { drawable -> .target { image ->
val drawable = image.asDrawable(view.context.resources)
// Copy bitmap in case it came from memory cache // Copy bitmap in case it came from memory cache
// Because SSIV needs to thoroughly read the image // Because SSIV needs to thoroughly read the image
val copy = (drawable as? BitmapDrawable)?.let { val copy = (drawable as? BitmapDrawable)?.let {

View File

@ -102,9 +102,12 @@ fun SetIntervalDialog(
), ),
), ),
) )
} else {
Spacer(Modifier.height(MaterialTheme.padding.small)) Text(
stringResource(MR.strings.manga_interval_expected_update_null),
)
} }
Spacer(Modifier.height(MaterialTheme.padding.small))
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) { if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
Text(stringResource(MR.strings.manga_interval_custom_amount)) Text(stringResource(MR.strings.manga_interval_custom_amount))

View File

@ -2,6 +2,7 @@ package eu.kanade.presentation.manga.components
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateFloatAsState 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.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector import androidx.compose.animation.graphics.vector.AnimatedImageVector
@ -42,7 +43,7 @@ import androidx.compose.material.icons.outlined.Sync
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle import androidx.compose.material3.ProvideTextStyle
@ -73,13 +74,16 @@ import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.crossfade
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
import tachiyomi.presentation.core.components.material.TextButton import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.pluralStringResource import tachiyomi.presentation.core.i18n.pluralStringResource
@ -96,13 +100,9 @@ private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTIL
fun MangaInfoBox( fun MangaInfoBox(
isTabletUi: Boolean, isTabletUi: Boolean,
appBarPadding: Dp, appBarPadding: Dp,
title: String, manga: Manga,
author: String?,
artist: String?,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
coverDataProvider: () -> Manga,
status: Long,
onCoverClick: () -> Unit, onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit, doSearch: (query: String, global: Boolean) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -114,7 +114,10 @@ fun MangaInfoBox(
MaterialTheme.colorScheme.background, MaterialTheme.colorScheme.background,
) )
AsyncImage( AsyncImage(
model = coverDataProvider(), model = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = null, contentDescription = null,
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
@ -134,28 +137,20 @@ fun MangaInfoBox(
if (!isTabletUi) { if (!isTabletUi) {
MangaAndSourceTitlesSmall( MangaAndSourceTitlesSmall(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, manga = manga,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} else { } else {
MangaAndSourceTitlesLarge( MangaAndSourceTitlesLarge(
appBarPadding = appBarPadding, appBarPadding = appBarPadding,
coverDataProvider = coverDataProvider, manga = manga,
onCoverClick = onCoverClick,
title = title,
doSearch = doSearch,
author = author,
artist = artist,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
onCoverClick = onCoverClick,
doSearch = doSearch,
) )
} }
} }
@ -176,7 +171,7 @@ fun MangaActionRow(
onEditCategory: (() -> Unit)?, onEditCategory: (() -> Unit)?,
modifier: Modifier = Modifier, 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 // TODO: show something better when using custom interval
val nextUpdateDays = remember(nextUpdate) { val nextUpdateDays = remember(nextUpdate) {
@ -271,7 +266,8 @@ fun ExpandableMangaDescription(
modifier = Modifier modifier = Modifier
.padding(top = 8.dp) .padding(top = 8.dp)
.padding(vertical = 12.dp) .padding(vertical = 12.dp)
.animateContentSize(), .animateContentSize(animationSpec = spring())
.fillMaxWidth(),
) { ) {
var showMenu by remember { mutableStateOf(false) } var showMenu by remember { mutableStateOf(false) }
var tagSelected by remember { mutableStateOf("") } var tagSelected by remember { mutableStateOf("") }
@ -335,15 +331,11 @@ fun ExpandableMangaDescription(
@Composable @Composable
private fun MangaAndSourceTitlesLarge( private fun MangaAndSourceTitlesLarge(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Manga, manga: Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
@ -353,19 +345,22 @@ private fun MangaAndSourceTitlesLarge(
) { ) {
MangaCover.Book( MangaCover.Book(
modifier = Modifier.fillMaxWidth(0.65f), modifier = Modifier.fillMaxWidth(0.65f),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
MangaContentInfo( MangaContentInfo(
title = title, title = manga.title,
doSearch = doSearch, author = manga.author,
author = author, artist = manga.artist,
artist = artist, status = manga.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }
@ -374,15 +369,11 @@ private fun MangaAndSourceTitlesLarge(
@Composable @Composable
private fun MangaAndSourceTitlesSmall( private fun MangaAndSourceTitlesSmall(
appBarPadding: Dp, appBarPadding: Dp,
coverDataProvider: () -> Manga, manga: Manga,
onCoverClick: () -> Unit,
title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?,
artist: String?,
status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
onCoverClick: () -> Unit,
doSearch: (query: String, global: Boolean) -> Unit,
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@ -395,7 +386,10 @@ private fun MangaAndSourceTitlesSmall(
modifier = Modifier modifier = Modifier
.sizeIn(maxWidth = 100.dp) .sizeIn(maxWidth = 100.dp)
.align(Alignment.Top), .align(Alignment.Top),
data = coverDataProvider(), data = ImageRequest.Builder(LocalContext.current)
.data(manga)
.crossfade(true)
.build(),
contentDescription = stringResource(MR.strings.manga_cover), contentDescription = stringResource(MR.strings.manga_cover),
onClick = onCoverClick, onClick = onCoverClick,
) )
@ -403,13 +397,13 @@ private fun MangaAndSourceTitlesSmall(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
) { ) {
MangaContentInfo( MangaContentInfo(
title = title, title = manga.title,
doSearch = doSearch, author = manga.author,
author = author, artist = manga.artist,
artist = artist, status = manga.status,
status = status,
sourceName = sourceName, sourceName = sourceName,
isStubSource = isStubSource, isStubSource = isStubSource,
doSearch = doSearch,
) )
} }
} }
@ -418,12 +412,12 @@ private fun MangaAndSourceTitlesSmall(
@Composable @Composable
private fun ColumnScope.MangaContentInfo( private fun ColumnScope.MangaContentInfo(
title: String, title: String,
doSearch: (query: String, global: Boolean) -> Unit,
author: String?, author: String?,
artist: String?, artist: String?,
status: Long, status: Long,
sourceName: String, sourceName: String,
isStubSource: Boolean, isStubSource: Boolean,
doSearch: (query: String, global: Boolean) -> Unit,
textAlign: TextAlign? = LocalTextStyle.current.textAlign, textAlign: TextAlign? = LocalTextStyle.current.textAlign,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -649,7 +643,7 @@ private fun TagsChip(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
SuggestionChip( SuggestionChip(
modifier = modifier, modifier = modifier,
onClick = onClick, onClick = onClick,

View File

@ -31,8 +31,6 @@ import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.material.TextButton import tachiyomi.presentation.core.components.material.TextButton
import tachiyomi.presentation.core.components.material.padding import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.isScrolledToEnd
import tachiyomi.presentation.core.util.isScrolledToStart
@Composable @Composable
fun ScanlatorFilterDialog( fun ScanlatorFilterDialog(
@ -96,8 +94,8 @@ fun ScanlatorFilterDialog(
} }
} }
} }
if (!state.isScrolledToStart()) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter)) if (state.canScrollBackward) HorizontalDivider(modifier = Modifier.align(Alignment.TopCenter))
if (!state.isScrolledToEnd()) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter)) if (state.canScrollForward) HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
} }
}, },
properties = DialogProperties( properties = DialogProperties(
@ -110,8 +108,14 @@ fun ScanlatorFilterDialog(
} }
} else { } else {
FlowRow { FlowRow {
TextButton(onClick = mutableExcludedScanlators::clear) { if (mutableExcludedScanlators.isEmpty()) {
Text(text = stringResource(MR.strings.action_reset)) 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)) Spacer(modifier = Modifier.weight(1f))
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {

View File

@ -26,7 +26,7 @@ import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget import eu.kanade.presentation.more.settings.widget.TextPreferenceWidget
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.more.DownloadQueueState import eu.kanade.tachiyomi.ui.more.DownloadQueueState
import tachiyomi.core.Constants import tachiyomi.core.common.Constants
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold

View File

@ -75,7 +75,7 @@ private fun NewUpdateScreenPreview() {
changelogInfo = """ changelogInfo = """
## Yay ## Yay
Foobar Foobar
### More info ### More info
- Hello - Hello
- World - World

View File

@ -14,11 +14,13 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
@ -28,19 +30,24 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState import eu.kanade.presentation.util.rememberRequestPackageInstallsPermissionState
import eu.kanade.tachiyomi.core.security.PrivacyPreferences
import eu.kanade.tachiyomi.util.system.launchRequestPackageInstallsPermission import eu.kanade.tachiyomi.util.system.launchRequestPackageInstallsPermission
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.util.secondaryItemAlpha
import uy.kohesive.injekt.injectLazy
internal class PermissionStep : OnboardingStep { internal class PermissionStep : OnboardingStep {
private val privacyPreferences: PrivacyPreferences by injectLazy()
private var notificationGranted by mutableStateOf(false) private var notificationGranted by mutableStateOf(false)
private var batteryGranted by mutableStateOf(false) private var batteryGranted by mutableStateOf(false)
@ -73,7 +80,7 @@ internal class PermissionStep : OnboardingStep {
} }
Column { Column {
PermissionItem( PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_install_apps), title = stringResource(MR.strings.onboarding_permission_install_apps),
subtitle = stringResource(MR.strings.onboarding_permission_install_apps_description), subtitle = stringResource(MR.strings.onboarding_permission_install_apps_description),
granted = installGranted, granted = installGranted,
@ -89,7 +96,7 @@ internal class PermissionStep : OnboardingStep {
// no-op. resulting checks is being done on resume // no-op. resulting checks is being done on resume
}, },
) )
PermissionItem( PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_notifications), title = stringResource(MR.strings.onboarding_permission_notifications),
subtitle = stringResource(MR.strings.onboarding_permission_notifications_description), subtitle = stringResource(MR.strings.onboarding_permission_notifications_description),
granted = notificationGranted, granted = notificationGranted,
@ -97,7 +104,7 @@ internal class PermissionStep : OnboardingStep {
) )
} }
PermissionItem( PermissionCheckbox(
title = stringResource(MR.strings.onboarding_permission_ignore_battery_opts), title = stringResource(MR.strings.onboarding_permission_ignore_battery_opts),
subtitle = stringResource(MR.strings.onboarding_permission_ignore_battery_opts_description), subtitle = stringResource(MR.strings.onboarding_permission_ignore_battery_opts_description),
granted = batteryGranted, granted = batteryGranted,
@ -109,6 +116,29 @@ internal class PermissionStep : OnboardingStep {
context.startActivity(intent) 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 @Composable
private fun PermissionItem( private fun PermissionCheckbox(
title: String, title: String,
subtitle: String, subtitle: String,
granted: Boolean, granted: Boolean,
@ -157,4 +187,26 @@ internal class PermissionStep : OnboardingStep {
colors = ListItemDefaults.colors(containerColor = Color.Transparent), 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),
)
}
} }

View File

@ -8,7 +8,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.core.preference.Preference as PreferenceData import tachiyomi.core.common.preference.Preference as PreferenceData
sealed class Preference { sealed class Preference {
abstract val title: String abstract val title: String

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