Compare commits
272 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dea38912fc | |||
| 5243346356 | |||
| 6bb3ec5b8a | |||
| 7390e72045 | |||
| 64ff5cb9af | |||
| 82f011e48e | |||
| 8868a5db2b | |||
| a335feedfc | |||
| 90ff5e69ec | |||
| 68a1820695 | |||
| 292b551027 | |||
| e19c62a8ae | |||
| 348cb335c4 | |||
| c426d11d76 | |||
| 1965c0825d | |||
| 0124763fcd | |||
| b0d737592c | |||
| e14596465b | |||
| 5e52dfcc66 | |||
| a09643fc77 | |||
| 19bc08659b | |||
| 2cb8f8f872 | |||
| 23c7bb09d3 | |||
| bdb8553e28 | |||
| fbac29e0cd | |||
| b0aa2ffc42 | |||
| 45b5d9b8a4 | |||
| 91b98cdb82 | |||
| 7f544f7163 | |||
| 3705880a77 | |||
| 759fd4d4e3 | |||
| fc956fc791 | |||
| 9d7346157b | |||
| 0f0f4cf4a9 | |||
| 426ef65102 | |||
| 95c834581b | |||
| 71f2daf8f3 | |||
| 7ec14cd9f0 | |||
| c23c9491fc | |||
| 29f3766c87 | |||
| 07c89890bc | |||
| 64a54f55b3 | |||
| f7202e67cc | |||
| 155b03c176 | |||
| 6b0482576b | |||
| c137bafd68 | |||
| 49bdffdc28 | |||
| f1b32d531a | |||
| a5ec6c5cdd | |||
| 9c56cdb1c1 | |||
| 543de065a6 | |||
| 33296e1faf | |||
| d1a90c0bb7 | |||
| 9fa61d33be | |||
| 0e9dcc7855 | |||
| 6738c6072d | |||
| 29033c539c | |||
| eaa3413c37 | |||
| 73d9d1d46d | |||
| 94f9aaf351 | |||
| e21149cb37 | |||
| 11aad16f59 | |||
| 33a3918e86 | |||
| d655b8ecdf | |||
| 70a8bef7a5 | |||
| 999a8613cf | |||
| 5721a02bca | |||
| e303b88b90 | |||
| a62dd5821a | |||
| a0786d9b09 | |||
| 04580ce357 | |||
| b759f2f02a | |||
| 8ae8068ecd | |||
| eecd9367d4 | |||
| 55dee69838 | |||
| a730ca5444 | |||
| cebd8fe0a8 | |||
| 55a979c5f7 | |||
| 728f3fc349 | |||
| a9a3ed1d16 | |||
| 36f13a7c6a | |||
| 37a2ccc678 | |||
| bb39088dd7 | |||
| c5546e1095 | |||
| 2d12c670db | |||
| 3db4bccebc | |||
| 2f23ad6bfd | |||
| de1898a2c9 | |||
| eb135ec22d | |||
| bf6c646dc7 | |||
| 9ce16d5e1c | |||
| 619ff726c8 | |||
| 730ceaaf49 | |||
| 07b701cb3c | |||
| b64c6b78ea | |||
| 521bce5c08 | |||
| a719ed8c9e | |||
| f6fc2d7e2f | |||
| 48d43c4f07 | |||
| f4fa86b2dc | |||
| 37db0dc1f6 | |||
| 1ada03b07a | |||
| f4c1e7c2d5 | |||
| 6c5282c598 | |||
| 7899474a36 | |||
| 225b419bba | |||
| fa64103a1c | |||
| 57e0e99f06 | |||
| efde7afa8e | |||
| f929a4bc26 | |||
| d35141c1cc | |||
| 6988966019 | |||
| f6d8ebbb0a | |||
| ae45df9fcf | |||
| f332344681 | |||
| c6abb340ca | |||
| 99dbb16a7a | |||
| f62e8933d7 | |||
| ee3c2fd79c | |||
| 6b08b873a8 | |||
| a3f2f49ab8 | |||
| 524f5cc6ab | |||
| a35e084b9e | |||
| 78f7fba67b | |||
| 69d1db3018 | |||
| d1b317e5c8 | |||
| fff40e031f | |||
| 5be2ec51ba | |||
| 1c2a7af13e | |||
| 182158acb0 | |||
| 21f92bfb3a | |||
| a5522ef732 | |||
| 239793f7fd | |||
| 4e9cfe4602 | |||
| f548c85e7a | |||
| 576349c446 | |||
| 9b00e0458b | |||
| 6a1ff99441 | |||
| 0121fe9397 | |||
| 5c47c7a409 | |||
| 8bb4f33f2e | |||
| 5f5fd51668 | |||
| c7bbad93b2 | |||
| 1a4a2506f4 | |||
| 7b7a594ddb | |||
| c2eece0fff | |||
| d29a4ff381 | |||
| 31f967235f | |||
| 7d6e746257 | |||
| d306139047 | |||
| 7e6811692e | |||
| 8df0446020 | |||
| 8ccf8fc74d | |||
| 4deaa41c53 | |||
| c843789f66 | |||
| 78da81fa42 | |||
| 4fc96f263d | |||
| 6a12b54ecb | |||
| 8ffcd5efec | |||
| 26121efeb4 | |||
| 1ecf3a567b | |||
| 20fff5798d | |||
| 0ba580ba30 | |||
| aaf28ee4f1 | |||
| 8558c110a9 | |||
| 3865583c28 | |||
| b2cc61f6fd | |||
| 47dd58de2a | |||
| 67d42c9c2b | |||
| b97f322d6f | |||
| d8cc4f8b45 | |||
| f78752fbdf | |||
| d968d58cd6 | |||
| 54d5f9baaf | |||
| c1bf53e28a | |||
| 517fd3a8f4 | |||
| 089d1aba57 | |||
| 46bf139f01 | |||
| c3fb5c0bec | |||
| 000a4ffc3f | |||
| 7b0b879d65 | |||
| 8a622f6c7d | |||
| 253060a3bc | |||
| b6b33e8c00 | |||
| 2e4f811090 | |||
| 215a1908f7 | |||
| 082acf000c | |||
| 2d1240b274 | |||
| 1e98709cc3 | |||
| 5550ddad4e | |||
| f9148c0c5e | |||
| 089e6268e7 | |||
| 712cd1493f | |||
| bbc8adc3e8 | |||
| 077b673c0a | |||
| 49eacf5178 | |||
| 98d1dddf4a | |||
| 37a616f3db | |||
| ad18696a1a | |||
| 34bb012a1c | |||
| 08c4989aa3 | |||
| 14dae420f5 | |||
| 65ed3c5ae6 | |||
| 5ae3508665 | |||
| e32eb0e009 | |||
| e0812ab5c8 | |||
| df9f79c120 | |||
| 990eb33b98 | |||
| e1bab1172a | |||
| aeeff72bed | |||
| 5895e78b39 | |||
| b24719a3e9 | |||
| d551619d9d | |||
| 06ad6c2e16 | |||
| df7e470e08 | |||
| 03f32ebffd | |||
| ed20d25452 | |||
| 596a8d002f | |||
| 206d824ed2 | |||
| 97ed4e55ad | |||
| 739f7bc848 | |||
| e866e60b19 | |||
| f135daeca5 | |||
| d80c19eb03 | |||
| 2d47147172 | |||
| de3570107e | |||
| 5480495619 | |||
| 694ef5f285 | |||
| 472c97c580 | |||
| 8b098b38f8 | |||
| 5e0585d724 | |||
| 3e438a9e87 | |||
| 8046c1a540 | |||
| 1f3f6cd4df | |||
| a62a5ed650 | |||
| a320903bc0 | |||
| a6c4f01c74 | |||
| a657c65261 | |||
| 5455daf96b | |||
| d40bc2b41b | |||
| 527ca85c39 | |||
| 189714eaf1 | |||
| 90d5104bdc | |||
| ceff887a10 | |||
| 2197bd0451 | |||
| 861a810961 | |||
| 81984c25df | |||
| b21d685a37 | |||
| fb4d9209f8 | |||
| 9ee0034c9a | |||
| 268b483182 | |||
| 2af6e7be32 | |||
| 3ecf86ae35 | |||
| 41bb0e08ba | |||
| 0bb1eb2da1 | |||
| 919df9a7cf | |||
| 2ea488bff5 | |||
| ec30ccccc2 | |||
| 780bdcbe55 | |||
| a90bc4c7fa | |||
| 5e421c6f0e | |||
| 742fdc19ca | |||
| 74505565ef | |||
| f041ed5b2a | |||
| 8762b20ab6 | |||
| 5a71889679 | |||
| a4983eb004 | |||
| 818bc7f75a | |||
| 7de6fa8c23 | |||
| edca9039e5 | |||
| fb1649125c | |||
| 0767526f18 |
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"labels": ["Dependencies"],
|
||||
"includePaths": [".github/workflows/*", "gradle/sy.versions.toml"],
|
||||
}
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
build:
|
||||
name: Build app
|
||||
@@ -27,19 +27,19 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: adopt
|
||||
|
||||
- name: Set up gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
- name: Build app
|
||||
run: ./gradlew detekt assembleDevDebug
|
||||
run: ./gradlew spotlessCheck assembleDevDebug
|
||||
|
||||
- name: Upload APK
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: TachiyomiSY-${{ github.sha }}.apk
|
||||
path: app/build/outputs/apk/dev/debug/app-dev-debug.apk
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
- name: Setup Android SDK
|
||||
run: |
|
||||
@@ -31,18 +31,18 @@ jobs:
|
||||
distribution: adopt
|
||||
|
||||
- name: Set up gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
|
||||
# SY <--
|
||||
- name: Write google-services.json
|
||||
uses: DamianReeves/write-file-action@v1.2
|
||||
uses: DamianReeves/write-file-action@v1.3
|
||||
with:
|
||||
path: app/google-services.json
|
||||
contents: ${{ secrets.GOOGLE_SERVICES_TEXT }}
|
||||
write-mode: overwrite
|
||||
|
||||
- name: Write client_secrets.json
|
||||
uses: DamianReeves/write-file-action@v1.2
|
||||
uses: DamianReeves/write-file-action@v1.3
|
||||
with:
|
||||
path: app/src/main/assets/client_secrets.json
|
||||
contents: ${{ secrets.CLIENT_SECRETS_TEXT }}
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
# SY -->
|
||||
|
||||
- name: Build app and run unit tests
|
||||
run: ./gradlew detekt assembleStandardRelease testStandardReleaseUnitTest --stacktrace
|
||||
run: ./gradlew spotlessCheck assembleStandardRelease testStandardReleaseUnitTest --stacktrace
|
||||
|
||||
- name: Sign APK
|
||||
uses: r0adkll/sign-android-release@v1
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
echo "APK_X86_64_SHA=$sha" >> $GITHUB_ENV
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.run_number }}
|
||||
name: TachiyomiSY
|
||||
|
||||
@@ -3,12 +3,11 @@ name: Remote Dispatch Action Initiator
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'preview'
|
||||
|
||||
jobs:
|
||||
trigger_preview_build:
|
||||
name: Trigger preview build
|
||||
if: ${{ github.ref == 'refs/heads/master' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -16,7 +15,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
- name: Create Tag
|
||||
run: |
|
||||
|
||||
@@ -40,6 +40,12 @@ jobs:
|
||||
"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."
|
||||
},
|
||||
{
|
||||
"type": "both",
|
||||
"regex": "^.*(myanimelist|mal).*$",
|
||||
"ignoreCase": true,
|
||||
"message": "For issues with linking MyAnimeList, please follow these steps:\n1. Update Mihon to version 0.16.4 or newer\n2. Change your default User-Agent (`More → Settings → Advanced → Default user agent string`)\n3. Close and restart Mihon\n4. Attempt to link MyAnimeList again\n\nIf you had MyAnimeList linked before, try to unlink it first before trying these steps."
|
||||
}
|
||||
]
|
||||
auto-close-ignore-label: do-not-autoclose
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Label PRs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
label_pr:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check PR and Add Label
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const prAuthor = context.payload.pull_request.user.login;
|
||||
|
||||
if (prAuthor === 'weblate') {
|
||||
const labels = ['Translations'];
|
||||
await github.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
labels: labels
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
.gradle
|
||||
.kotlin
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
.DS_Store
|
||||
|
||||
+7
-14
@@ -1,4 +1,4 @@
|
||||
Looking to report an issue/bug or make a feature request? Please refer to the [README file](https://github.com/tachiyomiorg/tachiyomi#issues-feature-requests-and-contributing).
|
||||
Looking to report an issue/bug or make a feature request? Please refer to the [README file](/README.md#issues-feature-requests-and-contributing).
|
||||
|
||||
---
|
||||
|
||||
@@ -9,7 +9,7 @@ Thanks for your interest in contributing to Tachiyomi!
|
||||
|
||||
Pull requests are welcome!
|
||||
|
||||
If you're interested in taking on [an open issue](https://github.com/tachiyomiorg/tachiyomi/issues), please comment on it so others are aware.
|
||||
If you're interested in taking on [an open issue](https://github.com/jobobby04/TachiyomiSY/issues), please comment on it so others are aware.
|
||||
You do not need to ask for permission nor an assignment.
|
||||
|
||||
## Prerequisites
|
||||
@@ -24,34 +24,27 @@ Before you start, please note that the ability to use following technologies is
|
||||
- [Android Studio](https://developer.android.com/studio)
|
||||
- Emulator or phone with developer options enabled to test changes.
|
||||
|
||||
## Linting
|
||||
|
||||
To auto-fix some linting errors, run the `ktlintFormat` Gradle task.
|
||||
|
||||
## Getting help
|
||||
|
||||
- Join [the Discord server](https://discord.gg/tachiyomi) for online help and to ask questions while developing.
|
||||
- Join [the Discord server](https://discord.gg/mihon) for online help and to ask questions while developing.
|
||||
|
||||
# Translations
|
||||
|
||||
Translations are done externally via Weblate. See [our website](https://tachiyomi.org/docs/contribute#translation) for more details.
|
||||
Translations are done externally via Weblate. See [our website](https://mihon.app/docs/contribute#translation) for more details.
|
||||
|
||||
|
||||
# Forks
|
||||
|
||||
Forks are allowed so long as they abide by [the project's LICENSE](https://github.com/tachiyomiorg/tachiyomi/blob/master/LICENSE).
|
||||
Forks are allowed so long as they abide by [the project's LICENSE](/LICENSE).
|
||||
|
||||
When creating a fork, remember to:
|
||||
|
||||
- To avoid confusion with the main app:
|
||||
- Change the app name
|
||||
- Change the app icon
|
||||
- Change or disable the [app update checker](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt)
|
||||
- Change or disable the [app update checker](/app/src/main/java/eu/kanade/tachiyomi/data/updater/AppUpdateChecker.kt)
|
||||
- To avoid installation conflicts:
|
||||
- Change the `applicationId` in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts)
|
||||
- To avoid having your data polluting the main app's analytics and crash report services:
|
||||
- If you want to use Firebase analytics, replace [`google-services.json`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/standard/google-services.json) with your own
|
||||
- If you want to use ACRA crash reporting, replace the `ACRA_URI` endpoint in [`build.gradle.kts`](https://github.com/tachiyomiorg/tachiyomi/blob/master/app/build.gradle.kts) with your own
|
||||
- Change the `applicationId` in [`build.gradle.kts`](/app/build.gradle.kts)
|
||||
|
||||
|
||||
### Supporting Cloud Sync - Google Drive Implementation
|
||||
|
||||
@@ -14,7 +14,7 @@ Features of Mihon(original) include:
|
||||
* Online reading from a variety of sources
|
||||
* Local reading of downloaded content
|
||||
* A configurable reader with multiple viewers, reading directions and other settings.
|
||||
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.io/), [MangaUpdates](https://mangaupdates.com), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
|
||||
* Tracker support: [MyAnimeList](https://myanimelist.net/), [AniList](https://anilist.co/), [Kitsu](https://kitsu.app/), [MangaUpdates](https://mangaupdates.com), [Shikimori](https://shikimori.one), and [Bangumi](https://bgm.tv/) support
|
||||
* Categories to organize your library
|
||||
* Light and dark themes
|
||||
* Schedule updating your library for new chapters
|
||||
@@ -67,13 +67,22 @@ Get the app from our [releases page](https://github.com/jobobby04/tachiyomisy/re
|
||||
|
||||
If you want to try new features before they get to the stable release, you can download the preview version [here](https://github.com/jobobby04/tachiyomisypreview/releases).
|
||||
|
||||
## Translation
|
||||
Feel free to translate the project on [Weblate](https://hosted.weblate.org/projects/mihon/tachiyomisy/)
|
||||
|
||||
<details><summary>Translation Progress</summary>
|
||||
<a href="https://hosted.weblate.org/engage/mihon/">
|
||||
<img src="https://hosted.weblate.org/widgets/mihon/-/tachiyomisy/multi-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
</details>
|
||||
|
||||
## Issues, Feature Requests and Contributing
|
||||
|
||||
Please make sure to read the full guidelines. Your issue may be closed without warning if you do not.
|
||||
|
||||
<details><summary>Issues</summary>
|
||||
|
||||
1. **Before reporting a new issue, take a look at the [FAQ](https://tachiyomi.org/docs/faq/general), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
|
||||
1. **Before reporting a new issue, take a look at the [FAQ](https://mihon.app/docs/faq/general), the [changelog](https://github.com/jobobby04/tachiyomisy/releases) and the already opened [issues](https://github.com/jobobby04/tachiyomisy/issues).**
|
||||
2. If you are unsure, ask here: [](https://discord.gg/mihon)
|
||||
|
||||
</details>
|
||||
@@ -88,9 +97,7 @@ Please make sure to read the full guidelines. Your issue may be closed without w
|
||||
* If it could be device-dependent, try reproducing on another device (if possible)
|
||||
* Don't group unrelated requests into one issue
|
||||
|
||||
DO: https://github.com/tachiyomiorg/tachiyomi/issues/24 https://github.com/tachiyomiorg/tachiyomi/issues/71
|
||||
|
||||
DON'T: https://github.com/tachiyomiorg/tachiyomi/issues/75
|
||||
Use the [issue forms](https://github.com/jobobby04/TachiyomiSY/issues/new/choose) to submit a bug.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
+21
-44
@@ -1,9 +1,12 @@
|
||||
import mihon.buildlogic.getBuildTime
|
||||
import mihon.buildlogic.getCommitCount
|
||||
import mihon.buildlogic.getGitSha
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("mihon.android.application")
|
||||
id("mihon.android.application.compose")
|
||||
id("com.mikepenz.aboutlibraries.plugin")
|
||||
kotlin("android")
|
||||
kotlin("plugin.parcelize")
|
||||
kotlin("plugin.serialization")
|
||||
// id("com.github.zellius.shortcut-helper")
|
||||
@@ -18,7 +21,7 @@ if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
|
||||
|
||||
// shortcutHelper.setFilePath("./shortcuts.xml")
|
||||
|
||||
val SUPPORTED_ABIS = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
val supportedAbis = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
|
||||
android {
|
||||
namespace = "eu.kanade.tachiyomi"
|
||||
@@ -26,7 +29,7 @@ android {
|
||||
defaultConfig {
|
||||
applicationId = "eu.kanade.tachiyomi.sy"
|
||||
|
||||
versionCode = 66
|
||||
versionCode = 69
|
||||
versionName = "1.10.5"
|
||||
|
||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||
@@ -35,7 +38,7 @@ android {
|
||||
buildConfigField("boolean", "INCLUDE_UPDATER", "false")
|
||||
|
||||
ndk {
|
||||
abiFilters += SUPPORTED_ABIS
|
||||
abiFilters += supportedAbis
|
||||
}
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -44,7 +47,7 @@ android {
|
||||
abi {
|
||||
isEnable = true
|
||||
reset()
|
||||
include(*SUPPORTED_ABIS.toTypedArray())
|
||||
include(*supportedAbis.toTypedArray())
|
||||
isUniversalApk = true
|
||||
}
|
||||
}
|
||||
@@ -120,7 +123,6 @@ android {
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
compose = true
|
||||
buildConfig = true
|
||||
|
||||
// Disable some unused things
|
||||
@@ -133,10 +135,6 @@ android {
|
||||
abortOnError = false
|
||||
checkReleaseBuilds = false
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -154,26 +152,25 @@ dependencies {
|
||||
implementation(projects.presentationWidget)
|
||||
|
||||
// Compose
|
||||
implementation(platform(compose.bom))
|
||||
implementation(compose.activity)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3.core)
|
||||
implementation(compose.material.core)
|
||||
implementation(compose.material.icons)
|
||||
implementation(compose.animation)
|
||||
implementation(compose.animation.graphics)
|
||||
debugImplementation(compose.ui.tooling)
|
||||
implementation(compose.ui.tooling.preview)
|
||||
implementation(compose.ui.util)
|
||||
implementation(compose.accompanist.webview)
|
||||
implementation(compose.accompanist.systemuicontroller)
|
||||
|
||||
implementation(androidx.interpolator)
|
||||
|
||||
implementation(androidx.paging.runtime)
|
||||
implementation(androidx.paging.compose)
|
||||
|
||||
implementation(libs.bundles.sqlite)
|
||||
// SY -->
|
||||
implementation(libs.sqlcipher)
|
||||
implementation(sylibs.sqlcipher)
|
||||
// SY <--
|
||||
|
||||
implementation(kotlinx.reflect)
|
||||
@@ -215,10 +212,6 @@ dependencies {
|
||||
// Disk
|
||||
implementation(libs.disklrucache)
|
||||
implementation(libs.unifile)
|
||||
implementation(libs.bundles.archive)
|
||||
// SY -->
|
||||
implementation(libs.zip4j)
|
||||
// SY <--
|
||||
|
||||
// Preferences
|
||||
implementation(libs.preferencektx)
|
||||
@@ -247,15 +240,13 @@ dependencies {
|
||||
implementation(libs.bundles.voyager)
|
||||
implementation(libs.compose.materialmotion)
|
||||
implementation(libs.swipe)
|
||||
|
||||
implementation(libs.google.api.services.drive)
|
||||
implementation(libs.google.api.client.oauth)
|
||||
implementation(libs.compose.webview)
|
||||
implementation(libs.compose.grid)
|
||||
|
||||
// Logging
|
||||
implementation(libs.logcat)
|
||||
|
||||
// Crash reports/analytics
|
||||
// implementation(libs.bundles.acra)
|
||||
// "standardImplementation"(libs.firebase.analytics)
|
||||
|
||||
// Shizuku
|
||||
@@ -268,6 +259,8 @@ dependencies {
|
||||
// debugImplementation(libs.leakcanary.android)
|
||||
implementation(libs.leakcanary.plumber)
|
||||
|
||||
testImplementation(kotlinx.coroutines.test)
|
||||
|
||||
// SY -->
|
||||
// Text distance (EH)
|
||||
implementation(sylibs.simularity)
|
||||
@@ -282,6 +275,10 @@ dependencies {
|
||||
// RatingBar (SY)
|
||||
implementation(sylibs.ratingbar)
|
||||
implementation(sylibs.composeRatingbar)
|
||||
|
||||
// Google drive
|
||||
implementation(sylibs.google.api.services.drive)
|
||||
implementation(sylibs.google.api.client.oauth)
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
@@ -303,7 +300,7 @@ androidComponents {
|
||||
tasks {
|
||||
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
|
||||
withType<KotlinCompile> {
|
||||
kotlinOptions.freeCompilerArgs += listOf(
|
||||
compilerOptions.freeCompilerArgs.addAll(
|
||||
"-Xcontext-receivers",
|
||||
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
|
||||
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
|
||||
@@ -314,31 +311,11 @@ tasks {
|
||||
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
|
||||
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
|
||||
"-opt-in=coil3.annotation.ExperimentalCoilApi",
|
||||
"-opt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi",
|
||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
|
||||
"-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,
|
||||
)
|
||||
}
|
||||
|
||||
// https://developer.android.com/jetpack/androidx/releases/compose-compiler#1.5.9
|
||||
kotlinOptions.freeCompilerArgs += listOf(
|
||||
"-P",
|
||||
"plugin:androidx.compose.compiler.plugins.kotlin:nonSkippingGroupOptimization=true",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+5
-3
@@ -2,6 +2,7 @@
|
||||
|
||||
-keep,allowoptimization class eu.kanade.**
|
||||
-keep,allowoptimization class tachiyomi.**
|
||||
-keep,allowoptimization class mihon.**
|
||||
|
||||
# Keep common dependencies used in extensions
|
||||
-keep,allowoptimization class androidx.preference.** { public protected *; }
|
||||
@@ -46,6 +47,10 @@
|
||||
-dontnote rx.internal.util.PlatformDependent
|
||||
##---------------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 ----------
|
||||
-keepattributes *Annotation*, InnerClasses
|
||||
-dontnote kotlinx.serialization.** # core serialization annotations
|
||||
@@ -122,9 +127,6 @@
|
||||
# XmlUtil
|
||||
-keep public enum nl.adaptivity.xmlutil.EventType { *; }
|
||||
|
||||
# Apache Commons Compress
|
||||
-keep class * extends org.apache.commons.compress.archivers.zip.ZipExtraField { <init>(); }
|
||||
|
||||
# Firebase
|
||||
-keep class com.google.firebase.installations.** { *; }
|
||||
-keep interface com.google.firebase.installations.** { *; }
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_tachi_monochrome_launcher" />
|
||||
</adaptive-icon>
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_tachi_monochrome_launcher" />
|
||||
</adaptive-icon>
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -4,10 +4,7 @@ import eu.kanade.domain.chapter.interactor.GetAvailableScanlators
|
||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
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.GetExtensionRepos
|
||||
import eu.kanade.domain.extension.interactor.GetExtensionSources
|
||||
import eu.kanade.domain.extension.interactor.GetExtensionsByType
|
||||
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.SyncChapterProgressWithTrack
|
||||
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.chapter.ChapterRepositoryImpl
|
||||
import tachiyomi.data.history.HistoryRepositoryImpl
|
||||
@@ -111,6 +119,7 @@ class DomainModule : InjektModule {
|
||||
addFactory { GetMangaByUrlAndSourceId(get()) }
|
||||
addFactory { GetManga(get()) }
|
||||
addFactory { GetNextChapters(get(), get(), get(), get()) }
|
||||
addFactory { GetUpcomingManga(get()) }
|
||||
addFactory { ResetViewerFlags(get()) }
|
||||
addFactory { SetMangaChapterFlags(get()) }
|
||||
addFactory { FetchInterval(get()) }
|
||||
@@ -144,6 +153,7 @@ class DomainModule : InjektModule {
|
||||
addFactory { ShouldUpdateDbChapter() }
|
||||
addFactory { SyncChaptersWithSource(get(), get(), get(), get(), get(), get(), get(), get()) }
|
||||
addFactory { GetAvailableScanlators(get()) }
|
||||
addFactory { FilterChaptersForDownload(get(), get(), get(), get()) }
|
||||
|
||||
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
|
||||
addFactory { GetHistory(get()) }
|
||||
@@ -171,10 +181,15 @@ class DomainModule : InjektModule {
|
||||
addFactory { ToggleLanguage(get()) }
|
||||
addFactory { ToggleSource(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 { GetExtensionRepos(get()) }
|
||||
addFactory { ReplaceExtensionRepo(get()) }
|
||||
addFactory { UpdateExtensionRepo(get(), get()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ package eu.kanade.domain.base
|
||||
|
||||
import android.content.Context
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
||||
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
|
||||
import tachiyomi.core.common.preference.Preference
|
||||
import tachiyomi.core.common.preference.PreferenceStore
|
||||
import tachiyomi.i18n.MR
|
||||
@@ -22,8 +20,6 @@ class BasePreferences(
|
||||
|
||||
fun extensionInstaller() = ExtensionInstallerPreference(context, preferenceStore)
|
||||
|
||||
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
|
||||
|
||||
fun shownOnboardingFlow() = preferenceStore.getBoolean(Preference.appStateKey("onboarding_complete"), false)
|
||||
|
||||
enum class ExtensionInstaller(val titleRes: StringResource, val requiresSystemPermission: Boolean) {
|
||||
@@ -32,4 +28,6 @@ class BasePreferences(
|
||||
SHIZUKU(MR.strings.ext_installer_shizuku, false),
|
||||
PRIVATE(MR.strings.ext_installer_private, false),
|
||||
}
|
||||
|
||||
fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "")
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package eu.kanade.domain.extension.interactor
|
||||
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import tachiyomi.core.common.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()
|
||||
@@ -1,11 +0,0 @@
|
||||
package eu.kanade.domain.extension.interactor
|
||||
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import tachiyomi.core.common.preference.minusAssign
|
||||
|
||||
class DeleteExtensionRepo(private val preferences: SourcePreferences) {
|
||||
|
||||
fun await(repo: String) {
|
||||
preferences.extensionRepos() -= repo
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class GetExtensionsByType(
|
||||
extensionManager.installedExtensionsFlow,
|
||||
extensionManager.untrustedExtensionsFlow,
|
||||
extensionManager.availableExtensionsFlow,
|
||||
) { _activeLanguages, _installed, _untrusted, _available ->
|
||||
) { enabledLanguages, _installed, _untrusted, _available ->
|
||||
val (updates, installed) = _installed
|
||||
.filter { (showNsfwSources || !it.isNsfw) }
|
||||
.sortedWith(
|
||||
@@ -41,9 +41,9 @@ class GetExtensionsByType(
|
||||
}
|
||||
.flatMap { ext ->
|
||||
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 {
|
||||
ext.copy(
|
||||
name = it.name,
|
||||
|
||||
@@ -3,15 +3,18 @@ package eu.kanade.domain.extension.interactor
|
||||
import android.content.pm.PackageInfo
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import mihon.domain.extensionrepo.repository.ExtensionRepoRepository
|
||||
import tachiyomi.core.common.preference.getAndSet
|
||||
|
||||
class TrustExtension(
|
||||
private val extensionRepoRepository: ExtensionRepoRepository,
|
||||
private val preferences: SourcePreferences,
|
||||
) {
|
||||
|
||||
fun isTrusted(pkgInfo: PackageInfo, signatureHash: String): Boolean {
|
||||
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:$signatureHash"
|
||||
return key in preferences.trustedExtensions().get()
|
||||
suspend fun isTrusted(pkgInfo: PackageInfo, fingerprints: List<String>): Boolean {
|
||||
val trustedFingerprints = extensionRepoRepository.getAll().map { it.signingKeyFingerprint }.toHashSet()
|
||||
val key = "${pkgInfo.packageName}:${PackageInfoCompat.getLongVersionCode(pkgInfo)}:${fingerprints.last()}"
|
||||
return trustedFingerprints.any { fingerprints.contains(it) } || key in preferences.trustedExtensions().get()
|
||||
}
|
||||
|
||||
fun trust(pkgName: String, versionCode: Long, signatureHash: String) {
|
||||
@@ -19,9 +22,7 @@ class TrustExtension(
|
||||
// Remove previously trusted versions
|
||||
val removed = exts.filterNot { it.startsWith("$pkgName:") }.toMutableSet()
|
||||
|
||||
removed.also {
|
||||
it += "$pkgName:$versionCode:$signatureHash"
|
||||
}
|
||||
removed.also { it += "$pkgName:$versionCode:$signatureHash" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,11 @@ class GetEnabledSources(
|
||||
) { a, b, c -> Triple(a, b, c) },
|
||||
// SY <--
|
||||
repository.getSources(),
|
||||
) { pinnedSourceIds,
|
||||
(enabledLanguages, disabledSources, lastUsedSource),
|
||||
(excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter),
|
||||
sources,
|
||||
) {
|
||||
pinnedSourceIds,
|
||||
(enabledLanguages, disabledSources, lastUsedSource),
|
||||
(excludedFromDataSaver, sourcesInCategories, sourceCategoriesFilter),
|
||||
sources,
|
||||
->
|
||||
|
||||
val sourcesAndCategories = sourcesInCategories.map {
|
||||
|
||||
@@ -49,6 +49,11 @@ class SourcePreferences(
|
||||
emptySet(),
|
||||
)
|
||||
|
||||
fun globalSearchFilterState() = preferenceStore.getBoolean(
|
||||
Preference.appStateKey("has_filters_toggle_state"),
|
||||
false,
|
||||
)
|
||||
|
||||
// SY -->
|
||||
fun enableSourceBlacklist() = preferenceStore.getBoolean("eh_enable_source_blacklist", true)
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ class SyncPreferences(
|
||||
fun clientAPIKey() = preferenceStore.getString("sync_client_api_key", "")
|
||||
fun lastSyncTimestamp() = preferenceStore.getLong(Preference.appStateKey("last_sync_timestamp"), 0L)
|
||||
|
||||
fun lastSyncEtag() = preferenceStore.getString("sync_etag", "")
|
||||
|
||||
fun syncInterval() = preferenceStore.getInt("sync_interval", 0)
|
||||
fun syncService() = preferenceStore.getInt("sync_service", 0)
|
||||
|
||||
@@ -27,7 +29,7 @@ class SyncPreferences(
|
||||
)
|
||||
|
||||
fun uniqueDeviceID(): String {
|
||||
val uniqueIDPreference = preferenceStore.getString("unique_device_id", "")
|
||||
val uniqueIDPreference = preferenceStore.getString(Preference.appStateKey("unique_device_id"), "")
|
||||
|
||||
// Retrieve the current value of the preference
|
||||
var uniqueID = uniqueIDPreference.get()
|
||||
@@ -51,8 +53,15 @@ class SyncPreferences(
|
||||
tracking = preferenceStore.getBoolean("tracking", true).get(),
|
||||
history = preferenceStore.getBoolean("history", true).get(),
|
||||
appSettings = preferenceStore.getBoolean("appSettings", true).get(),
|
||||
extensionRepoSettings = preferenceStore.getBoolean("extensionRepoSettings", true).get(),
|
||||
sourceSettings = preferenceStore.getBoolean("sourceSettings", true).get(),
|
||||
privateSettings = preferenceStore.getBoolean("privateSettings", true).get(),
|
||||
|
||||
// SY -->
|
||||
customInfo = preferenceStore.getBoolean("customInfo", true).get(),
|
||||
readEntries = preferenceStore.getBoolean("readEntries", true).get(),
|
||||
savedSearches = preferenceStore.getBoolean("savedSearches", true).get(),
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
|
||||
@@ -63,8 +72,15 @@ class SyncPreferences(
|
||||
preferenceStore.getBoolean("tracking", true).set(syncSettings.tracking)
|
||||
preferenceStore.getBoolean("history", true).set(syncSettings.history)
|
||||
preferenceStore.getBoolean("appSettings", true).set(syncSettings.appSettings)
|
||||
preferenceStore.getBoolean("extensionRepoSettings", true).set(syncSettings.extensionRepoSettings)
|
||||
preferenceStore.getBoolean("sourceSettings", true).set(syncSettings.sourceSettings)
|
||||
preferenceStore.getBoolean("privateSettings", true).set(syncSettings.privateSettings)
|
||||
|
||||
// SY -->
|
||||
preferenceStore.getBoolean("customInfo", true).set(syncSettings.customInfo)
|
||||
preferenceStore.getBoolean("readEntries", true).set(syncSettings.readEntries)
|
||||
preferenceStore.getBoolean("savedSearches", true).set(syncSettings.savedSearches)
|
||||
// SY <--
|
||||
}
|
||||
|
||||
fun getSyncTriggerOptions(): SyncTriggerOptions {
|
||||
|
||||
@@ -7,6 +7,13 @@ data class SyncSettings(
|
||||
val tracking: Boolean = true,
|
||||
val history: Boolean = true,
|
||||
val appSettings: Boolean = true,
|
||||
val extensionRepoSettings: Boolean = true,
|
||||
val sourceSettings: Boolean = true,
|
||||
val privateSettings: Boolean = false,
|
||||
|
||||
// SY -->
|
||||
val customInfo: Boolean = true,
|
||||
val readEntries: Boolean = true,
|
||||
val savedSearches: Boolean = true,
|
||||
// SY <--
|
||||
)
|
||||
|
||||
@@ -18,12 +18,20 @@ class UiPreferences(
|
||||
|
||||
fun themeMode() = preferenceStore.getEnum(
|
||||
"pref_theme_mode_key",
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { ThemeMode.SYSTEM } else { ThemeMode.LIGHT },
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
ThemeMode.SYSTEM
|
||||
} else {
|
||||
ThemeMode.LIGHT
|
||||
},
|
||||
)
|
||||
|
||||
fun appTheme() = preferenceStore.getEnum(
|
||||
"pref_app_theme",
|
||||
if (DeviceUtil.isDynamicColorAvailable) { AppTheme.MONET } else { AppTheme.DEFAULT },
|
||||
if (DeviceUtil.isDynamicColorAvailable) {
|
||||
AppTheme.MONET
|
||||
} else {
|
||||
AppTheme.DEFAULT
|
||||
},
|
||||
)
|
||||
|
||||
fun themeDarkAmoled() = preferenceStore.getBoolean("pref_theme_dark_amoled_key", false)
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import android.util.DisplayMetrics
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -241,7 +240,7 @@ private fun DetailsHeader(
|
||||
Extension name: ${extension.name} (lang: ${extension.lang}; package: ${extension.pkgName})
|
||||
Extension version: ${extension.versionName} (lib: ${extension.libVersion}; version code: ${extension.versionCode})
|
||||
NSFW: ${extension.isNsfw}
|
||||
""".trimIndent()
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
if (extension is Extension.Installed) {
|
||||
@@ -251,8 +250,8 @@ private fun DetailsHeader(
|
||||
Update available: ${extension.hasUpdate}
|
||||
Obsolete: ${extension.isObsolete}
|
||||
Shared: ${extension.isShared}
|
||||
Repository: ${extension.repoUrl}
|
||||
""".trimIndent()
|
||||
Repository: ${extension.repoUrl}
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -362,10 +361,8 @@ private fun InfoText(
|
||||
primaryTextStyle: TextStyle = MaterialTheme.typography.bodyLarge,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
val clickableModifier = if (onClick != null) {
|
||||
Modifier.clickable(interactionSource, indication = null) { onClick() }
|
||||
Modifier.clickable(interactionSource = null, indication = null, onClick = onClick)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
|
||||
@@ -219,7 +219,9 @@ private fun ExtensionContent(
|
||||
when (it) {
|
||||
is Extension.Available -> onInstallExtension(it)
|
||||
is Extension.Installed -> onOpenExtension(it)
|
||||
is Extension.Untrusted -> { trustState = it }
|
||||
is Extension.Untrusted -> {
|
||||
trustState = it
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongClickItem = onLongClickItem,
|
||||
@@ -241,7 +243,9 @@ private fun ExtensionContent(
|
||||
onOpenExtension(it)
|
||||
}
|
||||
}
|
||||
is Extension.Untrusted -> { trustState = it }
|
||||
is Extension.Untrusted -> {
|
||||
trustState = it
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ fun FeedScreen(
|
||||
onClickDelete: (FeedSavedSearch) -> Unit,
|
||||
onClickManga: (Manga) -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
getMangaState: @Composable (Manga, CatalogueSource?) -> State<Manga>,
|
||||
getMangaState: @Composable (Manga) -> State<Manga>,
|
||||
) {
|
||||
when {
|
||||
state.isLoading -> LoadingScreen()
|
||||
@@ -119,7 +119,7 @@ fun FeedScreen(
|
||||
) {
|
||||
FeedItem(
|
||||
item = item,
|
||||
getMangaState = { getMangaState(it, item.source) },
|
||||
getMangaState = { getMangaState(it) },
|
||||
onClickManga = onClickManga,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.LabeledCheckbox
|
||||
import tachiyomi.presentation.core.components.ScrollbarLazyColumn
|
||||
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.components.material.topSmallPaddingValues
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
@@ -179,7 +179,7 @@ private fun SourcePinButton(
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onBackground.copy(
|
||||
alpha = SecondaryItemAlpha,
|
||||
alpha = SECONDARY_ALPHA,
|
||||
)
|
||||
}
|
||||
val description = if (isPinned) MR.strings.action_unpin else MR.strings.action_pin
|
||||
|
||||
@@ -7,8 +7,6 @@ import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.runtime.Composable
|
||||
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.DialogProperties
|
||||
import cafe.adriel.voyager.core.annotation.InternalVoyagerApi
|
||||
@@ -23,7 +21,6 @@ import tachiyomi.presentation.core.components.AdaptiveSheet as AdaptiveSheetImpl
|
||||
@Composable
|
||||
fun NavigatorAdaptiveSheet(
|
||||
screen: Screen,
|
||||
tonalElevation: Dp = 1.dp,
|
||||
enableSwipeDismiss: (Navigator) -> Boolean = { true },
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
@@ -31,7 +28,6 @@ fun NavigatorAdaptiveSheet(
|
||||
screen = screen,
|
||||
content = { sheetNavigator ->
|
||||
AdaptiveSheet(
|
||||
tonalElevation = tonalElevation,
|
||||
enableSwipeDismiss = enableSwipeDismiss(sheetNavigator),
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
@@ -73,7 +69,6 @@ fun NavigatorAdaptiveSheet(
|
||||
fun AdaptiveSheet(
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
tonalElevation: Dp = 1.dp,
|
||||
enableSwipeDismiss: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
@@ -86,7 +81,6 @@ fun AdaptiveSheet(
|
||||
AdaptiveSheetImpl(
|
||||
modifier = modifier,
|
||||
isTabletUi = isTabletUi,
|
||||
tonalElevation = tonalElevation,
|
||||
enableSwipeDismiss = enableSwipeDismiss,
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
|
||||
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.PlainTooltip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TooltipBox
|
||||
import androidx.compose.material3.TooltipDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
@@ -312,7 +312,7 @@ fun SearchToolbar(
|
||||
visualTransformation = visualTransformation,
|
||||
interactionSource = interactionSource,
|
||||
decorationBox = { innerTextField ->
|
||||
TextFieldDefaults.TextFieldDecorationBox(
|
||||
TextFieldDefaults.DecorationBox(
|
||||
value = searchQuery,
|
||||
innerTextField = innerTextField,
|
||||
enabled = true,
|
||||
@@ -331,6 +331,7 @@ fun SearchToolbar(
|
||||
),
|
||||
)
|
||||
},
|
||||
container = {},
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -58,6 +58,7 @@ fun TabbedDialog(
|
||||
PrimaryTabRow(
|
||||
modifier = Modifier.weight(1f),
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
divider = {},
|
||||
) {
|
||||
tabTitles.fastForEachIndexed { index, tab ->
|
||||
@@ -78,7 +79,7 @@ fun TabbedDialog(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
state = pagerState,
|
||||
verticalAlignment = Alignment.Top,
|
||||
pageContent = { page -> content(page) }
|
||||
pageContent = { page -> content(page) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ fun CrashScreen(
|
||||
acceptText = stringResource(MR.strings.pref_dump_crash_logs),
|
||||
onAcceptClick = {
|
||||
scope.launch {
|
||||
CrashLogUtil(context).dumpLogs()
|
||||
CrashLogUtil(context).dumpLogs(exception)
|
||||
}
|
||||
},
|
||||
rejectText = stringResource(MR.strings.crash_screen_restart_application),
|
||||
|
||||
@@ -155,7 +155,7 @@ private fun ColumnScope.FilterPage(
|
||||
)
|
||||
// SY <--
|
||||
|
||||
val trackers = remember { screenModel.trackers }
|
||||
val trackers by screenModel.trackersFlow.collectAsState()
|
||||
when (trackers.size) {
|
||||
0 -> {
|
||||
// No trackers
|
||||
@@ -188,6 +188,7 @@ private fun ColumnScope.SortPage(
|
||||
category: Category?,
|
||||
screenModel: LibrarySettingsScreenModel,
|
||||
) {
|
||||
val trackers by screenModel.trackersFlow.collectAsState()
|
||||
// SY -->
|
||||
val globalSortMode by screenModel.libraryPreferences.sortingMode().collectAsState()
|
||||
val sortingMode = if (screenModel.grouping == LibraryGroup.BY_DEFAULT) {
|
||||
@@ -206,12 +207,11 @@ private fun ColumnScope.SortPage(
|
||||
}.collectAsState(initial = screenModel.libraryPreferences.sortTagsForLibrary().get().isNotEmpty())
|
||||
// SY <--
|
||||
|
||||
val trackerSortOption =
|
||||
if (screenModel.trackers.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
|
||||
}
|
||||
val trackerSortOption = if (trackers.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
listOf(MR.strings.action_sort_tracker_score to LibrarySort.Type.TrackerMean)
|
||||
}
|
||||
|
||||
listOfNotNull(
|
||||
MR.strings.action_sort_alpha to LibrarySort.Type.Alphabetical,
|
||||
@@ -346,12 +346,13 @@ private fun ColumnScope.GroupPage(
|
||||
screenModel: LibrarySettingsScreenModel,
|
||||
hasCategories: Boolean,
|
||||
) {
|
||||
val groups = remember(hasCategories, screenModel.trackers) {
|
||||
val trackers by screenModel.trackersFlow.collectAsState()
|
||||
val groups = remember(hasCategories, trackers) {
|
||||
buildList {
|
||||
add(LibraryGroup.BY_DEFAULT)
|
||||
add(LibraryGroup.BY_SOURCE)
|
||||
add(LibraryGroup.BY_STATUS)
|
||||
if (screenModel.trackers.isNotEmpty()) {
|
||||
if (trackers.isNotEmpty()) {
|
||||
add(LibraryGroup.BY_TRACK_STATUS)
|
||||
}
|
||||
if (hasCategories) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shadow
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.kanade.presentation.manga.components.MangaCover
|
||||
@@ -42,19 +43,26 @@ import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.BadgeGroup
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.selectedBackground
|
||||
import tachiyomi.domain.manga.model.MangaCover as MangaCoverModel
|
||||
|
||||
object CommonMangaItemDefaults {
|
||||
val GridHorizontalSpacer = 4.dp
|
||||
val GridVerticalSpacer = 4.dp
|
||||
|
||||
@Suppress("ConstPropertyName")
|
||||
const val BrowseFavoriteCoverAlpha = 0.34f
|
||||
}
|
||||
|
||||
private val ContinueReadingButtonSize = 28.dp
|
||||
private val ContinueReadingButtonSizeSmall = 28.dp
|
||||
private val ContinueReadingButtonSizeLarge = 32.dp
|
||||
|
||||
private val ContinueReadingButtonIconSizeSmall = 16.dp
|
||||
private val ContinueReadingButtonIconSizeLarge = 20.dp
|
||||
|
||||
private val ContinueReadingButtonGridPadding = 6.dp
|
||||
private val ContinueReadingButtonListSpacing = 8.dp
|
||||
|
||||
private const val GridSelectedCoverAlpha = 0.76f
|
||||
private const val GRID_SELECTED_COVER_ALPHA = 0.76f
|
||||
|
||||
/**
|
||||
* Layout of grid list item with title overlaying the cover.
|
||||
@@ -62,7 +70,7 @@ private const val GridSelectedCoverAlpha = 0.76f
|
||||
*/
|
||||
@Composable
|
||||
fun MangaCompactGridItem(
|
||||
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||
coverData: MangaCoverModel,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
isSelected: Boolean = false,
|
||||
@@ -82,7 +90,7 @@ fun MangaCompactGridItem(
|
||||
MangaCover.Book(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha),
|
||||
.alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
|
||||
data = coverData,
|
||||
)
|
||||
},
|
||||
@@ -96,10 +104,12 @@ fun MangaCompactGridItem(
|
||||
)
|
||||
} else if (onClickContinueReading != null) {
|
||||
ContinueReadingButton(
|
||||
size = ContinueReadingButtonSizeLarge,
|
||||
iconSize = ContinueReadingButtonIconSizeLarge,
|
||||
onClick = onClickContinueReading,
|
||||
modifier = Modifier
|
||||
.padding(ContinueReadingButtonGridPadding)
|
||||
.align(Alignment.BottomEnd),
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -148,11 +158,13 @@ private fun BoxScope.CoverTextOverlay(
|
||||
)
|
||||
if (onClickContinueReading != null) {
|
||||
ContinueReadingButton(
|
||||
size = ContinueReadingButtonSizeSmall,
|
||||
iconSize = ContinueReadingButtonIconSizeSmall,
|
||||
onClick = onClickContinueReading,
|
||||
modifier = Modifier.padding(
|
||||
end = ContinueReadingButtonGridPadding,
|
||||
bottom = ContinueReadingButtonGridPadding,
|
||||
),
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -163,7 +175,7 @@ private fun BoxScope.CoverTextOverlay(
|
||||
*/
|
||||
@Composable
|
||||
fun MangaComfortableGridItem(
|
||||
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||
coverData: MangaCoverModel,
|
||||
title: String,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
@@ -185,7 +197,7 @@ fun MangaComfortableGridItem(
|
||||
MangaCover.Book(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.alpha(if (isSelected) GridSelectedCoverAlpha else coverAlpha),
|
||||
.alpha(if (isSelected) GRID_SELECTED_COVER_ALPHA else coverAlpha),
|
||||
data = coverData,
|
||||
)
|
||||
},
|
||||
@@ -194,10 +206,12 @@ fun MangaComfortableGridItem(
|
||||
content = {
|
||||
if (onClickContinueReading != null) {
|
||||
ContinueReadingButton(
|
||||
size = ContinueReadingButtonSizeLarge,
|
||||
iconSize = ContinueReadingButtonIconSizeLarge,
|
||||
onClick = onClickContinueReading,
|
||||
modifier = Modifier
|
||||
.padding(ContinueReadingButtonGridPadding)
|
||||
.align(Alignment.BottomEnd),
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -309,14 +323,14 @@ private fun GridItemSelectable(
|
||||
private fun Modifier.selectedOutline(
|
||||
isSelected: Boolean,
|
||||
color: Color,
|
||||
) = this then drawBehind { if (isSelected) drawRect(color = color) }
|
||||
) = drawBehind { if (isSelected) drawRect(color = color) }
|
||||
|
||||
/**
|
||||
* Layout of list item.
|
||||
*/
|
||||
@Composable
|
||||
fun MangaListItem(
|
||||
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||
coverData: MangaCoverModel,
|
||||
title: String,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
@@ -354,8 +368,10 @@ fun MangaListItem(
|
||||
BadgeGroup(content = badge)
|
||||
if (onClickContinueReading != null) {
|
||||
ContinueReadingButton(
|
||||
size = ContinueReadingButtonSizeSmall,
|
||||
iconSize = ContinueReadingButtonIconSizeSmall,
|
||||
onClick = onClickContinueReading,
|
||||
modifier = Modifier.padding(start = ContinueReadingButtonListSpacing),
|
||||
onClickContinueReading = onClickContinueReading,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -363,23 +379,25 @@ fun MangaListItem(
|
||||
|
||||
@Composable
|
||||
private fun ContinueReadingButton(
|
||||
size: Dp,
|
||||
iconSize: Dp,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickContinueReading: () -> Unit,
|
||||
) {
|
||||
Box(modifier = modifier) {
|
||||
FilledIconButton(
|
||||
onClick = onClickContinueReading,
|
||||
modifier = Modifier.size(ContinueReadingButtonSize),
|
||||
onClick = onClick,
|
||||
shape = MaterialTheme.shapes.small,
|
||||
colors = IconButtonDefaults.filledIconButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.9f),
|
||||
contentColor = contentColorFor(MaterialTheme.colorScheme.primaryContainer),
|
||||
),
|
||||
modifier = Modifier.size(size),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PlayArrow,
|
||||
contentDescription = stringResource(MR.strings.action_resume),
|
||||
modifier = Modifier.size(16.dp),
|
||||
modifier = Modifier.size(iconSize),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ private fun LibraryRegularToolbar(
|
||||
onClick = onClickOpenRandomManga,
|
||||
),
|
||||
AppBar.OverflowAction(
|
||||
title = stringResource(MR.strings.sync_library),
|
||||
title = stringResource(SYMR.strings.sync_library),
|
||||
onClick = onClickSyncNow,
|
||||
),
|
||||
).builder().apply {
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
package eu.kanade.presentation.manga
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
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.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.OutlinedButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
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.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
||||
@Composable
|
||||
@@ -18,42 +35,92 @@ fun DuplicateMangaDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onConfirm: () -> Unit,
|
||||
onOpenManga: () -> Unit,
|
||||
onMigrate: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AlertDialog(
|
||||
val minHeight = LocalPreferenceMinHeight.current
|
||||
|
||||
AdaptiveSheet(
|
||||
modifier = modifier,
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = {
|
||||
Text(text = stringResource(MR.strings.are_you_sure))
|
||||
},
|
||||
text = {
|
||||
Text(text = stringResource(MR.strings.confirm_add_duplicate_manga))
|
||||
},
|
||||
confirmButton = {
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
vertical = TabbedDialogPaddings.Vertical,
|
||||
horizontal = TabbedDialogPaddings.Horizontal,
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
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(
|
||||
onClick = {
|
||||
onDismissRequest()
|
||||
onOpenManga()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.action_show_manga))
|
||||
}
|
||||
|
||||
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))
|
||||
OutlinedButton(onClick = onDismissRequest, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(vertical = 8.dp),
|
||||
text = stringResource(MR.strings.action_cancel),
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontSize = 16.sp,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -77,6 +77,7 @@ import eu.kanade.tachiyomi.source.online.english.Pururin
|
||||
import eu.kanade.tachiyomi.source.online.english.Tsumino
|
||||
import eu.kanade.tachiyomi.ui.manga.ChapterList
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaScreenModel
|
||||
import eu.kanade.tachiyomi.ui.manga.MergedMangaData
|
||||
import eu.kanade.tachiyomi.ui.manga.PagePreviewState
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import exh.metadata.MetadataUtil
|
||||
@@ -578,6 +579,7 @@ private fun MangaScreenSmallImpl(
|
||||
|
||||
sharedChapterItems(
|
||||
manga = state.manga,
|
||||
mergedData = state.mergedData,
|
||||
chapters = listItem,
|
||||
isAnyChapterSelected = chapters.fastAny { it.selected },
|
||||
chapterSwipeStartAction = chapterSwipeStartAction,
|
||||
@@ -880,6 +882,7 @@ fun MangaScreenLargeImpl(
|
||||
|
||||
sharedChapterItems(
|
||||
manga = state.manga,
|
||||
mergedData = state.mergedData,
|
||||
chapters = listItem,
|
||||
isAnyChapterSelected = chapters.fastAny { it.selected },
|
||||
chapterSwipeStartAction = chapterSwipeStartAction,
|
||||
@@ -944,6 +947,7 @@ private fun SharedMangaBottomActionMenu(
|
||||
|
||||
private fun LazyListScope.sharedChapterItems(
|
||||
manga: Manga,
|
||||
mergedData: MergedMangaData?,
|
||||
chapters: List<ChapterList>,
|
||||
isAnyChapterSelected: Boolean,
|
||||
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
|
||||
@@ -995,7 +999,9 @@ private fun LazyListScope.sharedChapterItems(
|
||||
// SY <--
|
||||
},
|
||||
readProgress = item.chapter.lastPageRead
|
||||
.takeIf { /* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L }
|
||||
.takeIf {
|
||||
/* SY --> */(!item.chapter.read || alwaysShowReadingProgress)/* SY <-- */ && it > 0L
|
||||
}
|
||||
?.let {
|
||||
stringResource(
|
||||
MR.strings.chapter_progress,
|
||||
@@ -1011,7 +1017,8 @@ private fun LazyListScope.sharedChapterItems(
|
||||
read = item.chapter.read,
|
||||
bookmark = item.chapter.bookmark,
|
||||
selected = item.selected,
|
||||
downloadIndicatorEnabled = !isAnyChapterSelected && !manga.isLocal(),
|
||||
downloadIndicatorEnabled =
|
||||
!isAnyChapterSelected && !(mergedData?.manga?.get(item.chapter.mangaId) ?: manga).isLocal(),
|
||||
downloadStateProvider = { item.downloadState },
|
||||
downloadProgressProvider = { item.downloadProgress },
|
||||
chapterSwipeStartAction = chapterSwipeStartAction,
|
||||
|
||||
+1
-1
@@ -9,13 +9,13 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.material.icons.outlined.ArrowDownward
|
||||
import androidx.compose.material.icons.outlined.ErrorOutline
|
||||
import androidx.compose.material.ripple
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProgressIndicatorDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
||||
@@ -12,7 +12,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
@@ -60,6 +60,6 @@ private fun MissingChaptersWarning(count: Int) {
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.error.copy(alpha = SecondaryItemAlpha),
|
||||
color = MaterialTheme.colorScheme.error.copy(alpha = SECONDARY_ALPHA),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -33,12 +32,12 @@ import androidx.compose.material.icons.outlined.Label
|
||||
import androidx.compose.material.icons.outlined.MoreVert
|
||||
import androidx.compose.material.icons.outlined.RemoveDone
|
||||
import androidx.compose.material.icons.outlined.SwapCalls
|
||||
import androidx.compose.material.ripple
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
@@ -90,7 +89,7 @@ fun MangaBottomActionMenu(
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
|
||||
tonalElevation = 3.dp,
|
||||
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val confirm = remember { mutableStateListOf(false, false, false, false, false, false, false) }
|
||||
@@ -199,7 +198,7 @@ private fun RowScope.Button(
|
||||
.size(48.dp)
|
||||
.weight(animatedWeight)
|
||||
.combinedClickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
interactionSource = null,
|
||||
indication = ripple(bounded = false),
|
||||
onLongClick = onLongClick,
|
||||
onClick = onClick,
|
||||
@@ -252,7 +251,7 @@ fun LibraryBottomActionMenu(
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
shape = MaterialTheme.shapes.large.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
|
||||
tonalElevation = 3.dp,
|
||||
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val confirm =
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
@@ -41,8 +40,8 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import me.saket.swipe.SwipeableActionsBox
|
||||
import tachiyomi.domain.library.service.LibraryPreferences
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.ReadItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.selectedBackground
|
||||
|
||||
@@ -69,9 +68,6 @@ fun MangaChapterListItem(
|
||||
onChapterSwipe: (LibraryPreferences.ChapterSwipeAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val textAlpha = if (read) ReadItemAlpha else 1f
|
||||
val textSubtitleAlpha = if (read) ReadItemAlpha else SecondaryItemAlpha
|
||||
|
||||
val start = getSwipeAction(
|
||||
action = chapterSwipeStartAction,
|
||||
read = read,
|
||||
@@ -136,29 +132,39 @@ fun MangaChapterListItem(
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = LocalContentColor.current.copy(alpha = textAlpha),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
onTextLayout = { textHeight = it.size.height },
|
||||
color = LocalContentColor.current.copy(alpha = if (read) DISABLED_ALPHA else 1f),
|
||||
)
|
||||
}
|
||||
|
||||
Row(modifier = Modifier.alpha(textSubtitleAlpha)) {
|
||||
ProvideTextStyle(value = MaterialTheme.typography.bodySmall) {
|
||||
Row {
|
||||
val subtitleStyle = MaterialTheme.typography.bodySmall
|
||||
.merge(
|
||||
color = LocalContentColor.current
|
||||
.copy(alpha = if (read) DISABLED_ALPHA else SECONDARY_ALPHA),
|
||||
)
|
||||
ProvideTextStyle(value = subtitleStyle) {
|
||||
if (date != null) {
|
||||
Text(
|
||||
text = date,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (readProgress != null || scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText()
|
||||
if (readProgress != null ||
|
||||
scanlator != null/* SY --> */ ||
|
||||
sourceName != null/* SY <-- */
|
||||
) {
|
||||
DotSeparatorText()
|
||||
}
|
||||
}
|
||||
if (readProgress != null) {
|
||||
Text(
|
||||
text = readProgress,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = LocalContentColor.current.copy(alpha = ReadItemAlpha),
|
||||
color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
|
||||
)
|
||||
if (scanlator != null/* SY --> */ || sourceName != null/* SY <-- */) DotSeparatorText()
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.core.view.updatePadding
|
||||
import coil3.asDrawable
|
||||
import coil3.imageLoader
|
||||
import coil3.request.CachePolicy
|
||||
import coil3.request.ImageRequest
|
||||
|
||||
@@ -102,9 +102,12 @@ fun SetIntervalDialog(
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(MaterialTheme.padding.small))
|
||||
} else {
|
||||
Text(
|
||||
stringResource(MR.strings.manga_interval_expected_update_null),
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(MaterialTheme.padding.small))
|
||||
|
||||
if (onValueChanged != null && (isDevFlavor || isPreviewBuildType)) {
|
||||
Text(stringResource(MR.strings.manga_interval_custom_amount))
|
||||
|
||||
@@ -2,6 +2,7 @@ package eu.kanade.presentation.manga.components
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.graphics.res.animatedVectorResource
|
||||
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
|
||||
import androidx.compose.animation.graphics.vector.AnimatedImageVector
|
||||
@@ -81,6 +82,7 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.TextButton
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
@@ -180,7 +182,7 @@ fun MangaActionRow(
|
||||
// SY <--
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = .38f)
|
||||
val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = DISABLED_ALPHA)
|
||||
|
||||
// TODO: show something better when using custom interval
|
||||
val nextUpdateDays = remember(nextUpdate) {
|
||||
@@ -289,7 +291,8 @@ fun ExpandableMangaDescription(
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp)
|
||||
.padding(vertical = 12.dp)
|
||||
.animateContentSize(),
|
||||
.animateContentSize(animationSpec = spring())
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
var tagSelected by remember { mutableStateOf("") }
|
||||
|
||||
@@ -44,7 +44,7 @@ import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
||||
@Composable
|
||||
private fun PagePreviewLoading(
|
||||
setMaxWidth: (Dp) -> Unit
|
||||
setMaxWidth: (Dp) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
Box(
|
||||
@@ -63,7 +63,7 @@ private fun PagePreviewLoading(
|
||||
@Composable
|
||||
private fun PagePreviewRow(
|
||||
onOpenPage: (Int) -> Unit,
|
||||
items: ImmutableList<PagePreview>
|
||||
items: ImmutableList<PagePreview>,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -88,7 +88,7 @@ private fun PagePreviewMore(
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
TextButton(onClick = onMorePreviewsClicked) {
|
||||
Text(stringResource(SYMR.strings.more_previews))
|
||||
@@ -116,7 +116,7 @@ fun PagePreviews(
|
||||
pagePreviewState.pagePreviews.take(rowCount * itemPerRowCount).chunked(itemPerRowCount).forEach {
|
||||
PagePreviewRow(
|
||||
onOpenPage = onOpenPage,
|
||||
items = remember(it) { it.toImmutableList() }
|
||||
items = remember(it) { it.toImmutableList() },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ fun LazyListScope.PagePreviewItems(
|
||||
) {
|
||||
PagePreviewRow(
|
||||
onOpenPage = onOpenPage,
|
||||
items = remember(it) { it.toImmutableList() }
|
||||
items = remember(it) { it.toImmutableList() },
|
||||
)
|
||||
}
|
||||
item(
|
||||
|
||||
@@ -111,8 +111,14 @@ fun ScanlatorFilterDialog(
|
||||
}
|
||||
} else {
|
||||
FlowRow {
|
||||
TextButton(onClick = mutableExcludedScanlators::clear) {
|
||||
Text(text = stringResource(MR.strings.action_reset))
|
||||
if (mutableExcludedScanlators.isEmpty()) {
|
||||
TextButton(onClick = { mutableExcludedScanlators.addAll(availableScanlators) }) {
|
||||
Text(text = stringResource(MR.strings.action_select_all))
|
||||
}
|
||||
} else {
|
||||
TextButton(onClick = mutableExcludedScanlators::clear) {
|
||||
Text(text = stringResource(MR.strings.action_reset))
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TextButton(onClick = onDismissRequest) {
|
||||
|
||||
@@ -75,7 +75,7 @@ private fun NewUpdateScreenPreview() {
|
||||
changelogInfo = """
|
||||
## Yay
|
||||
Foobar
|
||||
|
||||
|
||||
### More info
|
||||
- Hello
|
||||
- World
|
||||
|
||||
@@ -7,12 +7,12 @@ import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.structuralEqualityPolicy
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.domain.track.service.TrackPreferences
|
||||
import eu.kanade.presentation.more.settings.widget.EditTextPreferenceWidget
|
||||
import eu.kanade.presentation.more.settings.widget.InfoWidget
|
||||
import eu.kanade.presentation.more.settings.widget.ListPreferenceWidget
|
||||
@@ -23,8 +23,6 @@ import eu.kanade.presentation.more.settings.widget.TrackingPreferenceWidget
|
||||
import kotlinx.coroutines.launch
|
||||
import tachiyomi.presentation.core.components.SliderItem
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
val LocalPreferenceHighlighted = compositionLocalOf(structuralEqualityPolicy()) { false }
|
||||
val LocalPreferenceMinHeight = compositionLocalOf(structuralEqualityPolicy()) { 56.dp }
|
||||
@@ -156,16 +154,14 @@ internal fun PreferenceItem(
|
||||
)
|
||||
}
|
||||
is Preference.PreferenceItem.TrackerPreference -> {
|
||||
val uName by Injekt.get<TrackPreferences>()
|
||||
.trackUsername(item.tracker)
|
||||
.collectAsState()
|
||||
item.tracker.run {
|
||||
TrackingPreferenceWidget(
|
||||
tracker = this,
|
||||
checked = uName.isNotEmpty(),
|
||||
onClick = { if (isLoggedIn) item.logout() else item.login() },
|
||||
)
|
||||
val isLoggedIn by item.tracker.let { tracker ->
|
||||
tracker.isLoggedInFlow.collectAsState(tracker.isLoggedIn)
|
||||
}
|
||||
TrackingPreferenceWidget(
|
||||
tracker = item.tracker,
|
||||
checked = isLoggedIn,
|
||||
onClick = { if (isLoggedIn) item.logout() else item.login() },
|
||||
)
|
||||
}
|
||||
is Preference.PreferenceItem.InfoPreference -> {
|
||||
InfoWidget(text = item.title)
|
||||
|
||||
+78
-66
@@ -3,11 +3,12 @@ package eu.kanade.presentation.more.settings.screen
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.webkit.WebStorage
|
||||
import android.webkit.WebView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Text
|
||||
@@ -112,71 +113,54 @@ object SettingsAdvancedScreen : SearchableSettings {
|
||||
val basePreferences = remember { Injekt.get<BasePreferences>() }
|
||||
val networkPreferences = remember { Injekt.get<NetworkPreferences>() }
|
||||
|
||||
return buildList {
|
||||
addAll(
|
||||
listOf(
|
||||
/* SY --> Preference.PreferenceItem.SwitchPreference(
|
||||
pref = basePreferences.acraEnabled(),
|
||||
title = stringResource(MR.strings.pref_enable_acra),
|
||||
subtitle = stringResource(MR.strings.pref_acra_summary),
|
||||
enabled = isPreviewBuildType || isReleaseBuildType,
|
||||
), SY <-- */
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_dump_crash_logs),
|
||||
subtitle = stringResource(MR.strings.pref_dump_crash_logs_summary),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
CrashLogUtil(context).dumpLogs()
|
||||
}
|
||||
},
|
||||
),
|
||||
/* SY --> Preference.PreferenceItem.SwitchPreference(
|
||||
pref = networkPreferences.verboseLogging(),
|
||||
title = stringResource(MR.strings.pref_verbose_logging),
|
||||
subtitle = stringResource(MR.strings.pref_verbose_logging_summary),
|
||||
onValueChanged = {
|
||||
context.toast(MR.strings.requires_app_restart)
|
||||
true
|
||||
},
|
||||
), SY <-- */
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_debug_info),
|
||||
onClick = { navigator.push(DebugInfoScreen()) },
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_onboarding_guide),
|
||||
onClick = { navigator.push(OnboardingScreen()) },
|
||||
),
|
||||
),
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
add(
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_manage_notifications),
|
||||
onClick = {
|
||||
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
addAll(
|
||||
listOf(
|
||||
getBackgroundActivityGroup(),
|
||||
getDataGroup(),
|
||||
getNetworkGroup(networkPreferences = networkPreferences),
|
||||
getLibraryGroup(),
|
||||
getExtensionsGroup(basePreferences = basePreferences),
|
||||
// SY -->
|
||||
// getDownloaderGroup(),
|
||||
getDataSaverGroup(),
|
||||
getDeveloperToolsGroup(),
|
||||
// SY <--
|
||||
),
|
||||
)
|
||||
}
|
||||
return listOf(
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_dump_crash_logs),
|
||||
subtitle = stringResource(MR.strings.pref_dump_crash_logs_summary),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
CrashLogUtil(context).dumpLogs()
|
||||
}
|
||||
},
|
||||
),
|
||||
/* SY --> Preference.PreferenceItem.SwitchPreference(
|
||||
pref = networkPreferences.verboseLogging(),
|
||||
title = stringResource(MR.strings.pref_verbose_logging),
|
||||
subtitle = stringResource(MR.strings.pref_verbose_logging_summary),
|
||||
onValueChanged = {
|
||||
context.toast(MR.strings.requires_app_restart)
|
||||
true
|
||||
},
|
||||
), SY <-- */
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_debug_info),
|
||||
onClick = { navigator.push(DebugInfoScreen()) },
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_onboarding_guide),
|
||||
onClick = { navigator.push(OnboardingScreen()) },
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_manage_notifications),
|
||||
onClick = {
|
||||
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
|
||||
putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
},
|
||||
),
|
||||
getBackgroundActivityGroup(),
|
||||
getDataGroup(),
|
||||
getNetworkGroup(networkPreferences = networkPreferences),
|
||||
getLibraryGroup(),
|
||||
getReaderGroup(basePreferences = basePreferences),
|
||||
getExtensionsGroup(basePreferences = basePreferences),
|
||||
// SY -->
|
||||
// getDownloaderGroup(),
|
||||
getDataSaverGroup(),
|
||||
getDeveloperToolsGroup(),
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -367,6 +351,34 @@ object SettingsAdvancedScreen : SearchableSettings {
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getReaderGroup(
|
||||
basePreferences: BasePreferences,
|
||||
): Preference.PreferenceGroup {
|
||||
val context = LocalContext.current
|
||||
val chooseColorProfile = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.OpenDocument(),
|
||||
) { uri ->
|
||||
uri?.let {
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
context.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
basePreferences.displayProfile().set(uri.toString())
|
||||
}
|
||||
}
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.pref_category_reader),
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_display_profile),
|
||||
subtitle = basePreferences.displayProfile().get(),
|
||||
onClick = {
|
||||
chooseColorProfile.launch(arrayOf("*/*"))
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getExtensionsGroup(
|
||||
basePreferences: BasePreferences,
|
||||
|
||||
+9
-5
@@ -180,11 +180,15 @@ object SettingsAppearanceScreen : SearchableSettings {
|
||||
Preference.PreferenceItem.SliderPreference(
|
||||
value = previewsRowCount,
|
||||
title = stringResource(SYMR.strings.pref_previews_row_count),
|
||||
subtitle = if (previewsRowCount > 0) pluralStringResource(
|
||||
SYMR.plurals.row_count,
|
||||
previewsRowCount,
|
||||
previewsRowCount,
|
||||
) else stringResource(MR.strings.disabled),
|
||||
subtitle = if (previewsRowCount > 0) {
|
||||
pluralStringResource(
|
||||
SYMR.plurals.row_count,
|
||||
previewsRowCount,
|
||||
previewsRowCount,
|
||||
)
|
||||
} else {
|
||||
stringResource(MR.strings.disabled)
|
||||
},
|
||||
min = 0,
|
||||
max = 10,
|
||||
onValueChanged = {
|
||||
|
||||
+7
-3
@@ -2,6 +2,7 @@ package eu.kanade.presentation.more.settings.screen
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
@@ -17,6 +18,7 @@ import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen
|
||||
import eu.kanade.tachiyomi.ui.category.sources.SourceCategoryScreen
|
||||
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.authenticate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import mihon.domain.extensionrepo.interactor.GetExtensionRepoCount
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.domain.UnsortedPreferences
|
||||
import tachiyomi.i18n.MR
|
||||
@@ -39,7 +41,9 @@ object SettingsBrowseScreen : SearchableSettings {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
val sourcePreferences = remember { Injekt.get<SourcePreferences>() }
|
||||
val reposCount by sourcePreferences.extensionRepos().collectAsState()
|
||||
val getExtensionRepoCount = remember { Injekt.get<GetExtensionRepoCount>() }
|
||||
|
||||
val reposCount by getExtensionRepoCount.subscribe().collectAsState(0)
|
||||
|
||||
// SY -->
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -90,7 +94,7 @@ object SettingsBrowseScreen : SearchableSettings {
|
||||
pref = uiPreferences.feedTabInFront(),
|
||||
title = stringResource(SYMR.strings.pref_feed_position),
|
||||
subtitle = stringResource(SYMR.strings.pref_feed_position_summery),
|
||||
enabled = hideFeedTab.not()
|
||||
enabled = hideFeedTab.not(),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -104,7 +108,7 @@ object SettingsBrowseScreen : SearchableSettings {
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.label_extension_repos),
|
||||
subtitle = pluralStringResource(MR.plurals.num_repos, reposCount.size, reposCount.size),
|
||||
subtitle = pluralStringResource(MR.plurals.num_repos, reposCount, reposCount),
|
||||
onClick = {
|
||||
navigator.push(ExtensionReposScreen())
|
||||
},
|
||||
|
||||
+57
-31
@@ -127,7 +127,17 @@ object SettingsDataScreen : SearchableSettings {
|
||||
val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
|
||||
context.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
// For some reason InkBook devices do not implement the SAF properly. Persistable URI grants do not
|
||||
// work. However, simply retrieving the URI and using it works fine for these devices. Access is not
|
||||
// revoked after the app is closed or the device is restarted.
|
||||
// This also holds for some Samsung devices. Thus, we simply execute inside of a try-catch block and
|
||||
// ignore the exception if it is thrown.
|
||||
try {
|
||||
context.contentResolver.takePersistableUriPermission(uri, flags)
|
||||
} catch (e: SecurityException) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
context.toast(MR.strings.file_picker_uri_permission_unsupported)
|
||||
}
|
||||
|
||||
UniFile.fromUri(context, uri)?.let {
|
||||
storageDirPref.set(it.uri.toString())
|
||||
@@ -349,15 +359,15 @@ object SettingsDataScreen : SearchableSettings {
|
||||
private fun getSyncPreferences(syncPreferences: SyncPreferences, syncService: Int): List<Preference> {
|
||||
return listOf(
|
||||
Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.pref_sync_service_category),
|
||||
title = stringResource(SYMR.strings.pref_sync_service_category),
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = syncPreferences.syncService(),
|
||||
title = stringResource(MR.strings.pref_sync_service),
|
||||
title = stringResource(SYMR.strings.pref_sync_service),
|
||||
entries = persistentMapOf(
|
||||
SyncManager.SyncService.NONE.value to stringResource(MR.strings.off),
|
||||
SyncManager.SyncService.SYNCYOMI.value to stringResource(MR.strings.syncyomi),
|
||||
SyncManager.SyncService.GOOGLE_DRIVE.value to stringResource(MR.strings.google_drive),
|
||||
SyncManager.SyncService.SYNCYOMI.value to stringResource(SYMR.strings.syncyomi),
|
||||
SyncManager.SyncService.GOOGLE_DRIVE.value to stringResource(SYMR.strings.google_drive),
|
||||
),
|
||||
onValueChanged = { true },
|
||||
),
|
||||
@@ -384,11 +394,23 @@ object SettingsDataScreen : SearchableSettings {
|
||||
syncServiceType: SyncManager.SyncService,
|
||||
syncPreferences: SyncPreferences,
|
||||
): List<Preference> {
|
||||
return when (syncServiceType) {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val preferences = when (syncServiceType) {
|
||||
SyncManager.SyncService.NONE -> emptyList()
|
||||
SyncManager.SyncService.SYNCYOMI -> getSelfHostPreferences(syncPreferences)
|
||||
SyncManager.SyncService.GOOGLE_DRIVE -> getGoogleDrivePreferences()
|
||||
}
|
||||
|
||||
return if (syncServiceType != SyncManager.SyncService.NONE) {
|
||||
preferences + Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(SYMR.strings.pref_choose_what_to_sync),
|
||||
onClick = {
|
||||
navigator.push(SyncSettingsSelector())
|
||||
},
|
||||
)
|
||||
} else {
|
||||
preferences
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -402,7 +424,7 @@ object SettingsDataScreen : SearchableSettings {
|
||||
val googleDriveSync = Injekt.get<GoogleDriveService>()
|
||||
return listOf(
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_google_drive_sign_in),
|
||||
title = stringResource(SYMR.strings.pref_google_drive_sign_in),
|
||||
onClick = {
|
||||
val intent = googleDriveSync.getSignInIntent()
|
||||
context.startActivity(intent)
|
||||
@@ -427,19 +449,19 @@ object SettingsDataScreen : SearchableSettings {
|
||||
val result = googleDriveSync.deleteSyncDataFromGoogleDrive()
|
||||
when (result) {
|
||||
GoogleDriveSyncService.DeleteSyncDataStatus.NOT_INITIALIZED -> context.toast(
|
||||
MR.strings.google_drive_not_signed_in,
|
||||
SYMR.strings.google_drive_not_signed_in,
|
||||
duration = 5000,
|
||||
)
|
||||
GoogleDriveSyncService.DeleteSyncDataStatus.NO_FILES -> context.toast(
|
||||
MR.strings.google_drive_sync_data_not_found,
|
||||
SYMR.strings.google_drive_sync_data_not_found,
|
||||
duration = 5000,
|
||||
)
|
||||
GoogleDriveSyncService.DeleteSyncDataStatus.SUCCESS -> context.toast(
|
||||
MR.strings.google_drive_sync_data_purged,
|
||||
SYMR.strings.google_drive_sync_data_purged,
|
||||
duration = 5000,
|
||||
)
|
||||
GoogleDriveSyncService.DeleteSyncDataStatus.ERROR -> context.toast(
|
||||
MR.strings.google_drive_sync_data_purge_error,
|
||||
SYMR.strings.google_drive_sync_data_purge_error,
|
||||
duration = 10000,
|
||||
)
|
||||
}
|
||||
@@ -450,7 +472,7 @@ object SettingsDataScreen : SearchableSettings {
|
||||
}
|
||||
|
||||
return Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_google_drive_purge_sync_data),
|
||||
title = stringResource(SYMR.strings.pref_google_drive_purge_sync_data),
|
||||
onClick = { showPurgeDialog = true },
|
||||
)
|
||||
}
|
||||
@@ -462,8 +484,8 @@ object SettingsDataScreen : SearchableSettings {
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = { Text(text = stringResource(MR.strings.pref_purge_confirmation_title)) },
|
||||
text = { Text(text = stringResource(MR.strings.pref_purge_confirmation_message)) },
|
||||
title = { Text(text = stringResource(SYMR.strings.pref_purge_confirmation_title)) },
|
||||
text = { Text(text = stringResource(SYMR.strings.pref_purge_confirmation_message)) },
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismissRequest) {
|
||||
Text(text = stringResource(MR.strings.action_cancel))
|
||||
@@ -482,8 +504,8 @@ object SettingsDataScreen : SearchableSettings {
|
||||
val scope = rememberCoroutineScope()
|
||||
return listOf(
|
||||
Preference.PreferenceItem.EditTextPreference(
|
||||
title = stringResource(MR.strings.pref_sync_host),
|
||||
subtitle = stringResource(MR.strings.pref_sync_host_summ),
|
||||
title = stringResource(SYMR.strings.pref_sync_host),
|
||||
subtitle = stringResource(SYMR.strings.pref_sync_host_summ),
|
||||
pref = syncPreferences.clientHost(),
|
||||
onValueChanged = { newValue ->
|
||||
scope.launch {
|
||||
@@ -496,8 +518,8 @@ object SettingsDataScreen : SearchableSettings {
|
||||
},
|
||||
),
|
||||
Preference.PreferenceItem.EditTextPreference(
|
||||
title = stringResource(MR.strings.pref_sync_api_key),
|
||||
subtitle = stringResource(MR.strings.pref_sync_api_key_summ),
|
||||
title = stringResource(SYMR.strings.pref_sync_api_key),
|
||||
subtitle = stringResource(SYMR.strings.pref_sync_api_key_summ),
|
||||
pref = syncPreferences.clientAPIKey(),
|
||||
),
|
||||
)
|
||||
@@ -505,16 +527,20 @@ object SettingsDataScreen : SearchableSettings {
|
||||
|
||||
@Composable
|
||||
private fun getSyncNowPref(): Preference.PreferenceGroup {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val context = LocalContext.current
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.pref_sync_now_group_title),
|
||||
title = stringResource(SYMR.strings.pref_sync_now_group_title),
|
||||
preferenceItems = persistentListOf(
|
||||
getSyncOptionsPref(),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_sync_now),
|
||||
subtitle = stringResource(MR.strings.pref_sync_now_subtitle),
|
||||
title = stringResource(SYMR.strings.pref_sync_now),
|
||||
subtitle = stringResource(SYMR.strings.pref_sync_now_subtitle),
|
||||
onClick = {
|
||||
navigator.push(SyncSettingsSelector())
|
||||
if (!SyncDataJob.isRunning(context)) {
|
||||
SyncDataJob.startNow(context)
|
||||
} else {
|
||||
context.toast(SYMR.strings.sync_in_progress)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -525,8 +551,8 @@ object SettingsDataScreen : SearchableSettings {
|
||||
private fun getSyncOptionsPref(): Preference.PreferenceItem.TextPreference {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
return Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.pref_sync_options),
|
||||
subtitle = stringResource(MR.strings.pref_sync_options_summ),
|
||||
title = stringResource(SYMR.strings.pref_sync_options),
|
||||
subtitle = stringResource(SYMR.strings.pref_sync_options_summ),
|
||||
onClick = { navigator.push(SyncTriggerOptionsScreen()) },
|
||||
)
|
||||
}
|
||||
@@ -538,16 +564,16 @@ object SettingsDataScreen : SearchableSettings {
|
||||
val lastSync by syncPreferences.lastSyncTimestamp().collectAsState()
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.pref_sync_automatic_category),
|
||||
title = stringResource(SYMR.strings.pref_sync_automatic_category),
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = syncIntervalPref,
|
||||
title = stringResource(MR.strings.pref_sync_interval),
|
||||
title = stringResource(SYMR.strings.pref_sync_interval),
|
||||
entries = persistentMapOf(
|
||||
0 to stringResource(MR.strings.off),
|
||||
30 to stringResource(MR.strings.update_30min),
|
||||
60 to stringResource(MR.strings.update_1hour),
|
||||
180 to stringResource(MR.strings.update_3hour),
|
||||
30 to stringResource(SYMR.strings.update_30min),
|
||||
60 to stringResource(SYMR.strings.update_1hour),
|
||||
180 to stringResource(SYMR.strings.update_3hour),
|
||||
360 to stringResource(MR.strings.update_6hour),
|
||||
720 to stringResource(MR.strings.update_12hour),
|
||||
1440 to stringResource(MR.strings.update_24hour),
|
||||
@@ -560,7 +586,7 @@ object SettingsDataScreen : SearchableSettings {
|
||||
},
|
||||
),
|
||||
Preference.PreferenceItem.InfoPreference(
|
||||
stringResource(MR.strings.last_synchronization, relativeTimeSpanString(lastSync)),
|
||||
stringResource(SYMR.strings.last_synchronization, relativeTimeSpanString(lastSync)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
+6
@@ -120,6 +120,7 @@ object SettingsDownloadScreen : SearchableSettings {
|
||||
allCategories: List<Category>,
|
||||
): Preference.PreferenceGroup {
|
||||
val downloadNewChaptersPref = downloadPreferences.downloadNewChapters()
|
||||
val downloadNewUnreadChaptersOnlyPref = downloadPreferences.downloadNewUnreadChaptersOnly()
|
||||
val downloadNewChapterCategoriesPref = downloadPreferences.downloadNewChapterCategories()
|
||||
val downloadNewChapterCategoriesExcludePref = downloadPreferences.downloadNewChapterCategoriesExclude()
|
||||
|
||||
@@ -152,6 +153,11 @@ object SettingsDownloadScreen : SearchableSettings {
|
||||
pref = downloadNewChaptersPref,
|
||||
title = stringResource(MR.strings.pref_download_new),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = downloadNewUnreadChaptersOnlyPref,
|
||||
title = stringResource(MR.strings.pref_download_new_unread_chapters_only),
|
||||
enabled = downloadNewChapters,
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = stringResource(MR.strings.categories),
|
||||
subtitle = getCategoriesLabel(
|
||||
|
||||
@@ -84,9 +84,6 @@ object SettingsLibraryScreen : SearchableSettings {
|
||||
val scope = rememberCoroutineScope()
|
||||
val userCategoriesCount = allCategories.filterNot(Category::isSystemCategory).size
|
||||
|
||||
val defaultCategory by libraryPreferences.defaultCategory().collectAsState()
|
||||
val selectedCategory = allCategories.find { it.id == defaultCategory.toLong() }
|
||||
|
||||
// For default category
|
||||
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
|
||||
allCategories.fastMap { it.id.toInt() }
|
||||
@@ -108,7 +105,6 @@ object SettingsLibraryScreen : SearchableSettings {
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = libraryPreferences.defaultCategory(),
|
||||
title = stringResource(MR.strings.default_category),
|
||||
subtitle = selectedCategory?.visualName ?: stringResource(MR.strings.default_category_summary),
|
||||
entries = ids.zip(labels).toMap().toImmutableMap(),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
|
||||
+62
-11
@@ -17,6 +17,7 @@ import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
import uy.kohesive.injekt.Injekt
|
||||
@@ -35,6 +36,7 @@ object SettingsReaderScreen : SearchableSettings {
|
||||
// SY -->
|
||||
val forceHorizontalSeekbar by readerPref.forceHorizontalSeekbar().collectAsState()
|
||||
// SY <--
|
||||
|
||||
return listOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = readerPref.defaultReadingMode(),
|
||||
@@ -81,24 +83,14 @@ object SettingsReaderScreen : SearchableSettings {
|
||||
enabled = !forceHorizontalSeekbar,
|
||||
),
|
||||
// SY <--
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = readerPref.trueColor(),
|
||||
title = stringResource(MR.strings.pref_true_color),
|
||||
subtitle = stringResource(MR.strings.pref_true_color_summary),
|
||||
enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,
|
||||
),
|
||||
/* SY -->
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = readerPref.pageTransitions(),
|
||||
title = stringResource(MR.strings.pref_page_transitions),
|
||||
),
|
||||
SY <-- */
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = readerPref.flashOnPageChange(),
|
||||
title = stringResource(MR.strings.pref_flash_page),
|
||||
subtitle = stringResource(MR.strings.pref_flash_page_summ),
|
||||
),
|
||||
getDisplayGroup(readerPreferences = readerPref),
|
||||
getEInkGroup(readerPreferences = readerPref),
|
||||
getReadingGroup(readerPreferences = readerPref),
|
||||
getPagedGroup(readerPreferences = readerPref),
|
||||
getWebtoonGroup(readerPreferences = readerPref),
|
||||
@@ -161,6 +153,65 @@ object SettingsReaderScreen : SearchableSettings {
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getEInkGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
|
||||
val flashPageState by readerPreferences.flashOnPageChange().collectAsState()
|
||||
|
||||
val flashMillisPref = readerPreferences.flashDurationMillis()
|
||||
val flashMillis by flashMillisPref.collectAsState()
|
||||
|
||||
val flashIntervalPref = readerPreferences.flashPageInterval()
|
||||
val flashInterval by flashIntervalPref.collectAsState()
|
||||
|
||||
val flashColorPref = readerPreferences.flashColor()
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = "E-Ink",
|
||||
preferenceItems = persistentListOf(
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = readerPreferences.flashOnPageChange(),
|
||||
title = stringResource(MR.strings.pref_flash_page),
|
||||
subtitle = stringResource(MR.strings.pref_flash_page_summ),
|
||||
),
|
||||
Preference.PreferenceItem.SliderPreference(
|
||||
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
|
||||
min = 1,
|
||||
max = 15,
|
||||
title = stringResource(MR.strings.pref_flash_duration),
|
||||
subtitle = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
|
||||
onValueChanged = {
|
||||
flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION)
|
||||
true
|
||||
},
|
||||
enabled = flashPageState,
|
||||
),
|
||||
Preference.PreferenceItem.SliderPreference(
|
||||
value = flashInterval,
|
||||
min = 1,
|
||||
max = 10,
|
||||
title = stringResource(MR.strings.pref_flash_page_interval),
|
||||
subtitle = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
|
||||
onValueChanged = {
|
||||
flashIntervalPref.set(it)
|
||||
true
|
||||
},
|
||||
enabled = flashPageState,
|
||||
),
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = flashColorPref,
|
||||
title = stringResource(MR.strings.pref_flash_with),
|
||||
entries = persistentMapOf(
|
||||
ReaderPreferences.FlashColor.BLACK to stringResource(MR.strings.pref_flash_style_black),
|
||||
ReaderPreferences.FlashColor.WHITE to stringResource(MR.strings.pref_flash_style_white),
|
||||
ReaderPreferences.FlashColor.WHITE_BLACK
|
||||
to stringResource(MR.strings.pref_flash_style_white_black),
|
||||
),
|
||||
enabled = flashPageState,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getReadingGroup(readerPreferences: ReaderPreferences): Preference.PreferenceGroup {
|
||||
return Preference.PreferenceGroup(
|
||||
|
||||
@@ -56,10 +56,9 @@ import tachiyomi.presentation.core.icons.Reddit
|
||||
import tachiyomi.presentation.core.icons.X
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.time.Instant
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
|
||||
object AboutScreen : Screen() {
|
||||
|
||||
@@ -293,11 +292,15 @@ object AboutScreen : Screen() {
|
||||
|
||||
internal fun getFormattedBuildTime(): String {
|
||||
return try {
|
||||
val df = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'", Locale.US)
|
||||
.withZone(ZoneId.of("UTC"))
|
||||
val buildTime = LocalDateTime.from(df.parse(BuildConfig.BUILD_TIME))
|
||||
|
||||
buildTime!!.toDateTimestampString(UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get()))
|
||||
LocalDateTime.ofInstant(
|
||||
Instant.parse(BuildConfig.BUILD_TIME),
|
||||
ZoneId.systemDefault(),
|
||||
)
|
||||
.toDateTimestampString(
|
||||
UiPreferences.dateFormat(
|
||||
Injekt.get<UiPreferences>().dateFormat().get(),
|
||||
),
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
BuildConfig.BUILD_TIME
|
||||
}
|
||||
|
||||
+6
-5
@@ -32,12 +32,13 @@ class OpenSourceLicensesScreen : Screen() {
|
||||
.fillMaxSize(),
|
||||
contentPadding = contentPadding,
|
||||
onLibraryClick = {
|
||||
val libraryLicenseScreen = OpenSourceLibraryLicenseScreen(
|
||||
name = it.library.name,
|
||||
website = it.library.website,
|
||||
license = it.library.licenses.firstOrNull()?.htmlReadyLicenseContent.orEmpty(),
|
||||
navigator.push(
|
||||
OpenSourceLibraryLicenseScreen(
|
||||
name = it.name,
|
||||
website = it.website,
|
||||
license = it.licenses.firstOrNull()?.htmlReadyLicenseContent.orEmpty(),
|
||||
),
|
||||
)
|
||||
navigator.push(libraryLicenseScreen)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
+24
-3
@@ -8,11 +8,15 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoConfirmDialog
|
||||
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoConflictDialog
|
||||
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoCreateDialog
|
||||
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionRepoDeleteDialog
|
||||
import eu.kanade.presentation.more.settings.screen.browse.components.ExtensionReposScreen
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||
|
||||
@@ -29,7 +33,7 @@ class ExtensionReposScreen(
|
||||
val state by screenModel.state.collectAsState()
|
||||
|
||||
LaunchedEffect(url) {
|
||||
url?.let { screenModel.createRepo(it) }
|
||||
url?.let { screenModel.showDialog(RepoDialog.Confirm(it)) }
|
||||
}
|
||||
|
||||
if (state is RepoScreenState.Loading) {
|
||||
@@ -42,17 +46,19 @@ class ExtensionReposScreen(
|
||||
ExtensionReposScreen(
|
||||
state = successState,
|
||||
onClickCreate = { screenModel.showDialog(RepoDialog.Create) },
|
||||
onOpenWebsite = { context.openInBrowser(it.website) },
|
||||
onClickDelete = { screenModel.showDialog(RepoDialog.Delete(it)) },
|
||||
onClickRefresh = { screenModel.refreshRepos() },
|
||||
navigateUp = navigator::pop,
|
||||
)
|
||||
|
||||
when (val dialog = successState.dialog) {
|
||||
null -> {}
|
||||
RepoDialog.Create -> {
|
||||
is RepoDialog.Create -> {
|
||||
ExtensionRepoCreateDialog(
|
||||
onDismissRequest = screenModel::dismissDialog,
|
||||
onCreate = { screenModel.createRepo(it) },
|
||||
repos = successState.repos,
|
||||
repoUrls = successState.repos.map { it.baseUrl }.toImmutableSet(),
|
||||
)
|
||||
}
|
||||
is RepoDialog.Delete -> {
|
||||
@@ -62,6 +68,21 @@ class ExtensionReposScreen(
|
||||
repo = dialog.repo,
|
||||
)
|
||||
}
|
||||
is RepoDialog.Conflict -> {
|
||||
ExtensionRepoConflictDialog(
|
||||
onDismissRequest = screenModel::dismissDialog,
|
||||
onMigrate = { screenModel.replaceRepo(dialog.newRepo) },
|
||||
oldRepo = dialog.oldRepo,
|
||||
newRepo = dialog.newRepo,
|
||||
)
|
||||
}
|
||||
is RepoDialog.Confirm -> {
|
||||
ExtensionRepoConfirmDialog(
|
||||
onDismissRequest = screenModel::dismissDialog,
|
||||
onCreate = { screenModel.createRepo(dialog.url) },
|
||||
repo = dialog.url,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
+49
-14
@@ -4,24 +4,29 @@ import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import eu.kanade.domain.extension.interactor.CreateExtensionRepo
|
||||
import eu.kanade.domain.extension.interactor.DeleteExtensionRepo
|
||||
import eu.kanade.domain.extension.interactor.GetExtensionRepos
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import mihon.domain.extensionrepo.interactor.CreateExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.DeleteExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.GetExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.ReplaceExtensionRepo
|
||||
import mihon.domain.extensionrepo.interactor.UpdateExtensionRepo
|
||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||
import tachiyomi.core.common.util.lang.launchIO
|
||||
import tachiyomi.i18n.MR
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class ExtensionReposScreenModel(
|
||||
private val getExtensionRepos: GetExtensionRepos = Injekt.get(),
|
||||
private val getExtensionRepo: GetExtensionRepo = Injekt.get(),
|
||||
private val createExtensionRepo: CreateExtensionRepo = Injekt.get(),
|
||||
private val deleteExtensionRepo: DeleteExtensionRepo = Injekt.get(),
|
||||
private val replaceExtensionRepo: ReplaceExtensionRepo = Injekt.get(),
|
||||
private val updateExtensionRepo: UpdateExtensionRepo = Injekt.get(),
|
||||
) : StateScreenModel<RepoScreenState>(RepoScreenState.Loading) {
|
||||
|
||||
private val _events: Channel<RepoEvent> = Channel(Int.MAX_VALUE)
|
||||
@@ -29,7 +34,7 @@ class ExtensionReposScreenModel(
|
||||
|
||||
init {
|
||||
screenModelScope.launchIO {
|
||||
getExtensionRepos.subscribe()
|
||||
getExtensionRepo.subscribeAll()
|
||||
.collectLatest { repos ->
|
||||
mutableState.update {
|
||||
RepoScreenState.Success(
|
||||
@@ -43,25 +48,51 @@ class ExtensionReposScreenModel(
|
||||
/**
|
||||
* Creates and adds a new repo to the database.
|
||||
*
|
||||
* @param name The name of the repo to create.
|
||||
* @param baseUrl The baseUrl of the repo to create.
|
||||
*/
|
||||
fun createRepo(name: String) {
|
||||
fun createRepo(baseUrl: String) {
|
||||
screenModelScope.launchIO {
|
||||
when (createExtensionRepo.await(name)) {
|
||||
is CreateExtensionRepo.Result.InvalidUrl -> _events.send(RepoEvent.InvalidUrl)
|
||||
when (val result = createExtensionRepo.await(baseUrl)) {
|
||||
CreateExtensionRepo.Result.InvalidUrl -> _events.send(RepoEvent.InvalidUrl)
|
||||
CreateExtensionRepo.Result.RepoAlreadyExists -> _events.send(RepoEvent.RepoAlreadyExists)
|
||||
is CreateExtensionRepo.Result.DuplicateFingerprint -> {
|
||||
showDialog(RepoDialog.Conflict(result.oldRepo, result.newRepo))
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given repo from the database.
|
||||
* Inserts a repo to the database, replace a matching repo with the same signing key fingerprint if found.
|
||||
*
|
||||
* @param repo The repo to delete.
|
||||
* @param newRepo The repo to insert
|
||||
*/
|
||||
fun deleteRepo(repo: String) {
|
||||
fun replaceRepo(newRepo: ExtensionRepo) {
|
||||
screenModelScope.launchIO {
|
||||
deleteExtensionRepo.await(repo)
|
||||
replaceExtensionRepo.await(newRepo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes information for each repository.
|
||||
*/
|
||||
fun refreshRepos() {
|
||||
val status = state.value
|
||||
|
||||
if (status is RepoScreenState.Success) {
|
||||
screenModelScope.launchIO {
|
||||
updateExtensionRepo.awaitAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the given repo from the database
|
||||
*/
|
||||
fun deleteRepo(baseUrl: String) {
|
||||
screenModelScope.launchIO {
|
||||
deleteExtensionRepo.await(baseUrl)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +118,14 @@ class ExtensionReposScreenModel(
|
||||
sealed class RepoEvent {
|
||||
sealed class LocalizedMessage(val stringRes: StringResource) : RepoEvent()
|
||||
data object InvalidUrl : LocalizedMessage(MR.strings.invalid_repo_name)
|
||||
data object RepoAlreadyExists : LocalizedMessage(MR.strings.error_repo_exists)
|
||||
}
|
||||
|
||||
sealed class RepoDialog {
|
||||
data object Create : RepoDialog()
|
||||
data class Delete(val repo: String) : RepoDialog()
|
||||
data class Conflict(val oldRepo: ExtensionRepo, val newRepo: ExtensionRepo) : RepoDialog()
|
||||
data class Confirm(val url: String) : RepoDialog()
|
||||
}
|
||||
|
||||
sealed class RepoScreenState {
|
||||
@@ -101,7 +135,8 @@ sealed class RepoScreenState {
|
||||
|
||||
@Immutable
|
||||
data class Success(
|
||||
val repos: ImmutableSet<String>,
|
||||
val repos: ImmutableSet<ExtensionRepo>,
|
||||
val oldRepos: ImmutableSet<String>? = null,
|
||||
val dialog: RepoDialog? = null,
|
||||
) : RepoScreenState() {
|
||||
|
||||
|
||||
+21
-5
@@ -9,6 +9,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.Label
|
||||
import androidx.compose.material.icons.automirrored.outlined.OpenInNew
|
||||
import androidx.compose.material.icons.outlined.ContentCopy
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
@@ -22,15 +23,17 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
||||
@Composable
|
||||
fun ExtensionReposContent(
|
||||
repos: ImmutableSet<String>,
|
||||
repos: ImmutableSet<ExtensionRepo>,
|
||||
lazyListState: LazyListState,
|
||||
paddingValues: PaddingValues,
|
||||
onOpenWebsite: (ExtensionRepo) -> Unit,
|
||||
onClickDelete: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
@@ -45,7 +48,8 @@ fun ExtensionReposContent(
|
||||
ExtensionRepoListItem(
|
||||
modifier = Modifier.animateItemPlacement(),
|
||||
repo = it,
|
||||
onDelete = { onClickDelete(it) },
|
||||
onOpenWebsite = { onOpenWebsite(it) },
|
||||
onDelete = { onClickDelete(it.baseUrl) },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -54,7 +58,8 @@ fun ExtensionReposContent(
|
||||
|
||||
@Composable
|
||||
private fun ExtensionRepoListItem(
|
||||
repo: String,
|
||||
repo: ExtensionRepo,
|
||||
onOpenWebsite: () -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
@@ -74,16 +79,27 @@ private fun ExtensionRepoListItem(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(imageVector = Icons.AutoMirrored.Outlined.Label, contentDescription = null)
|
||||
Text(text = repo, modifier = Modifier.padding(start = MaterialTheme.padding.medium))
|
||||
Text(
|
||||
text = repo.name,
|
||||
modifier = Modifier.padding(start = MaterialTheme.padding.medium),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
) {
|
||||
IconButton(onClick = onOpenWebsite) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Outlined.OpenInNew,
|
||||
contentDescription = stringResource(MR.strings.action_open_in_browser),
|
||||
)
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
val url = "$repo/index.min.json"
|
||||
val url = "${repo.baseUrl}/index.min.json"
|
||||
context.copyToClipboard(url, url)
|
||||
},
|
||||
) {
|
||||
|
||||
+71
-2
@@ -1,6 +1,7 @@
|
||||
package eu.kanade.presentation.more.settings.screen.browse.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
@@ -14,8 +15,10 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.coroutines.delay
|
||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -24,12 +27,12 @@ import kotlin.time.Duration.Companion.seconds
|
||||
fun ExtensionRepoCreateDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onCreate: (String) -> Unit,
|
||||
repos: ImmutableSet<String>,
|
||||
repoUrls: ImmutableSet<String>,
|
||||
) {
|
||||
var name by remember { mutableStateOf("") }
|
||||
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val nameAlreadyExists = remember(name) { repos.contains(name) }
|
||||
val nameAlreadyExists = remember(name) { repoUrls.contains(name) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
@@ -73,6 +76,7 @@ fun ExtensionRepoCreateDialog(
|
||||
Text(text = stringResource(msgRes))
|
||||
},
|
||||
isError = name.isNotEmpty() && nameAlreadyExists,
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
|
||||
singleLine = true,
|
||||
)
|
||||
}
|
||||
@@ -115,3 +119,68 @@ fun ExtensionRepoDeleteDialog(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExtensionRepoConflictDialog(
|
||||
oldRepo: ExtensionRepo,
|
||||
newRepo: ExtensionRepo,
|
||||
onDismissRequest: () -> Unit,
|
||||
onMigrate: () -> Unit,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onMigrate()
|
||||
onDismissRequest()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.action_replace_repo))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismissRequest) {
|
||||
Text(text = stringResource(MR.strings.action_cancel))
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(text = stringResource(MR.strings.action_replace_repo_title))
|
||||
},
|
||||
text = {
|
||||
Text(text = stringResource(MR.strings.action_replace_repo_message, newRepo.name, oldRepo.name))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExtensionRepoConfirmDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onCreate: () -> Unit,
|
||||
repo: String,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
title = {
|
||||
Text(text = stringResource(MR.strings.action_add_repo))
|
||||
},
|
||||
text = {
|
||||
Text(text = stringResource(MR.strings.add_repo_confirmation, repo))
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onCreate()
|
||||
onDismissRequest()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.action_add))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismissRequest) {
|
||||
Text(text = stringResource(MR.strings.action_cancel))
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
+16
@@ -5,12 +5,17 @@ package eu.kanade.presentation.more.settings.screen.browse.components
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Refresh
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.presentation.more.settings.screen.browse.RepoScreenState
|
||||
import mihon.domain.extensionrepo.model.ExtensionRepo
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.Scaffold
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
@@ -23,7 +28,9 @@ import tachiyomi.presentation.core.util.plus
|
||||
fun ExtensionReposScreen(
|
||||
state: RepoScreenState.Success,
|
||||
onClickCreate: () -> Unit,
|
||||
onOpenWebsite: (ExtensionRepo) -> Unit,
|
||||
onClickDelete: (String) -> Unit,
|
||||
onClickRefresh: () -> Unit,
|
||||
navigateUp: () -> Unit,
|
||||
) {
|
||||
val lazyListState = rememberLazyListState()
|
||||
@@ -33,6 +40,14 @@ fun ExtensionReposScreen(
|
||||
navigateUp = navigateUp,
|
||||
title = stringResource(MR.strings.label_extension_repos),
|
||||
scrollBehavior = scrollBehavior,
|
||||
actions = {
|
||||
IconButton(onClick = onClickRefresh) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Refresh,
|
||||
contentDescription = stringResource(resource = MR.strings.action_webview_refresh),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
@@ -55,6 +70,7 @@ fun ExtensionReposScreen(
|
||||
lazyListState = lazyListState,
|
||||
paddingValues = paddingValues + topSmallPaddingValues +
|
||||
PaddingValues(horizontal = MaterialTheme.padding.medium),
|
||||
onOpenWebsite = onOpenWebsite,
|
||||
onClickDelete = onClickDelete,
|
||||
)
|
||||
}
|
||||
|
||||
+2
-4
@@ -6,7 +6,6 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@@ -27,7 +26,6 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.update
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.LabeledCheckbox
|
||||
import tachiyomi.presentation.core.components.LazyColumnWithAction
|
||||
import tachiyomi.presentation.core.components.SectionCard
|
||||
@@ -69,7 +67,7 @@ class CreateBackupScreen : Screen() {
|
||||
LazyColumnWithAction(
|
||||
contentPadding = contentPadding,
|
||||
actionLabel = stringResource(MR.strings.action_create),
|
||||
actionEnabled = state.options.anyEnabled(),
|
||||
actionEnabled = state.options.canCreate(),
|
||||
onClickAction = {
|
||||
if (!BackupCreateJob.isManualJobRunning(context)) {
|
||||
try {
|
||||
@@ -104,7 +102,7 @@ class CreateBackupScreen : Screen() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Options(
|
||||
private fun Options(
|
||||
options: ImmutableList<BackupOptions.Entry>,
|
||||
state: CreateBackupScreenModel.State,
|
||||
model: CreateBackupScreenModel,
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ class RestoreBackupScreen(
|
||||
LazyColumnWithAction(
|
||||
contentPadding = contentPadding,
|
||||
actionLabel = stringResource(MR.strings.action_restore),
|
||||
actionEnabled = state.canRestore && state.options.anyEnabled(),
|
||||
actionEnabled = state.canRestore && state.options.canRestore(),
|
||||
onClickAction = {
|
||||
model.startRestore()
|
||||
navigator.pop()
|
||||
|
||||
+19
-12
@@ -5,7 +5,6 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
@@ -16,10 +15,10 @@ import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.tachiyomi.data.backup.create.BackupOptions
|
||||
import eu.kanade.tachiyomi.data.sync.SyncDataJob
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.update
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.LabeledCheckbox
|
||||
import tachiyomi.presentation.core.components.LazyColumnWithAction
|
||||
import tachiyomi.presentation.core.components.SectionCard
|
||||
@@ -31,7 +30,6 @@ import uy.kohesive.injekt.api.get
|
||||
class SyncSettingsSelector : Screen() {
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val context = LocalContext.current
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val model = rememberScreenModel { SyncSettingsSelectorModel() }
|
||||
val state by model.state.collectAsState()
|
||||
@@ -39,7 +37,7 @@ class SyncSettingsSelector : Screen() {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppBar(
|
||||
title = stringResource(MR.strings.pref_choose_what_to_sync),
|
||||
title = stringResource(SYMR.strings.pref_choose_what_to_sync),
|
||||
navigateUp = navigator::pop,
|
||||
scrollBehavior = it,
|
||||
)
|
||||
@@ -47,15 +45,10 @@ class SyncSettingsSelector : Screen() {
|
||||
) { contentPadding ->
|
||||
LazyColumnWithAction(
|
||||
contentPadding = contentPadding,
|
||||
actionLabel = stringResource(MR.strings.label_sync),
|
||||
actionEnabled = state.options.anyEnabled(),
|
||||
actionLabel = stringResource(MR.strings.action_save),
|
||||
actionEnabled = true,
|
||||
onClickAction = {
|
||||
if (!SyncDataJob.isAnyJobRunning(context)) {
|
||||
model.syncNow(context)
|
||||
navigator.pop()
|
||||
} else {
|
||||
context.toast(MR.strings.sync_in_progress)
|
||||
}
|
||||
navigator.pop()
|
||||
},
|
||||
) {
|
||||
item {
|
||||
@@ -121,8 +114,15 @@ private class SyncSettingsSelectorModel(
|
||||
tracking = syncSettings.tracking,
|
||||
history = syncSettings.history,
|
||||
appSettings = syncSettings.appSettings,
|
||||
extensionRepoSettings = syncSettings.extensionRepoSettings,
|
||||
sourceSettings = syncSettings.sourceSettings,
|
||||
privateSettings = syncSettings.privateSettings,
|
||||
|
||||
// SY -->
|
||||
customInfo = syncSettings.customInfo,
|
||||
readEntries = syncSettings.readEntries,
|
||||
savedSearches = syncSettings.savedSearches,
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
|
||||
@@ -134,8 +134,15 @@ private class SyncSettingsSelectorModel(
|
||||
tracking = backupOptions.tracking,
|
||||
history = backupOptions.history,
|
||||
appSettings = backupOptions.appSettings,
|
||||
extensionRepoSettings = backupOptions.extensionRepoSettings,
|
||||
sourceSettings = backupOptions.sourceSettings,
|
||||
privateSettings = backupOptions.privateSettings,
|
||||
|
||||
// SY -->
|
||||
customInfo = backupOptions.customInfo,
|
||||
readEntries = backupOptions.readEntries,
|
||||
savedSearches = backupOptions.savedSearches,
|
||||
// SY <--
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.sync.models.SyncTriggerOptions
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.update
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.LabeledCheckbox
|
||||
import tachiyomi.presentation.core.components.LazyColumnWithAction
|
||||
import tachiyomi.presentation.core.components.SectionCard
|
||||
@@ -34,7 +35,7 @@ class SyncTriggerOptionsScreen : Screen() {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppBar(
|
||||
title = stringResource(MR.strings.pref_sync_options),
|
||||
title = stringResource(SYMR.strings.pref_sync_options),
|
||||
navigateUp = navigator::pop,
|
||||
scrollBehavior = it,
|
||||
)
|
||||
@@ -43,13 +44,13 @@ class SyncTriggerOptionsScreen : Screen() {
|
||||
LazyColumnWithAction(
|
||||
contentPadding = contentPadding,
|
||||
actionLabel = stringResource(MR.strings.action_save),
|
||||
actionEnabled = state.options.anyEnabled(),
|
||||
actionEnabled = true,
|
||||
onClickAction = {
|
||||
navigator.pop()
|
||||
},
|
||||
) {
|
||||
item {
|
||||
SectionCard(MR.strings.label_triggers) {
|
||||
SectionCard(SYMR.strings.label_triggers) {
|
||||
Options(SyncTriggerOptions.mainOptions, state, model)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@ import tachiyomi.presentation.core.i18n.stringResource
|
||||
class BackupSchemaScreen : Screen() {
|
||||
|
||||
companion object {
|
||||
const val title = "Backup file schema"
|
||||
const val TITLE = "Backup file schema"
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -41,7 +41,7 @@ class BackupSchemaScreen : Screen() {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppBar(
|
||||
title = title,
|
||||
title = TITLE,
|
||||
navigateUp = navigator::pop,
|
||||
actions = {
|
||||
AppBarActions(
|
||||
@@ -50,7 +50,7 @@ class BackupSchemaScreen : Screen() {
|
||||
title = stringResource(MR.strings.action_copy_to_clipboard),
|
||||
icon = Icons.Default.ContentCopy,
|
||||
onClick = {
|
||||
context.copyToClipboard(title, schema)
|
||||
context.copyToClipboard(TITLE, schema)
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
+2
-2
@@ -31,11 +31,11 @@ class DebugInfoScreen : Screen() {
|
||||
itemsProvider = {
|
||||
listOf(
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = WorkerInfoScreen.title,
|
||||
title = WorkerInfoScreen.TITLE,
|
||||
onClick = { navigator.push(WorkerInfoScreen()) },
|
||||
),
|
||||
Preference.PreferenceItem.TextPreference(
|
||||
title = BackupSchemaScreen.title,
|
||||
title = BackupSchemaScreen.TITLE,
|
||||
onClick = { navigator.push(BackupSchemaScreen()) },
|
||||
),
|
||||
getAppInfoGroup(),
|
||||
|
||||
+4
-4
@@ -49,7 +49,7 @@ import java.time.ZoneId
|
||||
class WorkerInfoScreen : Screen() {
|
||||
|
||||
companion object {
|
||||
const val title = "Worker info"
|
||||
const val TITLE = "Worker info"
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -65,7 +65,7 @@ class WorkerInfoScreen : Screen() {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AppBar(
|
||||
title = title,
|
||||
title = TITLE,
|
||||
navigateUp = navigator::pop,
|
||||
actions = {
|
||||
AppBarActions(
|
||||
@@ -74,7 +74,7 @@ class WorkerInfoScreen : Screen() {
|
||||
title = stringResource(MR.strings.action_copy_to_clipboard),
|
||||
icon = Icons.Default.ContentCopy,
|
||||
onClick = {
|
||||
context.copyToClipboard(title, enqueued + finished + running)
|
||||
context.copyToClipboard(TITLE, enqueued + finished + running)
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -159,7 +159,7 @@ class WorkerInfoScreen : Screen() {
|
||||
Injekt.get<UiPreferences>().dateFormat().get(),
|
||||
),
|
||||
)
|
||||
appendLine("Next scheduled run: $timestamp",)
|
||||
appendLine("Next scheduled run: $timestamp")
|
||||
appendLine("Attempt #${workInfo.runAttemptCount + 1}")
|
||||
}
|
||||
appendLine()
|
||||
|
||||
+1
-2
@@ -223,13 +223,12 @@ fun AppThemePreviewItem(
|
||||
contentAlignment = Alignment.BottomCenter,
|
||||
) {
|
||||
Surface(
|
||||
tonalElevation = 3.dp,
|
||||
color = MaterialTheme.colorScheme.surfaceContainer,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(32.dp)
|
||||
.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.padding(horizontal = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
||||
@@ -34,7 +34,9 @@ import tachiyomi.presentation.core.util.isScrolledToEnd
|
||||
import tachiyomi.presentation.core.util.isScrolledToStart
|
||||
|
||||
private enum class State {
|
||||
CHECKED, INVERSED, UNCHECKED
|
||||
CHECKED,
|
||||
INVERSED,
|
||||
UNCHECKED,
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -15,7 +15,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.SECONDARY_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
|
||||
@Composable
|
||||
@@ -73,7 +73,7 @@ private fun RowScope.BaseStatsItem(
|
||||
style = subtitleStyle
|
||||
.copy(
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
.copy(alpha = SecondaryItemAlpha),
|
||||
.copy(alpha = SECONDARY_ALPHA),
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
@@ -226,7 +226,7 @@ private fun ChapterText(
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
if (downloaded) {
|
||||
appendInlineContent(DownloadedIconContentId)
|
||||
appendInlineContent(DOWNLOADED_ICON_ID)
|
||||
append(' ')
|
||||
}
|
||||
append(name)
|
||||
@@ -236,7 +236,7 @@ private fun ChapterText(
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
inlineContent = persistentMapOf(
|
||||
DownloadedIconContentId to InlineTextContent(
|
||||
DOWNLOADED_ICON_ID to InlineTextContent(
|
||||
Placeholder(
|
||||
width = 22.sp,
|
||||
height = 22.sp,
|
||||
@@ -273,7 +273,7 @@ private val CardColor: CardColors
|
||||
)
|
||||
|
||||
private val VerticalSpacerSize = 24.dp
|
||||
private const val DownloadedIconContentId = "downloaded"
|
||||
private const val DOWNLOADED_ICON_ID = "downloaded"
|
||||
|
||||
private fun previewChapter(name: String, scanlator: String, chapterNumber: Double) = Chapter.create().copy(
|
||||
id = 0L,
|
||||
|
||||
@@ -7,19 +7,42 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Stable
|
||||
class DisplayRefreshHost {
|
||||
|
||||
internal var currentDisplayRefresh by mutableStateOf(false)
|
||||
private val readerPreferences = Injekt.get<ReaderPreferences>()
|
||||
|
||||
internal val flashMillis = readerPreferences.flashDurationMillis()
|
||||
internal val flashMode = readerPreferences.flashColor()
|
||||
|
||||
internal val flashIntervalPref = readerPreferences.flashPageInterval()
|
||||
|
||||
// Internal State for Flash
|
||||
private var flashInterval = flashIntervalPref.get()
|
||||
private var timesCalled = 0
|
||||
|
||||
fun flash() {
|
||||
currentDisplayRefresh = true
|
||||
if (timesCalled % flashInterval == 0) {
|
||||
currentDisplayRefresh = true
|
||||
}
|
||||
timesCalled += 1
|
||||
}
|
||||
|
||||
fun setInterval(interval: Int) {
|
||||
flashInterval = interval
|
||||
timesCalled = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +52,39 @@ fun DisplayRefreshHost(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val currentDisplayRefresh = hostState.currentDisplayRefresh
|
||||
val refreshDuration by hostState.flashMillis.collectAsState()
|
||||
val flashMode by hostState.flashMode.collectAsState()
|
||||
val flashInterval by hostState.flashIntervalPref.collectAsState()
|
||||
|
||||
var currentColor by remember { mutableStateOf<Color?>(null) }
|
||||
|
||||
LaunchedEffect(currentDisplayRefresh) {
|
||||
if (currentDisplayRefresh) {
|
||||
delay(1.5.seconds)
|
||||
hostState.currentDisplayRefresh = false
|
||||
if (!currentDisplayRefresh) {
|
||||
currentColor = null
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
val refreshDurationHalf = refreshDuration.milliseconds / 2
|
||||
currentColor = if (flashMode == ReaderPreferences.FlashColor.BLACK) {
|
||||
Color.Black
|
||||
} else {
|
||||
Color.White
|
||||
}
|
||||
delay(refreshDurationHalf)
|
||||
if (flashMode == ReaderPreferences.FlashColor.WHITE_BLACK) {
|
||||
currentColor = Color.Black
|
||||
}
|
||||
delay(refreshDurationHalf)
|
||||
hostState.currentDisplayRefresh = false
|
||||
}
|
||||
|
||||
LaunchedEffect(flashInterval) {
|
||||
hostState.setInterval(flashInterval)
|
||||
}
|
||||
|
||||
Canvas(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
) {
|
||||
if (currentDisplayRefresh) {
|
||||
drawRect(Color.Black)
|
||||
}
|
||||
currentColor?.let { drawRect(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.ContentCopy
|
||||
import androidx.compose.material.icons.outlined.Photo
|
||||
import androidx.compose.material.icons.outlined.Save
|
||||
import androidx.compose.material.icons.outlined.Share
|
||||
@@ -31,9 +32,9 @@ fun ReaderPageActionsDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
// SY -->
|
||||
onSetAsCover: (useExtraPage: Boolean) -> Unit,
|
||||
onShare: (useExtraPage: Boolean) -> Unit,
|
||||
onShare: (copy: Boolean, useExtraPage: Boolean) -> Unit,
|
||||
onSave: (useExtraPage: Boolean) -> Unit,
|
||||
onShareCombined: () -> Unit,
|
||||
onShareCombined: (copy: Boolean) -> Unit,
|
||||
onSaveCombined: () -> Unit,
|
||||
hasExtraPage: Boolean,
|
||||
// SY <--
|
||||
@@ -43,9 +44,7 @@ fun ReaderPageActionsDialog(
|
||||
var useExtraPage by remember { mutableStateOf(false) }
|
||||
// SY <--
|
||||
|
||||
AdaptiveSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
) {
|
||||
AdaptiveSheet(onDismissRequest = onDismissRequest) {
|
||||
Column(modifier = Modifier.padding(vertical = 16.dp)) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||
@@ -64,6 +63,25 @@ fun ReaderPageActionsDialog(
|
||||
icon = Icons.Outlined.Photo,
|
||||
onClick = { showSetCoverDialog = true },
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(
|
||||
// SY -->
|
||||
if (hasExtraPage) {
|
||||
SYMR.strings.action_copy_first_page
|
||||
} else {
|
||||
MR.strings.action_copy_to_clipboard
|
||||
},
|
||||
// SY <--
|
||||
),
|
||||
icon = Icons.Outlined.ContentCopy,
|
||||
onClick = {
|
||||
// SY -->
|
||||
onShare(true, false)
|
||||
// SY <--
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(
|
||||
@@ -78,7 +96,7 @@ fun ReaderPageActionsDialog(
|
||||
icon = Icons.Outlined.Share,
|
||||
onClick = {
|
||||
// SY -->
|
||||
onShare(false)
|
||||
onShare(false, false)
|
||||
// SY <--
|
||||
onDismissRequest()
|
||||
},
|
||||
@@ -116,12 +134,21 @@ fun ReaderPageActionsDialog(
|
||||
showSetCoverDialog = true
|
||||
},
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(SYMR.strings.action_copy_second_page),
|
||||
icon = Icons.Outlined.ContentCopy,
|
||||
onClick = {
|
||||
onShare(true, true)
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(SYMR.strings.action_share_second_page),
|
||||
icon = Icons.Outlined.Share,
|
||||
onClick = {
|
||||
onShare(true)
|
||||
onShare(false, true)
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
@@ -138,12 +165,21 @@ fun ReaderPageActionsDialog(
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||
) {
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(SYMR.strings.action_copy_combined_page),
|
||||
icon = Icons.Outlined.ContentCopy,
|
||||
onClick = {
|
||||
onShareCombined(true)
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
ActionButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
title = stringResource(SYMR.strings.action_share_combined_page),
|
||||
icon = Icons.Outlined.Share,
|
||||
onClick = {
|
||||
onShareCombined()
|
||||
onShareCombined(false)
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
|
||||
@@ -63,7 +63,7 @@ fun ExhUtils(
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.background(backgroundColor),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
AnimatedVisibility(visible = isVisible) {
|
||||
Column {
|
||||
@@ -84,7 +84,7 @@ fun ExhUtils(
|
||||
) {
|
||||
Column(
|
||||
Modifier.weight(3f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(SYMR.strings.eh_autoscroll),
|
||||
@@ -93,17 +93,17 @@ fun ExhUtils(
|
||||
fontFamily = FontFamily.SansSerif,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.fillMaxWidth(0.75f),
|
||||
textAlign = TextAlign.Center
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
Modifier.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Switch(
|
||||
checked = isAutoScroll,
|
||||
onCheckedChange = null,
|
||||
enabled = isAutoScrollEnabled
|
||||
enabled = isAutoScrollEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ fun ExhUtils(
|
||||
) {
|
||||
Column(
|
||||
Modifier.weight(3f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
var autoScrollFrequencyState by remember {
|
||||
mutableStateOf(autoScrollFrequency)
|
||||
|
||||
@@ -5,11 +5,14 @@ import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.i18n.sy.SYMR
|
||||
import tachiyomi.presentation.core.components.CheckboxItem
|
||||
import tachiyomi.presentation.core.components.SettingsChipRow
|
||||
import tachiyomi.presentation.core.components.SliderItem
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
|
||||
@@ -20,9 +23,27 @@ private val themes = listOf(
|
||||
MR.strings.automatic_background to 3,
|
||||
)
|
||||
|
||||
private val flashColors = listOf(
|
||||
MR.strings.pref_flash_style_black to ReaderPreferences.FlashColor.BLACK,
|
||||
MR.strings.pref_flash_style_white to ReaderPreferences.FlashColor.WHITE,
|
||||
MR.strings.pref_flash_style_white_black to ReaderPreferences.FlashColor.WHITE_BLACK,
|
||||
)
|
||||
|
||||
@Composable
|
||||
internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
||||
val readerTheme by screenModel.preferences.readerTheme().collectAsState()
|
||||
|
||||
val flashPageState by screenModel.preferences.flashOnPageChange().collectAsState()
|
||||
|
||||
val flashMillisPref = screenModel.preferences.flashDurationMillis()
|
||||
val flashMillis by flashMillisPref.collectAsState()
|
||||
|
||||
val flashIntervalPref = screenModel.preferences.flashPageInterval()
|
||||
val flashInterval by flashIntervalPref.collectAsState()
|
||||
|
||||
val flashColorPref = screenModel.preferences.flashColor()
|
||||
val flashColor by flashColorPref.collectAsState()
|
||||
|
||||
SettingsChipRow(MR.strings.pref_reader_theme) {
|
||||
themes.map { (labelRes, value) ->
|
||||
FilterChip(
|
||||
@@ -95,6 +116,35 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
||||
label = stringResource(MR.strings.pref_flash_page),
|
||||
pref = screenModel.preferences.flashOnPageChange(),
|
||||
)
|
||||
if (flashPageState) {
|
||||
SliderItem(
|
||||
value = flashMillis / ReaderPreferences.MILLI_CONVERSION,
|
||||
label = stringResource(MR.strings.pref_flash_duration),
|
||||
valueText = stringResource(MR.strings.pref_flash_duration_summary, flashMillis),
|
||||
onChange = { flashMillisPref.set(it * ReaderPreferences.MILLI_CONVERSION) },
|
||||
min = 1,
|
||||
max = 15,
|
||||
)
|
||||
SliderItem(
|
||||
value = flashInterval,
|
||||
label = stringResource(MR.strings.pref_flash_page_interval),
|
||||
valueText = pluralStringResource(MR.plurals.pref_pages, flashInterval, flashInterval),
|
||||
onChange = {
|
||||
flashIntervalPref.set(it)
|
||||
},
|
||||
min = 1,
|
||||
max = 10,
|
||||
)
|
||||
SettingsChipRow(MR.strings.pref_flash_with) {
|
||||
flashColors.map { (labelRes, value) ->
|
||||
FilterChip(
|
||||
selected = flashColor == value,
|
||||
onClick = { flashColorPref.set(value) },
|
||||
label = { Text(stringResource(labelRes)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SY -->
|
||||
CheckboxItem(
|
||||
|
||||
@@ -8,6 +8,12 @@ internal abstract class BaseColorScheme {
|
||||
abstract val darkScheme: ColorScheme
|
||||
abstract val lightScheme: ColorScheme
|
||||
|
||||
// Cannot be pure black as there's content scrolling behind it
|
||||
// https://m3.material.io/components/navigation-bar/guidelines#90615a71-607e-485e-9e09-778bfc080563
|
||||
private val surfaceContainer = Color(0xFF0C0C0C)
|
||||
private val surfaceContainerHigh = Color(0xFF131313)
|
||||
private val surfaceContainerHighest = Color(0xFF1B1B1B)
|
||||
|
||||
fun getColorScheme(isDark: Boolean, isAmoled: Boolean): ColorScheme {
|
||||
if (!isDark) return lightScheme
|
||||
|
||||
@@ -18,6 +24,12 @@ internal abstract class BaseColorScheme {
|
||||
onBackground = Color.White,
|
||||
surface = Color.Black,
|
||||
onSurface = Color.White,
|
||||
surfaceVariant = surfaceContainer, // Navigation bar background (ThemePrefWidget)
|
||||
surfaceContainerLowest = surfaceContainer,
|
||||
surfaceContainerLow = surfaceContainer,
|
||||
surfaceContainer = surfaceContainer, // Navigation bar background
|
||||
surfaceContainerHigh = surfaceContainerHigh,
|
||||
surfaceContainerHighest = surfaceContainerHighest,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+67
-43
@@ -19,53 +19,77 @@ internal object GreenAppleColorScheme : BaseColorScheme() {
|
||||
|
||||
override val darkScheme = darkColorScheme(
|
||||
primary = Color(0xFF7ADB8F),
|
||||
onPrimary = Color(0xFF003915),
|
||||
primaryContainer = Color(0xFF005322),
|
||||
onPrimaryContainer = Color(0xFF96F8A9),
|
||||
inversePrimary = Color(0xFF006D2F),
|
||||
secondary = Color(0xFF7ADB8F),
|
||||
onSecondary = Color(0xFF003915),
|
||||
secondaryContainer = Color(0xFF005322),
|
||||
onSecondaryContainer = Color(0xFF96F8A9),
|
||||
tertiary = Color(0xFFFFB3AA),
|
||||
onTertiary = Color(0xFF680006),
|
||||
tertiaryContainer = Color(0xFF93000D),
|
||||
onTertiaryContainer = Color(0xFFFFDAD5),
|
||||
background = Color(0xFF1A1C19),
|
||||
onBackground = Color(0xFFE1E3DD),
|
||||
surface = Color(0xFF1A1C19),
|
||||
onSurface = Color(0xFFE1E3DD),
|
||||
surfaceVariant = Color(0xFF414941),
|
||||
onSurfaceVariant = Color(0xFFC1C8BE),
|
||||
surfaceTint = Color(0xFF7ADB8F),
|
||||
inverseSurface = Color(0xFFE1E3DD),
|
||||
inverseOnSurface = Color(0xFF1A1C19),
|
||||
outline = Color(0xFF8B9389),
|
||||
onPrimary = Color(0xFF003917),
|
||||
primaryContainer = Color(0xFF017737),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFF7ADB8F), // Unread badge
|
||||
onSecondary = Color(0xFF003917), // Unread badge text
|
||||
secondaryContainer = Color(0xFF017737), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFFFFFFF), // Navigation bar selected icon
|
||||
tertiary = Color(0xFFFFB3AC), // Downloaded badge
|
||||
onTertiary = Color(0xFF680008), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFC7282A),
|
||||
onTertiaryContainer = Color(0xFFFFFFFF),
|
||||
error = Color(0xFFFFB4AB),
|
||||
onError = Color(0xFF690005),
|
||||
errorContainer = Color(0xFF93000A),
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
background = Color(0xFF0F1510),
|
||||
onBackground = Color(0xFFDFE4DB),
|
||||
surface = Color(0xFF0F1510),
|
||||
onSurface = Color(0xFFDFE4DB),
|
||||
surfaceVariant = Color(0xFF3F493F), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFBECABC),
|
||||
outline = Color(0xFF889487),
|
||||
outlineVariant = Color(0xFF3F493F),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFFDFE4DB),
|
||||
inverseOnSurface = Color(0xFF2C322C),
|
||||
inversePrimary = Color(0xFF006D32),
|
||||
surfaceDim = Color(0xFF0F1510),
|
||||
surfaceBright = Color(0xFF353B35),
|
||||
surfaceContainerLowest = Color(0xFF0A0F0B),
|
||||
surfaceContainerLow = Color(0xFF181D18),
|
||||
surfaceContainer = Color(0xFF1C211C), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF262B26),
|
||||
surfaceContainerHighest = Color(0xFF313630),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
primary = Color(0xFF006D2F),
|
||||
primary = Color(0xFF005927),
|
||||
onPrimary = Color(0xFFFFFFFF),
|
||||
primaryContainer = Color(0xFF96F8A9),
|
||||
onPrimaryContainer = Color(0xFF002109),
|
||||
primaryContainer = Color(0xFF188140),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFF005927), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFF97f7a9), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF000000), // Navigation bar selected icon
|
||||
tertiary = Color(0xFF9D0012), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFD33131),
|
||||
onTertiaryContainer = Color(0xFFFFFFFF),
|
||||
error = Color(0xFFBA1A1A),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFFFDAD6),
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
background = Color(0xFFF6FBF2),
|
||||
onBackground = Color(0xFF181D18),
|
||||
surface = Color(0xFFF6FBF2),
|
||||
onSurface = Color(0xFF181D18),
|
||||
surfaceVariant = Color(0xFFDAE6D7), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF3F493F),
|
||||
outline = Color(0xFF6F7A6E),
|
||||
outlineVariant = Color(0xFFBECABC),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFF2C322C),
|
||||
inverseOnSurface = Color(0xFFEDF2E9),
|
||||
inversePrimary = Color(0xFF7ADB8F),
|
||||
secondary = Color(0xFF006D2F),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFF96F8A9),
|
||||
onSecondaryContainer = Color(0xFF002109),
|
||||
tertiary = Color(0xFFB91D22),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
tertiaryContainer = Color(0xFFFFDAD5),
|
||||
onTertiaryContainer = Color(0xFF410003),
|
||||
background = Color(0xFFFBFDF7),
|
||||
onBackground = Color(0xFF1A1C19),
|
||||
surface = Color(0xFFFBFDF7),
|
||||
onSurface = Color(0xFF1A1C19),
|
||||
surfaceVariant = Color(0xFFDDE5DA),
|
||||
onSurfaceVariant = Color(0xFF414941),
|
||||
surfaceTint = Color(0xFF006D2F),
|
||||
inverseSurface = Color(0xFF2F312E),
|
||||
inverseOnSurface = Color(0xFFF0F2EC),
|
||||
outline = Color(0xFF717970),
|
||||
surfaceDim = Color(0xFFD6DCD3),
|
||||
surfaceBright = Color(0xFFF6FBF2),
|
||||
surfaceContainerLowest = Color(0xFFFFFFFF),
|
||||
surfaceContainerLow = Color(0xFFF0F5EC),
|
||||
surfaceContainer = Color(0xFFEAEFE6), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFE4EAE1),
|
||||
surfaceContainerHighest = Color(0xFFDFE4DB),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,53 +18,77 @@ internal object LavenderColorScheme : BaseColorScheme() {
|
||||
|
||||
override val darkScheme = darkColorScheme(
|
||||
primary = Color(0xFFA177FF),
|
||||
onPrimary = Color(0xFF111129),
|
||||
onPrimary = Color(0xFF3D0090),
|
||||
primaryContainer = Color(0xFFA177FF),
|
||||
onPrimaryContainer = Color(0xFF111129),
|
||||
inversePrimary = Color(0xFF006D2F),
|
||||
secondary = Color(0xFFA177FF),
|
||||
onSecondary = Color(0xFF111129),
|
||||
secondaryContainer = Color(0xFFA177FF),
|
||||
onSecondaryContainer = Color(0xFF111129),
|
||||
tertiary = Color(0xFF5E25E1),
|
||||
onTertiary = Color(0xFFE8E8E8),
|
||||
tertiaryContainer = Color(0xFF111129),
|
||||
onTertiaryContainer = Color(0xFFDEE8FF),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFA177FF), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFF423271), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFA177FF), // Navigation bar selected icon
|
||||
tertiary = Color(0xFFCDBDFF), // Downloaded badge
|
||||
onTertiary = Color(0xFF360096), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF5512D8),
|
||||
onTertiaryContainer = Color(0xFFEFE6FF),
|
||||
error = Color(0xFFFFB4AB),
|
||||
onError = Color(0xFF690005),
|
||||
errorContainer = Color(0xFF93000A),
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
background = Color(0xFF111129),
|
||||
onBackground = Color(0xFFDEE8FF),
|
||||
onBackground = Color(0xFFE7E0EC),
|
||||
surface = Color(0xFF111129),
|
||||
onSurface = Color(0xFFDEE8FF),
|
||||
surfaceVariant = Color(0x2CB6B6B6),
|
||||
onSurfaceVariant = Color(0xFFE8E8E8),
|
||||
surfaceTint = Color(0xFFA177FF),
|
||||
inverseSurface = Color(0xFF221247),
|
||||
inverseOnSurface = Color(0xFFDEE8FF),
|
||||
outline = Color(0xA8905FFF),
|
||||
onSurface = Color(0xFFE7E0EC),
|
||||
surfaceVariant = Color(0xFF3D2F6B), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFCBC3D6),
|
||||
outline = Color(0xFF958E9F),
|
||||
outlineVariant = Color(0xFF4A4453),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFFE7E0EC),
|
||||
inverseOnSurface = Color(0xFF322F38),
|
||||
inversePrimary = Color(0xFF6D41C8),
|
||||
surfaceDim = Color(0xFF111129),
|
||||
surfaceBright = Color(0xFF3B3841),
|
||||
surfaceContainerLowest = Color(0xFF15132d),
|
||||
surfaceContainerLow = Color(0xFF171531),
|
||||
surfaceContainer = Color(0xFF1D193B), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF241f41),
|
||||
surfaceContainerHighest = Color(0xFF282446),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
primary = Color(0xFF7B46AF),
|
||||
onPrimary = Color(0xFFEDE2FF),
|
||||
primary = Color(0xFF6D41C8),
|
||||
onPrimary = Color(0xFFFFFFFF),
|
||||
primaryContainer = Color(0xFF7B46AF),
|
||||
onPrimaryContainer = Color(0xFFEDE2FF),
|
||||
inversePrimary = Color(0xFFD6BAFF),
|
||||
secondary = Color(0xFF7B46AF),
|
||||
onSecondary = Color(0xFFEDE2FF),
|
||||
secondaryContainer = Color(0xFF7B46AF),
|
||||
onSecondaryContainer = Color(0xFFEDE2FF),
|
||||
tertiary = Color(0xFFEDE2FF),
|
||||
onTertiary = Color(0xFF7B46AF),
|
||||
tertiaryContainer = Color(0xFFEDE2FF),
|
||||
onTertiaryContainer = Color(0xFF7B46AF),
|
||||
onPrimaryContainer = Color(0xFF130038),
|
||||
secondary = Color(0xFF7B46AF), // Unread badge
|
||||
onSecondary = Color(0xFFEDE2FF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFC9B0E6), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF7B46AF), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFEDE2FF), // Downloaded badge
|
||||
onTertiary = Color(0xFF7B46AF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF6D3BF0),
|
||||
onTertiaryContainer = Color(0xFFFFFFFF),
|
||||
error = Color(0xFFBA1A1A),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFFFDAD6),
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
background = Color(0xFFEDE2FF),
|
||||
onBackground = Color(0xFF1B1B22),
|
||||
onBackground = Color(0xFF1D1A22),
|
||||
surface = Color(0xFFEDE2FF),
|
||||
onSurface = Color(0xFF1B1B22),
|
||||
surfaceVariant = Color(0xFFB9B0CC),
|
||||
onSurfaceVariant = Color(0xD849454E),
|
||||
surfaceTint = Color(0xFF7B46AF),
|
||||
inverseSurface = Color(0xFF313033),
|
||||
inverseOnSurface = Color(0xFFF3EFF4),
|
||||
outline = Color(0xFF7B46AF),
|
||||
onSurface = Color(0xFF1D1A22),
|
||||
surfaceVariant = Color(0xFFE4D5F8), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF4A4453),
|
||||
outline = Color(0xFF7B7485),
|
||||
outlineVariant = Color(0xFFCBC3D6),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFF322F38),
|
||||
inverseOnSurface = Color(0xFFF5EEFA),
|
||||
inversePrimary = Color(0xFFA177FF),
|
||||
surfaceDim = Color(0xFFDED7E3),
|
||||
surfaceBright = Color(0xFFEDE2FF),
|
||||
surfaceContainerLowest = Color(0xFFDACCEC),
|
||||
surfaceContainerLow = Color(0xFFDED0F1),
|
||||
surfaceContainer = Color(0xFFE4D5F8), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFEADCFD),
|
||||
surfaceContainerHighest = Color(0xFFEEE2FF),
|
||||
)
|
||||
}
|
||||
|
||||
+24
-14
@@ -23,24 +23,29 @@ internal object MidnightDuskColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFBD1C5C),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
inversePrimary = Color(0xFFF02475),
|
||||
secondary = Color(0xFFF02475),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFF02475),
|
||||
onSecondaryContainer = Color(0xFFFFFFFF),
|
||||
tertiary = Color(0xFF55971C),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFF02475), // Unread badge
|
||||
onSecondary = Color(0xFF16151D), // Unread badge text
|
||||
secondaryContainer = Color(0xFF66183C), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFF02475), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF55971C), // Downloaded badge
|
||||
onTertiary = Color(0xFF16151D), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF386412),
|
||||
onTertiaryContainer = Color(0xFFE5E1E5),
|
||||
background = Color(0xFF16151D),
|
||||
onBackground = Color(0xFFE5E1E5),
|
||||
surface = Color(0xFF16151D),
|
||||
onSurface = Color(0xFFE5E1E5),
|
||||
surfaceVariant = Color(0xFF524346),
|
||||
surfaceVariant = Color(0xFF281624), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFD6C1C4),
|
||||
surfaceTint = Color(0xFFF02475),
|
||||
inverseSurface = Color(0xFF333043),
|
||||
inverseOnSurface = Color(0xFFFFFFFF),
|
||||
outline = Color(0xFF9F8C8F),
|
||||
surfaceContainerLowest = Color(0xFF221320),
|
||||
surfaceContainerLow = Color(0xFF251522),
|
||||
surfaceContainer = Color(0xFF281624), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF2D1C2A),
|
||||
surfaceContainerHighest = Color(0xFF2F1F2C),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -49,23 +54,28 @@ internal object MidnightDuskColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFFFD9E1),
|
||||
onPrimaryContainer = Color(0xFF3F0017),
|
||||
inversePrimary = Color(0xFFFFB1C4),
|
||||
secondary = Color(0xFFBB0054),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFFFD9E1),
|
||||
onSecondaryContainer = Color(0xFF3F0017),
|
||||
tertiary = Color(0xFF006638),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFBB0054), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFEFBAD4), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFD1377C), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF006638), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF00894b),
|
||||
onTertiaryContainer = Color(0xFF2D1600),
|
||||
background = Color(0xFFFFFBFF),
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
surface = Color(0xFFFFFBFF),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
surfaceVariant = Color(0xFFF3DDE0),
|
||||
surfaceVariant = Color(0xFFF9E6F1), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF524346),
|
||||
surfaceTint = Color(0xFFBB0054),
|
||||
inverseSurface = Color(0xFF313033),
|
||||
inverseOnSurface = Color(0xFFF4F0F4),
|
||||
outline = Color(0xFF847376),
|
||||
surfaceContainerLowest = Color(0xFFDAC0CD),
|
||||
surfaceContainerLow = Color(0xFFE8D1DD),
|
||||
surfaceContainer = Color(0xFFF9E6F1), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFFCF3F8),
|
||||
surfaceContainerHighest = Color(0xFFFEF9FC),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,19 +17,19 @@ internal object NordColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF88C0D0),
|
||||
onPrimaryContainer = Color(0xFF2E3440),
|
||||
inversePrimary = Color(0xFF397E91),
|
||||
secondary = Color(0xFF81A1C1),
|
||||
onSecondary = Color(0xFF2E3440),
|
||||
secondaryContainer = Color(0xFF81A1C1),
|
||||
onSecondaryContainer = Color(0xFF2E3440),
|
||||
tertiary = Color(0xFF5E81AC),
|
||||
onTertiary = Color(0xFF000000),
|
||||
secondary = Color(0xFF81A1C1), // Unread badge
|
||||
onSecondary = Color(0xFF2E3440), // Unread badge text
|
||||
secondaryContainer = Color(0xFF506275), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF88C0D0), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF5E81AC), // Downloaded badge
|
||||
onTertiary = Color(0xFF000000), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF5E81AC),
|
||||
onTertiaryContainer = Color(0xFF000000),
|
||||
background = Color(0xFF2E3440),
|
||||
onBackground = Color(0xFFECEFF4),
|
||||
surface = Color(0xFF3B4252),
|
||||
surface = Color(0xFF2E3440),
|
||||
onSurface = Color(0xFFECEFF4),
|
||||
surfaceVariant = Color(0xFF2E3440),
|
||||
surfaceVariant = Color(0xFF414C5C), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFECEFF4),
|
||||
surfaceTint = Color(0xFF88C0D0),
|
||||
inverseSurface = Color(0xFFD8DEE9),
|
||||
@@ -39,6 +39,11 @@ internal object NordColorScheme : BaseColorScheme() {
|
||||
onError = Color(0xFF2E3440),
|
||||
errorContainer = Color(0xFFBF616A),
|
||||
onErrorContainer = Color(0xFF000000),
|
||||
surfaceContainerLowest = Color(0xFF373F4D),
|
||||
surfaceContainerLow = Color(0xFF3E4756),
|
||||
surfaceContainer = Color(0xFF414C5C),
|
||||
surfaceContainerHigh = Color(0xFF4E5766),
|
||||
surfaceContainerHighest = Color(0xFF505968), // Navigation bar background
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -47,19 +52,19 @@ internal object NordColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF5E81AC),
|
||||
onPrimaryContainer = Color(0xFF000000),
|
||||
inversePrimary = Color(0xFF8CA8CD),
|
||||
secondary = Color(0xFF81A1C1),
|
||||
onSecondary = Color(0xFF2E3440),
|
||||
secondaryContainer = Color(0xFF81A1C1),
|
||||
onSecondaryContainer = Color(0xFF2E3440),
|
||||
tertiary = Color(0xFF88C0D0),
|
||||
onTertiary = Color(0xFF2E3440),
|
||||
secondary = Color(0xFF81A1C1), // Unread badge
|
||||
onSecondary = Color(0xFF2E3440), // Unread badge text
|
||||
secondaryContainer = Color(0xFF91B4D7), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF2E3440), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF88C0D0), // Downloaded badge
|
||||
onTertiary = Color(0xFF2E3440), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF88C0D0),
|
||||
onTertiaryContainer = Color(0xFF2E3440),
|
||||
background = Color(0xFFECEFF4),
|
||||
onBackground = Color(0xFF2E3440),
|
||||
surface = Color(0xFFE5E9F0),
|
||||
onSurface = Color(0xFF2E3440),
|
||||
surfaceVariant = Color(0xFFffffff),
|
||||
surfaceVariant = Color(0xFFDAE0EA), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF2E3440),
|
||||
surfaceTint = Color(0xFF5E81AC),
|
||||
inverseSurface = Color(0xFF3B4252),
|
||||
@@ -68,5 +73,10 @@ internal object NordColorScheme : BaseColorScheme() {
|
||||
onError = Color(0xFFECEFF4),
|
||||
errorContainer = Color(0xFFBF616A),
|
||||
onErrorContainer = Color(0xFF000000),
|
||||
surfaceContainerLowest = Color(0xFFD1D7E0),
|
||||
surfaceContainerLow = Color(0xFFD6DCE6),
|
||||
surfaceContainer = Color(0xFFDAE0EA), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFE9EDF3),
|
||||
surfaceContainerHighest = Color(0xFFF2F4F8),
|
||||
)
|
||||
}
|
||||
|
||||
+67
-43
@@ -18,54 +18,78 @@ import androidx.compose.ui.graphics.Color
|
||||
internal object StrawberryColorScheme : BaseColorScheme() {
|
||||
|
||||
override val darkScheme = darkColorScheme(
|
||||
primary = Color(0xFFFFB2B9),
|
||||
onPrimary = Color(0xFF67001B),
|
||||
primaryContainer = Color(0xFF91002A),
|
||||
onPrimaryContainer = Color(0xFFFFDADD),
|
||||
inversePrimary = Color(0xFFB61E40),
|
||||
secondary = Color(0xFFFFB2B9),
|
||||
onSecondary = Color(0xFF67001B),
|
||||
secondaryContainer = Color(0xFF91002A),
|
||||
onSecondaryContainer = Color(0xFFFFDADD),
|
||||
tertiary = Color(0xFFE8C08E),
|
||||
onTertiary = Color(0xFF432C06),
|
||||
tertiaryContainer = Color(0xFF5D421B),
|
||||
onTertiaryContainer = Color(0xFFFFDDB1),
|
||||
primary = Color(0xFFFFB2B8),
|
||||
onPrimary = Color(0xFF67001D),
|
||||
primaryContainer = Color(0xFFD53855),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFED4A65), // Unread badge
|
||||
onSecondary = Color(0xFF201A1A), // Unread badge text
|
||||
secondaryContainer = Color(0xFF91002A), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFFFFFFF), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFE8C08E), // Downloaded badge
|
||||
onTertiary = Color(0xFF201A1A), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF775930),
|
||||
onTertiaryContainer = Color(0xFFFFF7F1),
|
||||
error = Color(0xFFFFB4AB),
|
||||
onError = Color(0xFF690005),
|
||||
errorContainer = Color(0xFF93000A),
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
background = Color(0xFF201A1A),
|
||||
onBackground = Color(0xFFECDFDF),
|
||||
onBackground = Color(0xFFF7DCDD),
|
||||
surface = Color(0xFF201A1A),
|
||||
onSurface = Color(0xFFECDFDF),
|
||||
surfaceVariant = Color(0xFF534344),
|
||||
onSurfaceVariant = Color(0xFFD7C1C2),
|
||||
surfaceTint = Color(0xFFFFB2B9),
|
||||
inverseSurface = Color(0xFFECDFDF),
|
||||
inverseOnSurface = Color(0xFF201A1A),
|
||||
outline = Color(0xFFA08C8D),
|
||||
onSurface = Color(0xFFF7DCDD),
|
||||
surfaceVariant = Color(0xFF322727), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFE1BEC0),
|
||||
outline = Color(0xFFA9898B),
|
||||
outlineVariant = Color(0xFF594042),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFFF7DCDD),
|
||||
inverseOnSurface = Color(0xFF3D2C2D),
|
||||
inversePrimary = Color(0xFFB61F40),
|
||||
surfaceDim = Color(0xFF1D1011),
|
||||
surfaceBright = Color(0xFF463536),
|
||||
surfaceContainerLowest = Color(0xFF2C2222),
|
||||
surfaceContainerLow = Color(0xFF302525),
|
||||
surfaceContainer = Color(0xFF322727), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF3C2F2F),
|
||||
surfaceContainerHighest = Color(0xFF463737),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
primary = Color(0xFFB61E40),
|
||||
primary = Color(0xFFA10833),
|
||||
onPrimary = Color(0xFFFFFFFF),
|
||||
primaryContainer = Color(0xFFFFDADD),
|
||||
onPrimaryContainer = Color(0xFF40000D),
|
||||
inversePrimary = Color(0xFFFFB2B9),
|
||||
secondary = Color(0xFFB61E40),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFFFDADD),
|
||||
onSecondaryContainer = Color(0xFF40000D),
|
||||
tertiary = Color(0xFF775930),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
tertiaryContainer = Color(0xFFFFDDB1),
|
||||
onTertiaryContainer = Color(0xFF2A1800),
|
||||
background = Color(0xFFFCFCFC),
|
||||
onBackground = Color(0xFF201A1A),
|
||||
surface = Color(0xFFFCFCFC),
|
||||
onSurface = Color(0xFF201A1A),
|
||||
surfaceVariant = Color(0xFFF4DDDD),
|
||||
onSurfaceVariant = Color(0xFF534344),
|
||||
surfaceTint = Color(0xFFB61E40),
|
||||
inverseSurface = Color(0xFF362F2F),
|
||||
inverseOnSurface = Color(0xFFFBEDED),
|
||||
outline = Color(0xFF857374),
|
||||
primaryContainer = Color(0xFFD53855),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFA10833), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFD53855), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFF6EAED), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF5F441D), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF87683D),
|
||||
onTertiaryContainer = Color(0xFFFFFFFF),
|
||||
error = Color(0xFFBA1A1A),
|
||||
onError = Color(0xFFFFFFFF),
|
||||
errorContainer = Color(0xFFFFDAD6),
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
background = Color(0xFFFAFAFA),
|
||||
onBackground = Color(0xFF261819),
|
||||
surface = Color(0xFFFAFAFA),
|
||||
onSurface = Color(0xFF261819),
|
||||
surfaceVariant = Color(0xFFF6EAED), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF594042),
|
||||
outline = Color(0xFF8D7071),
|
||||
outlineVariant = Color(0xFFE1BEC0),
|
||||
scrim = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFF3D2C2D),
|
||||
inverseOnSurface = Color(0xFFFFECED),
|
||||
inversePrimary = Color(0xFFFFB2B8),
|
||||
surfaceDim = Color(0xFFEED4D5),
|
||||
surfaceBright = Color(0xFFFFF8F7),
|
||||
surfaceContainerLowest = Color(0xFFF7DCDD),
|
||||
surfaceContainerLow = Color(0xFFFDE2E3),
|
||||
surfaceContainer = Color(0xFFF6EAED), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFFFF0F0),
|
||||
surfaceContainerHighest = Color(0xFFFFFFFF),
|
||||
)
|
||||
}
|
||||
|
||||
+24
-14
@@ -22,19 +22,19 @@ internal object TachiyomiColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF00429B),
|
||||
onPrimaryContainer = Color(0xFFD9E2FF),
|
||||
inversePrimary = Color(0xFF0058CA),
|
||||
secondary = Color(0xFFB0C6FF),
|
||||
onSecondary = Color(0xFF002D6E),
|
||||
secondaryContainer = Color(0xFF00429B),
|
||||
onSecondaryContainer = Color(0xFFD9E2FF),
|
||||
tertiary = Color(0xFF7ADC77),
|
||||
onTertiary = Color(0xFF003909),
|
||||
secondary = Color(0xFFB0C6FF), // Unread badge
|
||||
onSecondary = Color(0xFF002D6E), // Unread badge text
|
||||
secondaryContainer = Color(0xFF00429B), // Navigation bar selector pill & pro
|
||||
onSecondaryContainer = Color(0xFFD9E2FF), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF7ADC77), // Downloaded badge
|
||||
onTertiary = Color(0xFF003909), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF005312),
|
||||
onTertiaryContainer = Color(0xFF95F990),
|
||||
background = Color(0xFF1B1B1F),
|
||||
onBackground = Color(0xFFE3E2E6),
|
||||
surface = Color(0xFF1B1B1F),
|
||||
onSurface = Color(0xFFE3E2E6),
|
||||
surfaceVariant = Color(0xFF44464F),
|
||||
surfaceVariant = Color(0xFF211F26), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFC5C6D0),
|
||||
surfaceTint = Color(0xFFB0C6FF),
|
||||
inverseSurface = Color(0xFFE3E2E6),
|
||||
@@ -45,6 +45,11 @@ internal object TachiyomiColorScheme : BaseColorScheme() {
|
||||
onErrorContainer = Color(0xFFFFDAD6),
|
||||
outline = Color(0xFF8F9099),
|
||||
outlineVariant = Color(0xFF44464F),
|
||||
surfaceContainerLowest = Color(0xFF1A181D),
|
||||
surfaceContainerLow = Color(0xFF1E1C22),
|
||||
surfaceContainer = Color(0xFF211F26), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF292730),
|
||||
surfaceContainerHighest = Color(0xFF302E38),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -53,19 +58,19 @@ internal object TachiyomiColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFD9E2FF),
|
||||
onPrimaryContainer = Color(0xFF001945),
|
||||
inversePrimary = Color(0xFFB0C6FF),
|
||||
secondary = Color(0xFF0058CA),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFD9E2FF),
|
||||
onSecondaryContainer = Color(0xFF001945),
|
||||
tertiary = Color(0xFF006E1B),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFF0058CA), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFD9E2FF), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF001945), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF006E1B), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF95F990),
|
||||
onTertiaryContainer = Color(0xFF002203),
|
||||
background = Color(0xFFFEFBFF),
|
||||
onBackground = Color(0xFF1B1B1F),
|
||||
surface = Color(0xFFFEFBFF),
|
||||
onSurface = Color(0xFF1B1B1F),
|
||||
surfaceVariant = Color(0xFFE1E2EC),
|
||||
surfaceVariant = Color(0xFFF3EDF7), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF44464F),
|
||||
surfaceTint = Color(0xFF0058CA),
|
||||
inverseSurface = Color(0xFF303034),
|
||||
@@ -76,5 +81,10 @@ internal object TachiyomiColorScheme : BaseColorScheme() {
|
||||
onErrorContainer = Color(0xFF410002),
|
||||
outline = Color(0xFF757780),
|
||||
outlineVariant = Color(0xFFC5C6D0),
|
||||
surfaceContainerLowest = Color(0xFFF5F1F8),
|
||||
surfaceContainerLow = Color(0xFFF7F2FA),
|
||||
surfaceContainer = Color(0xFFF3EDF7), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFFCF7FF),
|
||||
surfaceContainerHighest = Color(0xFFFCF7FF),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,24 +23,29 @@ internal object TakoColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFF3B375),
|
||||
onPrimaryContainer = Color(0xFF38294E),
|
||||
inversePrimary = Color(0xFF84531E),
|
||||
secondary = Color(0xFFF3B375),
|
||||
onSecondary = Color(0xFF38294E),
|
||||
secondaryContainer = Color(0xFFF3B375),
|
||||
onSecondaryContainer = Color(0xFF38294E),
|
||||
tertiary = Color(0xFF66577E),
|
||||
onTertiary = Color(0xFFF3B375),
|
||||
secondary = Color(0xFFF3B375), // Unread badge
|
||||
onSecondary = Color(0xFF38294E), // Unread badge text
|
||||
secondaryContainer = Color(0xFF5C4D4B), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFF3B375), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF66577E), // Downloaded badge
|
||||
onTertiary = Color(0xFFF3B375), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF4E4065),
|
||||
onTertiaryContainer = Color(0xFFEDDCFF),
|
||||
background = Color(0xFF21212E),
|
||||
onBackground = Color(0xFFE3E0F2),
|
||||
surface = Color(0xFF21212E),
|
||||
onSurface = Color(0xFFE3E0F2),
|
||||
surfaceVariant = Color(0xFF49454E),
|
||||
surfaceVariant = Color(0xFF2A2A3C), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFCBC4CE),
|
||||
surfaceTint = Color(0xFF66577E),
|
||||
inverseSurface = Color(0xFFE5E1E6),
|
||||
inverseOnSurface = Color(0xFF1B1B1E),
|
||||
outline = Color(0xFF958F99),
|
||||
surfaceContainerLowest = Color(0xFF20202E),
|
||||
surfaceContainerLow = Color(0xFF262636),
|
||||
surfaceContainer = Color(0xFF2A2A3C), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF303044),
|
||||
surfaceContainerHighest = Color(0xFF36364D),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -49,23 +54,28 @@ internal object TakoColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF66577E),
|
||||
onPrimaryContainer = Color(0xFFF3B375),
|
||||
inversePrimary = Color(0xFFD6BAFF),
|
||||
secondary = Color(0xFF66577E),
|
||||
onSecondary = Color(0xFFF3B375),
|
||||
secondaryContainer = Color(0xFF66577E),
|
||||
onSecondaryContainer = Color(0xFFF3B375),
|
||||
tertiary = Color(0xFFF3B375),
|
||||
onTertiary = Color(0xFF574360),
|
||||
secondary = Color(0xFF66577E), // Unread badge
|
||||
onSecondary = Color(0xFFF3B375), // Unread badge text
|
||||
secondaryContainer = Color(0xFFC8BED0), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF66577E), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFF3B375), // Downloaded badge
|
||||
onTertiary = Color(0xFF574360), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFFDD6B0),
|
||||
onTertiaryContainer = Color(0xFF221437),
|
||||
background = Color(0xFFF7F5FF),
|
||||
onBackground = Color(0xFF1B1B22),
|
||||
surface = Color(0xFFF7F5FF),
|
||||
onSurface = Color(0xFF1B1B22),
|
||||
surfaceVariant = Color(0xFFE8E0EB),
|
||||
surfaceVariant = Color(0xFFE8E0EB), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF49454E),
|
||||
surfaceTint = Color(0xFF66577E),
|
||||
inverseSurface = Color(0xFF313033),
|
||||
inverseOnSurface = Color(0xFFF3EFF4),
|
||||
outline = Color(0xFF7A757E),
|
||||
surfaceContainerLowest = Color(0xFFD7D0DA),
|
||||
surfaceContainerLow = Color(0xFFDFD8E2),
|
||||
surfaceContainer = Color(0xFFE8E0EB), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFEEE6F1),
|
||||
surfaceContainerHighest = Color(0xFFF7EEFA),
|
||||
)
|
||||
}
|
||||
|
||||
+24
-14
@@ -15,24 +15,29 @@ internal object TealTurqoiseColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF40E0D0),
|
||||
onPrimaryContainer = Color(0xFF000000),
|
||||
inversePrimary = Color(0xFF008080),
|
||||
secondary = Color(0xFF40E0D0),
|
||||
onSecondary = Color(0xFF000000),
|
||||
secondaryContainer = Color(0xFF18544E),
|
||||
onSecondaryContainer = Color(0xFF40E0D0),
|
||||
tertiary = Color(0xFFBF1F2F),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFF40E0D0), // Unread badge
|
||||
onSecondary = Color(0xFF000000), // Unread badge text
|
||||
secondaryContainer = Color(0xFF18544E), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF40E0D0), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFBF1F2F), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF200508),
|
||||
onTertiaryContainer = Color(0xFFBF1F2F),
|
||||
background = Color(0xFF202125),
|
||||
onBackground = Color(0xFFDFDEDA),
|
||||
surface = Color(0xFF202125),
|
||||
onSurface = Color(0xFFDFDEDA),
|
||||
surfaceVariant = Color(0xFF3F4947),
|
||||
surfaceVariant = Color(0xFF233133), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFDFDEDA),
|
||||
surfaceTint = Color(0xFF40E0D0),
|
||||
inverseSurface = Color(0xFFDFDEDA),
|
||||
inverseOnSurface = Color(0xFF202125),
|
||||
outline = Color(0xFF899391),
|
||||
surfaceContainerLowest = Color(0xFF202C2E),
|
||||
surfaceContainerLow = Color(0xFF222F31),
|
||||
surfaceContainer = Color(0xFF233133), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF28383A),
|
||||
surfaceContainerHighest = Color(0xFF2F4244),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -41,23 +46,28 @@ internal object TealTurqoiseColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF008080),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
inversePrimary = Color(0xFF40E0D0),
|
||||
secondary = Color(0xFF008080),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFBFDFDF),
|
||||
onSecondaryContainer = Color(0xFF008080),
|
||||
tertiary = Color(0xFFFF7F7F),
|
||||
onTertiary = Color(0xFF000000),
|
||||
secondary = Color(0xFF008080), // Unread badge text
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFCFE5E4), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF008080), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFFF7F7F), // Downloaded badge
|
||||
onTertiary = Color(0xFF000000), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF2A1616),
|
||||
onTertiaryContainer = Color(0xFFFF7F7F),
|
||||
background = Color(0xFFFAFAFA),
|
||||
onBackground = Color(0xFF050505),
|
||||
surface = Color(0xFFFAFAFA),
|
||||
onSurface = Color(0xFF050505),
|
||||
surfaceVariant = Color(0xFFDAE5E2),
|
||||
surfaceVariant = Color(0xFFEBF3F1), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF050505),
|
||||
surfaceTint = Color(0xFFBFDFDF),
|
||||
inverseSurface = Color(0xFF050505),
|
||||
inverseOnSurface = Color(0xFFFAFAFA),
|
||||
outline = Color(0xFF6F7977),
|
||||
surfaceContainerLowest = Color(0xFFE1E9E7),
|
||||
surfaceContainerLow = Color(0xFFE6EEEC),
|
||||
surfaceContainer = Color(0xFFEBF3F1), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFF0F8F6),
|
||||
surfaceContainerHighest = Color(0xFFF7FFFD),
|
||||
)
|
||||
}
|
||||
|
||||
+24
-14
@@ -22,24 +22,29 @@ internal object TidalWaveColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF004d61),
|
||||
onPrimaryContainer = Color(0xFFb8eaff),
|
||||
inversePrimary = Color(0xFFa12b03),
|
||||
secondary = Color(0xFF5ed4fc),
|
||||
onSecondary = Color(0xFF003544),
|
||||
secondaryContainer = Color(0xFF004d61),
|
||||
onSecondaryContainer = Color(0xFFb8eaff),
|
||||
tertiary = Color(0xFF92f7bc),
|
||||
onTertiary = Color(0xFF001c3b),
|
||||
secondary = Color(0xFF5ed4fc), // Unread badge
|
||||
onSecondary = Color(0xFF003544), // Unread badge text
|
||||
secondaryContainer = Color(0xFF004d61), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFb8eaff), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF92f7bc), // Downloaded badge
|
||||
onTertiary = Color(0xFF001c3b), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFc3fada),
|
||||
onTertiaryContainer = Color(0xFF78ffd6),
|
||||
background = Color(0xFF001c3b),
|
||||
onBackground = Color(0xFFd5e3ff),
|
||||
surface = Color(0xFF001c3b),
|
||||
onSurface = Color(0xFFd5e3ff),
|
||||
surfaceVariant = Color(0xFF40484c),
|
||||
surfaceVariant = Color(0xFF082b4b), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFbfc8cc),
|
||||
surfaceTint = Color(0xFF5ed4fc),
|
||||
inverseSurface = Color(0xFFffe3c4),
|
||||
inverseOnSurface = Color(0xFF001c3b),
|
||||
outline = Color(0xFF8a9296),
|
||||
surfaceContainerLowest = Color(0xFF072642),
|
||||
surfaceContainerLow = Color(0xFF072947),
|
||||
surfaceContainer = Color(0xFF082b4b), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF093257),
|
||||
surfaceContainerHighest = Color(0xFF0A3861),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -48,23 +53,28 @@ internal object TidalWaveColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFB4D4DF),
|
||||
onPrimaryContainer = Color(0xFF001f28),
|
||||
inversePrimary = Color(0xFFff987f),
|
||||
secondary = Color(0xFF006780),
|
||||
onSecondary = Color(0xFFffffff),
|
||||
secondaryContainer = Color(0xFFb8eaff),
|
||||
onSecondaryContainer = Color(0xFF001f28),
|
||||
tertiary = Color(0xFF92f7bc),
|
||||
onTertiary = Color(0xFF001c3b),
|
||||
secondary = Color(0xFF006780), // Unread badge
|
||||
onSecondary = Color(0xFFffffff), // Unread badge text
|
||||
secondaryContainer = Color(0xFF9AE1FF), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF001f28), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF92f7bc), // Downloaded badge
|
||||
onTertiary = Color(0xFF001c3b), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFc3fada),
|
||||
onTertiaryContainer = Color(0xFF78ffd6),
|
||||
background = Color(0xFFfdfbff),
|
||||
onBackground = Color(0xFF001c3b),
|
||||
surface = Color(0xFFfdfbff),
|
||||
onSurface = Color(0xFF001c3b),
|
||||
surfaceVariant = Color(0xFFdce4e8),
|
||||
surfaceVariant = Color(0xFFe8eff5), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF40484c),
|
||||
surfaceTint = Color(0xFF006780),
|
||||
inverseSurface = Color(0xFF020400),
|
||||
inverseOnSurface = Color(0xFFffe3c4),
|
||||
outline = Color(0xFF70787c),
|
||||
surfaceContainerLowest = Color(0xFFe2e8ec),
|
||||
surfaceContainerLow = Color(0xFFe5ecf1),
|
||||
surfaceContainer = Color(0xFFe8eff5), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFedf4fA),
|
||||
surfaceContainerHighest = Color(0xFFf5faff),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,24 +17,29 @@ internal object YinYangColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFFFFFFF),
|
||||
onPrimaryContainer = Color(0xFF000000),
|
||||
inversePrimary = Color(0xFFCECECE),
|
||||
secondary = Color(0xFFFFFFFF),
|
||||
onSecondary = Color(0xFF5A5A5A),
|
||||
secondaryContainer = Color(0xFF717171),
|
||||
onSecondaryContainer = Color(0xFFE4E4E4),
|
||||
tertiary = Color(0xFF000000),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFFFFFFF), // Unread badge
|
||||
onSecondary = Color(0xFF5A5A5A), // Unread badge text
|
||||
secondaryContainer = Color(0xFF717171), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFE4E4E4), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF000000), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF00419E),
|
||||
onTertiaryContainer = Color(0xFFD8E2FF),
|
||||
background = Color(0xFF1E1E1E),
|
||||
onBackground = Color(0xFFE6E6E6),
|
||||
surface = Color(0xFF1E1E1E),
|
||||
onSurface = Color(0xFFE6E6E6),
|
||||
surfaceVariant = Color(0xFF4E4E4E),
|
||||
surfaceVariant = Color(0xFF313131), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFD1D1D1),
|
||||
surfaceTint = Color(0xFFFFFFFF),
|
||||
inverseSurface = Color(0xFFE6E6E6),
|
||||
inverseOnSurface = Color(0xFF1E1E1E),
|
||||
outline = Color(0xFF999999),
|
||||
surfaceContainerLowest = Color(0xFF2A2A2A),
|
||||
surfaceContainerLow = Color(0xFF2D2D2D),
|
||||
surfaceContainer = Color(0xFF313131), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF383838),
|
||||
surfaceContainerHighest = Color(0xFF3F3F3F),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -43,23 +48,28 @@ internal object YinYangColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF000000),
|
||||
onPrimaryContainer = Color(0xFFFFFFFF),
|
||||
inversePrimary = Color(0xFFA6A6A6),
|
||||
secondary = Color(0xFF000000),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFDDDDDD),
|
||||
onSecondaryContainer = Color(0xFF0C0C0C),
|
||||
tertiary = Color(0xFFFFFFFF),
|
||||
onTertiary = Color(0xFF000000),
|
||||
secondary = Color(0xFF000000), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFDDDDDD), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF0C0C0C), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFFFFFFF), // Downloaded badge
|
||||
onTertiary = Color(0xFF000000), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFD8E2FF),
|
||||
onTertiaryContainer = Color(0xFF001947),
|
||||
background = Color(0xFFFDFDFD),
|
||||
onBackground = Color(0xFF222222),
|
||||
surface = Color(0xFFFDFDFD),
|
||||
onSurface = Color(0xFF222222),
|
||||
surfaceVariant = Color(0xFFEDEDED),
|
||||
surfaceVariant = Color(0xFFE8E8E8), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF515151),
|
||||
surfaceTint = Color(0xFF000000),
|
||||
inverseSurface = Color(0xFF333333),
|
||||
inverseOnSurface = Color(0xFFF4F4F4),
|
||||
outline = Color(0xFF838383),
|
||||
surfaceContainerLowest = Color(0xFFCFCFCF),
|
||||
surfaceContainerLow = Color(0xFFDADADA),
|
||||
surfaceContainer = Color(0xFFE8E8E8), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFECECEC),
|
||||
surfaceContainerHighest = Color(0xFFEFEFEF),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,24 +23,29 @@ internal object YotsubaColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFF862200),
|
||||
onPrimaryContainer = Color(0xFFFFDBCF),
|
||||
inversePrimary = Color(0xFFAE3200),
|
||||
secondary = Color(0xFFFFB59D),
|
||||
onSecondary = Color(0xFF5F1600),
|
||||
secondaryContainer = Color(0xFF862200),
|
||||
onSecondaryContainer = Color(0xFFFFDBCF),
|
||||
tertiary = Color(0xFFD7C68D),
|
||||
onTertiary = Color(0xFF3A2F05),
|
||||
secondary = Color(0xFFFFB59D), // Unread badge
|
||||
onSecondary = Color(0xFF5F1600), // Unread badge text
|
||||
secondaryContainer = Color(0xFF862200), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFFFFDBCF), // Navigation bar selector icon
|
||||
tertiary = Color(0xFFD7C68D), // Downloaded badge
|
||||
onTertiary = Color(0xFF3A2F05), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFF524619),
|
||||
onTertiaryContainer = Color(0xFFF5E2A7),
|
||||
background = Color(0xFF211A18),
|
||||
onBackground = Color(0xFFEDE0DD),
|
||||
surface = Color(0xFF211A18),
|
||||
onSurface = Color(0xFFEDE0DD),
|
||||
surfaceVariant = Color(0xFF53433F),
|
||||
surfaceVariant = Color(0xFF332723), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFFD8C2BC),
|
||||
surfaceTint = Color(0xFFFFB59D),
|
||||
inverseSurface = Color(0xFFEDE0DD),
|
||||
inverseOnSurface = Color(0xFF211A18),
|
||||
outline = Color(0xFFA08C87),
|
||||
surfaceContainerLowest = Color(0xFF2E221F),
|
||||
surfaceContainerLow = Color(0xFF312521),
|
||||
surfaceContainer = Color(0xFF332723), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFF413531),
|
||||
surfaceContainerHighest = Color(0xFF4C403D),
|
||||
)
|
||||
|
||||
override val lightScheme = lightColorScheme(
|
||||
@@ -49,23 +54,28 @@ internal object YotsubaColorScheme : BaseColorScheme() {
|
||||
primaryContainer = Color(0xFFFFDBCF),
|
||||
onPrimaryContainer = Color(0xFF3B0A00),
|
||||
inversePrimary = Color(0xFFFFB59D),
|
||||
secondary = Color(0xFFAE3200),
|
||||
onSecondary = Color(0xFFFFFFFF),
|
||||
secondaryContainer = Color(0xFFFFDBCF),
|
||||
onSecondaryContainer = Color(0xFF3B0A00),
|
||||
tertiary = Color(0xFF6B5E2F),
|
||||
onTertiary = Color(0xFFFFFFFF),
|
||||
secondary = Color(0xFFAE3200), // Unread badge
|
||||
onSecondary = Color(0xFFFFFFFF), // Unread badge text
|
||||
secondaryContainer = Color(0xFFEBCDC2), // Navigation bar selector pill & progress indicator (remaining)
|
||||
onSecondaryContainer = Color(0xFF3B0A00), // Navigation bar selector icon
|
||||
tertiary = Color(0xFF6B5E2F), // Downloaded badge
|
||||
onTertiary = Color(0xFFFFFFFF), // Downloaded badge text
|
||||
tertiaryContainer = Color(0xFFF5E2A7),
|
||||
onTertiaryContainer = Color(0xFF231B00),
|
||||
background = Color(0xFFFCFCFC),
|
||||
onBackground = Color(0xFF211A18),
|
||||
surface = Color(0xFFFCFCFC),
|
||||
onSurface = Color(0xFF211A18),
|
||||
surfaceVariant = Color(0xFFF5DED8),
|
||||
surfaceVariant = Color(0xFFF6EBE7), // Navigation bar background (ThemePrefWidget)
|
||||
onSurfaceVariant = Color(0xFF53433F),
|
||||
surfaceTint = Color(0xFFAE3200),
|
||||
inverseSurface = Color(0xFF362F2D),
|
||||
inverseOnSurface = Color(0xFFFBEEEB),
|
||||
outline = Color(0xFF85736E),
|
||||
surfaceContainerLowest = Color(0xFFECE3E0),
|
||||
surfaceContainerLow = Color(0xFFF1E7E4),
|
||||
surfaceContainer = Color(0xFFF6EBE7), // Navigation bar background
|
||||
surfaceContainerHigh = Color(0xFFFAF4F2),
|
||||
surfaceContainerHighest = Color(0xFFFBF6F4),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
@@ -58,8 +57,6 @@ import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
private const val UnsetStatusTextAlpha = 0.5F
|
||||
|
||||
@Composable
|
||||
fun TrackInfoDialogHome(
|
||||
trackItems: List<TrackItem>,
|
||||
@@ -72,6 +69,7 @@ fun TrackInfoDialogHome(
|
||||
onNewSearch: (TrackItem) -> Unit,
|
||||
onOpenInBrowser: (TrackItem) -> Unit,
|
||||
onRemoved: (TrackItem) -> Unit,
|
||||
onCopyLink: (TrackItem) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -116,6 +114,7 @@ fun TrackInfoDialogHome(
|
||||
onNewSearch = { onNewSearch(item) },
|
||||
onOpenInBrowser = { onOpenInBrowser(item) },
|
||||
onRemoved = { onRemoved(item) },
|
||||
onCopyLink = { onCopyLink(item) },
|
||||
)
|
||||
} else {
|
||||
TrackInfoItemEmpty(
|
||||
@@ -144,6 +143,7 @@ private fun TrackInfoItem(
|
||||
onNewSearch: () -> Unit,
|
||||
onOpenInBrowser: () -> Unit,
|
||||
onRemoved: () -> Unit,
|
||||
onCopyLink: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Column {
|
||||
@@ -153,6 +153,7 @@ private fun TrackInfoItem(
|
||||
TrackLogoIcon(
|
||||
tracker = tracker,
|
||||
onClick = onOpenInBrowser,
|
||||
onLongClick = onCopyLink,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -179,6 +180,7 @@ private fun TrackInfoItem(
|
||||
TrackInfoItemMenu(
|
||||
onOpenInBrowser = onOpenInBrowser,
|
||||
onRemoved = onRemoved,
|
||||
onCopyLink = onCopyLink,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ private fun TrackInfoItem(
|
||||
modifier = Modifier
|
||||
.padding(top = 12.dp)
|
||||
.clip(MaterialTheme.shapes.medium)
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.background(MaterialTheme.colorScheme.surfaceContainerHighest)
|
||||
.padding(8.dp)
|
||||
.clip(RoundedCornerShape(6.dp)),
|
||||
) {
|
||||
@@ -206,10 +208,9 @@ private fun TrackInfoItem(
|
||||
if (onScoreClick != null) {
|
||||
VerticalDivider()
|
||||
TrackDetailsItem(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.alpha(if (score == null) UnsetStatusTextAlpha else 1f),
|
||||
text = score ?: stringResource(MR.strings.score),
|
||||
modifier = Modifier.weight(1f),
|
||||
text = score,
|
||||
placeholder = stringResource(MR.strings.score),
|
||||
onClick = onScoreClick,
|
||||
)
|
||||
}
|
||||
@@ -238,6 +239,8 @@ private fun TrackInfoItem(
|
||||
}
|
||||
}
|
||||
|
||||
private const val UNSET_TEXT_ALPHA = 0.5F
|
||||
|
||||
@Composable
|
||||
private fun TrackDetailsItem(
|
||||
text: String?,
|
||||
@@ -258,7 +261,7 @@ private fun TrackDetailsItem(
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (text == null) UnsetStatusTextAlpha else 1f),
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = if (text == null) UNSET_TEXT_ALPHA else 1f),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -287,6 +290,7 @@ private fun TrackInfoItemEmpty(
|
||||
private fun TrackInfoItemMenu(
|
||||
onOpenInBrowser: () -> Unit,
|
||||
onRemoved: () -> Unit,
|
||||
onCopyLink: () -> Unit,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
Box(modifier = Modifier.wrapContentSize(Alignment.TopStart)) {
|
||||
@@ -307,6 +311,13 @@ private fun TrackInfoItemMenu(
|
||||
expanded = false
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(MR.strings.action_copy_link)) },
|
||||
onClick = {
|
||||
onCopyLink()
|
||||
expanded = false
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(MR.strings.action_remove)) },
|
||||
onClick = {
|
||||
|
||||
@@ -56,6 +56,7 @@ internal class TrackInfoDialogHomePreviewProvider :
|
||||
onNewSearch = {},
|
||||
onOpenInBrowser = {},
|
||||
onRemoved = {},
|
||||
onCopyLink = {},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -71,6 +72,7 @@ internal class TrackInfoDialogHomePreviewProvider :
|
||||
onNewSearch = {},
|
||||
onOpenInBrowser = {},
|
||||
onRemoved = {},
|
||||
onCopyLink = {},
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@ private fun SearchResultItem(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val clipboardManager: ClipboardManager = LocalClipboardManager.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val type = trackSearch.publishing_type.toLowerCase(Locale.current).capitalize(Locale.current)
|
||||
val status = trackSearch.publishing_status.toLowerCase(Locale.current).capitalize(Locale.current)
|
||||
val description = trackSearch.summary.trim()
|
||||
@@ -243,7 +244,10 @@ private fun SearchResultItem(
|
||||
)
|
||||
.combinedClickable(
|
||||
onLongClick = { dropDownMenuExpanded = true },
|
||||
onClick = onClick,
|
||||
onClick = {
|
||||
focusManager.clearFocus()
|
||||
onClick()
|
||||
},
|
||||
)
|
||||
.padding(12.dp),
|
||||
) {
|
||||
|
||||
@@ -22,9 +22,10 @@ import tachiyomi.presentation.core.util.clickableNoIndication
|
||||
fun TrackLogoIcon(
|
||||
tracker: Tracker,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onLongClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val modifier = if (onClick != null) {
|
||||
Modifier.clickableNoIndication(onClick = onClick)
|
||||
Modifier.clickableNoIndication(onClick = onClick, onLongClick = onLongClick)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
@@ -53,6 +54,7 @@ private fun TrackLogoIconPreviews(
|
||||
TrackLogoIcon(
|
||||
tracker = tracker,
|
||||
onClick = null,
|
||||
onLongClick = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.CalendarMonth
|
||||
import androidx.compose.material.icons.outlined.FlipToBack
|
||||
import androidx.compose.material.icons.outlined.Refresh
|
||||
import androidx.compose.material.icons.outlined.SelectAll
|
||||
@@ -50,6 +51,7 @@ fun UpdateScreen(
|
||||
onClickCover: (UpdatesItem) -> Unit,
|
||||
onSelectAll: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
onCalendarClicked: () -> Unit,
|
||||
onUpdateLibrary: () -> Boolean,
|
||||
onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit,
|
||||
onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit,
|
||||
@@ -63,6 +65,7 @@ fun UpdateScreen(
|
||||
Scaffold(
|
||||
topBar = { scrollBehavior ->
|
||||
UpdatesAppBar(
|
||||
onCalendarClicked = { onCalendarClicked() },
|
||||
onUpdateLibrary = { onUpdateLibrary() },
|
||||
actionModeCounter = state.selected.size,
|
||||
onSelectAll = { onSelectAll(true) },
|
||||
@@ -132,6 +135,7 @@ fun UpdateScreen(
|
||||
|
||||
@Composable
|
||||
private fun UpdatesAppBar(
|
||||
onCalendarClicked: () -> Unit,
|
||||
onUpdateLibrary: () -> Unit,
|
||||
// For action mode
|
||||
actionModeCounter: Int,
|
||||
@@ -147,6 +151,11 @@ private fun UpdatesAppBar(
|
||||
actions = {
|
||||
AppBarActions(
|
||||
persistentListOf(
|
||||
AppBar.Action(
|
||||
title = stringResource(MR.strings.action_view_upcoming),
|
||||
icon = Icons.Outlined.CalendarMonth,
|
||||
onClick = onCalendarClicked,
|
||||
),
|
||||
AppBar.Action(
|
||||
title = stringResource(MR.strings.action_update_library),
|
||||
icon = Icons.Outlined.Refresh,
|
||||
|
||||
@@ -43,7 +43,7 @@ import eu.kanade.tachiyomi.ui.updates.UpdatesItem
|
||||
import tachiyomi.domain.updates.model.UpdatesWithRelations
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.ListGroupHeader
|
||||
import tachiyomi.presentation.core.components.material.ReadItemAlpha
|
||||
import tachiyomi.presentation.core.components.material.DISABLED_ALPHA
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import tachiyomi.presentation.core.util.selectedBackground
|
||||
@@ -107,8 +107,10 @@ internal fun LazyListScope.updatesUiItems(
|
||||
readProgress = updatesItem.update.lastPageRead
|
||||
.takeIf {
|
||||
/* SY --> */(
|
||||
!updatesItem.update.read || (preserveReadingPosition && updatesItem.isEhBasedUpdate())
|
||||
)/* SY <-- */ && it > 0L
|
||||
!updatesItem.update.read ||
|
||||
(preserveReadingPosition && updatesItem.isEhBasedUpdate())
|
||||
)/* SY <-- */ &&
|
||||
it > 0L
|
||||
}
|
||||
?.let {
|
||||
stringResource(
|
||||
@@ -152,7 +154,7 @@ private fun UpdatesUiItem(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val textAlpha = if (update.read) ReadItemAlpha else 1f
|
||||
val textAlpha = if (update.read) DISABLED_ALPHA else 1f
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
@@ -226,7 +228,7 @@ private fun UpdatesUiItem(
|
||||
Text(
|
||||
text = readProgress,
|
||||
maxLines = 1,
|
||||
color = LocalContentColor.current.copy(alpha = ReadItemAlpha),
|
||||
color = LocalContentColor.current.copy(alpha = DISABLED_ALPHA),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package eu.kanade.presentation.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.ContentTransform
|
||||
@@ -28,7 +27,6 @@ import soup.compose.material.motion.animation.rememberSlideDistance
|
||||
/**
|
||||
* For invoking back press to the parent activity
|
||||
*/
|
||||
@SuppressLint("ComposeCompositionLocalUsage")
|
||||
val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositionLocalOf { null }
|
||||
|
||||
interface Tab : cafe.adriel.voyager.navigator.tab.Tab {
|
||||
|
||||
@@ -30,12 +30,12 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.google.accompanist.web.AccompanistWebViewClient
|
||||
import com.google.accompanist.web.LoadingState
|
||||
import com.google.accompanist.web.WebContent
|
||||
import com.google.accompanist.web.WebView
|
||||
import com.google.accompanist.web.rememberWebViewNavigator
|
||||
import com.google.accompanist.web.rememberWebViewState
|
||||
import com.kevinnzou.web.AccompanistWebViewClient
|
||||
import com.kevinnzou.web.LoadingState
|
||||
import com.kevinnzou.web.WebContent
|
||||
import com.kevinnzou.web.WebView
|
||||
import com.kevinnzou.web.rememberWebViewNavigator
|
||||
import com.kevinnzou.web.rememberWebViewState
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
||||
|
||||
@@ -28,11 +28,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.web.AccompanistWebViewClient
|
||||
import com.google.accompanist.web.LoadingState
|
||||
import com.google.accompanist.web.WebView
|
||||
import com.google.accompanist.web.rememberWebViewNavigator
|
||||
import com.google.accompanist.web.rememberWebViewState
|
||||
import com.kevinnzou.web.AccompanistWebViewClient
|
||||
import com.kevinnzou.web.LoadingState
|
||||
import com.kevinnzou.web.WebView
|
||||
import com.kevinnzou.web.rememberWebViewNavigator
|
||||
import com.kevinnzou.web.rememberWebViewState
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
import eu.kanade.presentation.components.AppBarActions
|
||||
import eu.kanade.presentation.components.WarningBanner
|
||||
|
||||
@@ -17,10 +17,6 @@ import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import coil3.ImageLoader
|
||||
import coil3.SingletonImageLoader
|
||||
import coil3.disk.DiskCache
|
||||
import coil3.disk.directory
|
||||
import coil3.gif.AnimatedImageDecoder
|
||||
import coil3.gif.GifDecoder
|
||||
import coil3.network.okhttp.OkHttpNetworkFetcherFactory
|
||||
import coil3.request.allowRgb565
|
||||
import coil3.request.crossfade
|
||||
@@ -42,6 +38,7 @@ import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
|
||||
import eu.kanade.tachiyomi.crash.CrashActivity
|
||||
import eu.kanade.tachiyomi.crash.GlobalExceptionHandler
|
||||
import eu.kanade.tachiyomi.data.coil.BufferedSourceFetcher
|
||||
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher
|
||||
import eu.kanade.tachiyomi.data.coil.MangaCoverKeyer
|
||||
import eu.kanade.tachiyomi.data.coil.MangaKeyer
|
||||
@@ -74,8 +71,12 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import logcat.LogPriority
|
||||
import logcat.LogcatLogger
|
||||
import mihon.core.migration.Migrator
|
||||
import mihon.core.migration.migrations.migrations
|
||||
import org.conscrypt.Conscrypt
|
||||
import tachiyomi.core.common.i18n.stringResource
|
||||
import tachiyomi.core.common.preference.Preference
|
||||
import tachiyomi.core.common.preference.PreferenceStore
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.storage.service.StorageManager
|
||||
import tachiyomi.i18n.MR
|
||||
@@ -173,42 +174,62 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
||||
|
||||
val syncPreferences: SyncPreferences = Injekt.get()
|
||||
val syncTriggerOpt = syncPreferences.getSyncTriggerOptions()
|
||||
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppStart
|
||||
) {
|
||||
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppStart) {
|
||||
SyncDataJob.startNow(this@App)
|
||||
}
|
||||
|
||||
initializeMigrator()
|
||||
}
|
||||
|
||||
private fun initializeMigrator() {
|
||||
val preferenceStore = Injekt.get<PreferenceStore>()
|
||||
// SY -->
|
||||
val preference = preferenceStore.getInt(Preference.appStateKey("eh_last_version_code"), 0)
|
||||
// SY <--
|
||||
logcat { "Migration from ${preference.get()} to ${BuildConfig.VERSION_CODE}" }
|
||||
Migrator.initialize(
|
||||
old = preference.get(),
|
||||
new = BuildConfig.VERSION_CODE,
|
||||
migrations = migrations,
|
||||
onMigrationComplete = {
|
||||
logcat { "Updating last version to ${BuildConfig.VERSION_CODE}" }
|
||||
preference.set(BuildConfig.VERSION_CODE)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun newImageLoader(context: Context): ImageLoader {
|
||||
return ImageLoader.Builder(this).apply {
|
||||
val callFactoryLazy = lazy { Injekt.get<NetworkHelper>().client }
|
||||
val diskCacheLazy = lazy { CoilDiskCache.get(this@App) }
|
||||
components {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
add(AnimatedImageDecoder.Factory())
|
||||
} else {
|
||||
add(GifDecoder.Factory())
|
||||
}
|
||||
// NetworkFetcher.Factory
|
||||
add(OkHttpNetworkFetcherFactory(callFactoryLazy::value))
|
||||
// Decoder.Factory
|
||||
add(TachiyomiImageDecoder.Factory())
|
||||
add(MangaCoverFetcher.MangaFactory(callFactoryLazy, diskCacheLazy))
|
||||
add(MangaCoverFetcher.MangaCoverFactory(callFactoryLazy, diskCacheLazy))
|
||||
add(MangaKeyer())
|
||||
// Fetcher.Factory
|
||||
add(BufferedSourceFetcher.Factory())
|
||||
add(MangaCoverFetcher.MangaCoverFactory(callFactoryLazy))
|
||||
add(MangaCoverFetcher.MangaFactory(callFactoryLazy))
|
||||
// SY -->
|
||||
add(PagePreviewFetcher.Factory(callFactoryLazy))
|
||||
// SY <--
|
||||
// Keyer
|
||||
add(MangaCoverKeyer())
|
||||
add(MangaKeyer())
|
||||
// SY -->
|
||||
add(PagePreviewKeyer())
|
||||
add(PagePreviewFetcher.Factory(callFactoryLazy, diskCacheLazy))
|
||||
// SY <--
|
||||
}
|
||||
diskCache(diskCacheLazy::value)
|
||||
|
||||
crossfade((300 * this@App.animatorDurationScale).toInt())
|
||||
allowRgb565(DeviceUtil.isLowRamDevice(this@App))
|
||||
if (networkPreferences.verboseLogging().get()) logger(DebugLogger())
|
||||
|
||||
// Coil spawns a new thread for every image load by default
|
||||
fetcherDispatcher(Dispatchers.IO.limitedParallelism(8))
|
||||
decoderDispatcher(Dispatchers.IO.limitedParallelism(2))
|
||||
}.build()
|
||||
fetcherCoroutineContext(Dispatchers.IO.limitedParallelism(8))
|
||||
decoderCoroutineContext(Dispatchers.IO.limitedParallelism(3))
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
@@ -216,8 +237,7 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
||||
|
||||
val syncPreferences: SyncPreferences = Injekt.get()
|
||||
val syncTriggerOpt = syncPreferences.getSyncTriggerOptions()
|
||||
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppResume
|
||||
) {
|
||||
if (syncPreferences.isSyncEnabled() && syncTriggerOpt.syncOnAppResume) {
|
||||
SyncDataJob.startNow(this@App)
|
||||
}
|
||||
}
|
||||
@@ -316,7 +336,7 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
||||
"""
|
||||
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}, ${BuildConfig.COMMIT_SHA}, ${BuildConfig.VERSION_CODE})
|
||||
Preview build: $syDebugVersion
|
||||
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
|
||||
Android version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
|
||||
Android build ID: ${Build.DISPLAY}
|
||||
Device brand: ${Build.BRAND}
|
||||
Device manufacturer: ${Build.MANUFACTURER}
|
||||
@@ -356,24 +376,3 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
||||
}
|
||||
|
||||
private const val ACTION_DISABLE_INCOGNITO_MODE = "tachi.action.DISABLE_INCOGNITO_MODE"
|
||||
|
||||
/**
|
||||
* Direct copy of Coil's internal SingletonDiskCache so that [MangaCoverFetcher] can access it.
|
||||
*/
|
||||
private object CoilDiskCache {
|
||||
|
||||
private const val FOLDER_NAME = "image_cache"
|
||||
private var instance: DiskCache? = null
|
||||
|
||||
@Synchronized
|
||||
fun get(context: Context): DiskCache {
|
||||
return instance ?: run {
|
||||
val safeCacheDir = context.cacheDir.apply { mkdirs() }
|
||||
// Create the singleton disk cache instance.
|
||||
DiskCache.Builder()
|
||||
.directory(safeCacheDir.resolve(FOLDER_NAME))
|
||||
.build()
|
||||
.also { instance = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user