mirror of
https://github.com/mihonapp/mihon.git
synced 2025-07-26 09:25:53 +02:00
Compare commits
133 Commits
Author | SHA1 | Date | |
---|---|---|---|
c615f4d458 | |||
9e09a20e65 | |||
7115a9b9fe | |||
fd8b97fc87 | |||
4dd67e4348 | |||
10973bf3cd | |||
934ed0551a | |||
38428c6ebe | |||
bf85e147e7 | |||
d2dd34c2e5 | |||
c4ab2b4675 | |||
aa2ec5940f | |||
79323de326 | |||
08e6487a9a | |||
4498b10a10 | |||
6f2bb18d72 | |||
b690de55e5 | |||
83fda20078 | |||
f656a37045 | |||
c58b495433 | |||
242aeb6a68 | |||
d9969cea8a | |||
d61db5931e | |||
0ea3ac9807 | |||
f9e43f574f | |||
5ef11e61d0 | |||
48546c3db4 | |||
4d87ed496c | |||
06d12e6562 | |||
477e3d9b94 | |||
3c16082636 | |||
29aee68ec7 | |||
75e23299b4 | |||
935ff1ee98 | |||
c672cb81ec | |||
7559c133c0 | |||
589bdba0b1 | |||
aca65f13bb | |||
7bf30a094a | |||
5454279a8e | |||
006bcdf934 | |||
b00f00730d | |||
f2c48480b6 | |||
1730dd6af1 | |||
2501fef9e4 | |||
12e41b6e6f | |||
c892c793a8 | |||
3a82b4d924 | |||
b4b3a4d286 | |||
448702e5be | |||
2ef1f07aae | |||
1a319601de | |||
cdf242e8c8 | |||
aee785a8bb | |||
d45fc1e245 | |||
14500ba4f8 | |||
345e9c2a9a | |||
b53e24e0db | |||
d3a73fc228 | |||
c2812fca24 | |||
856847a60a | |||
748e2480d3 | |||
2ebc8d9ae5 | |||
e28b015580 | |||
e4bc8990fb | |||
a179327d9d | |||
823749fc1e | |||
2b5d9fd76b | |||
7a972dfdb7 | |||
c31e75f02f | |||
b56b8b55b4 | |||
2695a4d8c7 | |||
1a4dad72a9 | |||
b7e6b4c28a | |||
dc2d470413 | |||
293b967858 | |||
c637172ee0 | |||
e468554fd9 | |||
5b5eb92184 | |||
58ebf14691 | |||
992bab4f79 | |||
6fe650319d | |||
f301dc64f0 | |||
33a2219716 | |||
62480f090b | |||
e7937fe562 | |||
287489d7d0 | |||
2df0236669 | |||
c54d77333f | |||
8c494f314c | |||
8cea78de83 | |||
b6468c7e31 | |||
1967923a94 | |||
91004ad514 | |||
a2ee4e63ae | |||
4d8289cd36 | |||
289264878e | |||
768bb7b503 | |||
db4ae134aa | |||
7329f03bc5 | |||
82ea643c7d | |||
741c10e0b9 | |||
34bb90f3c2 | |||
f04cf72c0c | |||
157438e0c1 | |||
75b23c99ec | |||
6bb3070c57 | |||
7df10b076c | |||
2245658363 | |||
46774771ec | |||
6263817bb4 | |||
60456fe0e9 | |||
a0f47d3f1b | |||
6efcb8ccfa | |||
0d128b75e2 | |||
0067d474c8 | |||
cf393b217b | |||
e265b929a1 | |||
4cd01428ed | |||
3be05fbf9b | |||
5d90ba8aa0 | |||
48cab708ce | |||
5d9753d6a7 | |||
425e48bec6 | |||
a42be4a833 | |||
30e030bb8e | |||
2a3c3d8d6a | |||
7b026cec8d | |||
d8b528a4e0 | |||
0f45907144 | |||
c4c9931ae2 | |||
68345e636e | |||
0861c5618c |
.github
app
build.gradle.kts
build.gradle.ktssrc
main
AndroidManifest.xml
java
eu
kanade
core
data
domain
DomainModule.kt
backup
service
base
category
interactor
chapter
interactor
GetChapter.ktGetChapterByMangaId.ktSetDefaultChapterSettings.ktSetReadStatus.ktSyncChaptersWithSource.ktSyncChaptersWithTrackServiceTwoWay.ktUpdateChapter.kt
model
download
history
interactor
library
service
manga
interactor
GetDuplicateLibraryManga.ktGetFavorites.ktGetLibraryManga.ktGetManga.ktGetMangaWithChapters.ktNetworkToLocalManga.ktResetViewerFlags.ktSetMangaChapterFlags.ktSetMangaViewerFlags.ktUpdateManga.kt
model
source
interactor
GetEnabledSources.ktGetLanguagesWithSources.ktGetSourcesWithFavoriteCount.ktGetSourcesWithNonLibraryManga.ktToggleLanguage.ktToggleSource.ktToggleSourcePin.kt
model
repository
service
track
interactor
model
service
store
ui
presentation
browse
BrowseSourceScreen.ktExtensionsScreen.ktGlobalSearchScreen.ktMigrateMangaScreen.ktMigrateSearchScreen.ktMigrateSourceScreen.ktSourcesFilterScreen.ktSourcesScreen.kt
components
category
components
AppBar.ktChangeCategoryDialog.ktCommonMangaItem.ktDeleteLibraryMangaDialog.ktDuplicateMangaDialog.ktEmptyScreen.ktNavigationRail.ktScaffold.ktSettingsItems.kt
history
library
components
manga
more
MoreScreen.ktNewUpdateScreen.kt
settings
updates
util
webview
tachiyomi
App.ktAppModule.ktMigrations.kt
crash
data
backup
BackupCreatorJob.ktBackupFileValidator.ktBackupManager.ktBackupRestoreService.ktBackupRestorer.kt
models
cache
coil
database
models
download
DownloadCache.ktDownloadManager.ktDownloadPendingDeleter.ktDownloadProvider.ktDownloadService.ktDownloadStore.ktDownloader.kt
model
library
notification
saver
track
EnhancedTrackService.ktNoLoginTrackService.ktTrackManager.ktTrackService.kt
anilist
bangumi
kavita
kitsu
komga
mangaupdates
myanimelist
shikimori
suwayomi
updater
extension
glance
source
ui
browse
BrowseTab.kt
extension
migration
source
category
download
history
library
main
manga
more
reader
ReaderActivity.ktReaderViewModel.kt
loader
ChapterLoader.ktDirectoryPageLoader.ktDownloadPageLoader.ktEpubPageLoader.ktHttpPageLoader.ktPageLoader.ktRarPageLoader.ktZipPageLoader.kt
model
setting
viewer
security
setting
track
stats
updates
webview
util
widget
res
drawable-nodpi
drawable
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
values
buildSrc
core
data
.gitignorebuild.gradle.ktsconsumer-rules.proproguard-rules.pro
src
main
AndroidManifest.xml
java
tachiyomi
data
AndroidDatabaseHandler.ktDatabaseAdapter.ktDatabaseHandler.ktQueryPagingSource.ktTransactionContext.kt
category
chapter
history
manga
source
track
updates
sqldelight
domain
.gitignorebuild.gradle.ktsconsumer-rules.proproguard-rules.pro
src
main
AndroidManifest.xml
java
tachiyomi
domain
category
chapter
interactor
model
repository
history
interactor
model
repository
library
manga
source
track
updates
test
java
tachiyomi
domain
library
model
gradle
i18n
build.gradle.kts
src
main
res
values-am
values-ar
values-b+es+419
values-be
values-bg
values-bn
values-ca
values-ceb
values-cs
values-cv
values-da
values-de
values-el
values-eo
values-es
values-eu
values-fa
values-fi
values-fil
values-fr
values-gl
values-he
values-hi
values-hr
values-hu
values-in
values-it
values-ja
values-jv
values-ka-rGE
values-kk
values-km
values-kn
values-ko
values-lt
values-lv
values-mr
values-ms
values-my
values-nb-rNO
values-ne
values-nl
values-pl
values-pt-rBR
values-pt
values-ro
values-ru
values-sa
values-sah
values-sc
values-sdh
values-sk
values-sq
values-sr
values-sv
values-te
values-th
values-tr
values-uk
values-uz
values-vi
values-zh-rCN
values-zh-rTW
values
macrobenchmark
presentation-core
presentation-widget
.gitignorebuild.gradle.ktsconsumer-rules.proproguard-rules.pro
settings.gradle.ktssrc
main
source-api
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -3,7 +3,7 @@
|
|||||||
I acknowledge that:
|
I acknowledge that:
|
||||||
|
|
||||||
- I have updated:
|
- I have updated:
|
||||||
- To the latest version of the app (stable is v0.14.3)
|
- To the latest version of the app (stable is v0.14.6)
|
||||||
- All extensions
|
- All extensions
|
||||||
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
|
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
|
||||||
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
|
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions
|
||||||
|
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
4
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
@ -53,7 +53,7 @@ body:
|
|||||||
label: Tachiyomi version
|
label: Tachiyomi version
|
||||||
description: You can find your Tachiyomi version in **More → About**.
|
description: You can find your Tachiyomi version in **More → About**.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Example: "0.14.3"
|
Example: "0.14.6"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
|
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated the app to version **[0.14.3](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
- label: I have updated the app to version **[0.14.6](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated all installed extensions.
|
- label: I have updated all installed extensions.
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
2
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
@ -33,7 +33,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
|
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
|
||||||
required: true
|
required: true
|
||||||
- label: I have updated the app to version **[0.14.3](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
- label: I have updated the app to version **[0.14.6](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
|
||||||
required: true
|
required: true
|
||||||
- label: I will fill out all of the requested information in this form.
|
- label: I will fill out all of the requested information in this form.
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/workflows/build_pull_request.yml
vendored
2
.github/workflows/build_pull_request.yml
vendored
@ -36,4 +36,4 @@ jobs:
|
|||||||
- name: Build app and run unit tests
|
- name: Build app and run unit tests
|
||||||
uses: gradle/gradle-command-action@v2
|
uses: gradle/gradle-command-action@v2
|
||||||
with:
|
with:
|
||||||
arguments: assembleStandardRelease testStandardReleaseUnitTest
|
arguments: lintKotlin assembleStandardRelease testStandardReleaseUnitTest
|
2
.github/workflows/build_push.yml
vendored
2
.github/workflows/build_push.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
- name: Build app and run unit tests
|
- name: Build app and run unit tests
|
||||||
uses: gradle/gradle-command-action@v2
|
uses: gradle/gradle-command-action@v2
|
||||||
with:
|
with:
|
||||||
arguments: assembleStandardRelease testStandardReleaseUnitTest
|
arguments: lintKotlin assembleStandardRelease testStandardReleaseUnitTest
|
||||||
|
|
||||||
# Sign APK and create release for tags
|
# Sign APK and create release for tags
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.jmailen.gradle.kotlinter.tasks.LintTask
|
import org.jmailen.gradle.kotlinter.tasks.LintTask
|
||||||
|
|
||||||
@ -8,7 +7,6 @@ plugins {
|
|||||||
kotlin("android")
|
kotlin("android")
|
||||||
kotlin("plugin.serialization")
|
kotlin("plugin.serialization")
|
||||||
id("com.github.zellius.shortcut-helper")
|
id("com.github.zellius.shortcut-helper")
|
||||||
id("com.squareup.sqldelight")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
|
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
|
||||||
@ -21,15 +19,11 @@ val SUPPORTED_ABIS = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "eu.kanade.tachiyomi"
|
namespace = "eu.kanade.tachiyomi"
|
||||||
compileSdk = AndroidConfig.compileSdk
|
|
||||||
ndkVersion = AndroidConfig.ndk
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "eu.kanade.tachiyomi"
|
applicationId = "eu.kanade.tachiyomi"
|
||||||
minSdk = AndroidConfig.minSdk
|
versionCode = 101
|
||||||
targetSdk = AndroidConfig.targetSdk
|
versionName = "0.14.6"
|
||||||
versionCode = 93
|
|
||||||
versionName = "0.14.3"
|
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
|
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
|
||||||
@ -141,32 +135,16 @@ android {
|
|||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
|
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
|
|
||||||
isCoreLibraryDesugaringEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
sqldelight {
|
|
||||||
database("Database") {
|
|
||||||
packageName = "eu.kanade.tachiyomi"
|
|
||||||
dialect = "sqlite:3.24"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":i18n"))
|
implementation(project(":i18n"))
|
||||||
implementation(project(":core"))
|
implementation(project(":core"))
|
||||||
implementation(project(":source-api"))
|
implementation(project(":source-api"))
|
||||||
|
implementation(project(":data"))
|
||||||
coreLibraryDesugaring(libs.desugar)
|
implementation(project(":domain"))
|
||||||
|
implementation(project(":presentation-core"))
|
||||||
|
implementation(project(":presentation-widget"))
|
||||||
|
|
||||||
// Compose
|
// Compose
|
||||||
implementation(platform(compose.bom))
|
implementation(platform(compose.bom))
|
||||||
@ -189,9 +167,6 @@ dependencies {
|
|||||||
implementation(androidx.paging.compose)
|
implementation(androidx.paging.compose)
|
||||||
|
|
||||||
implementation(libs.bundles.sqlite)
|
implementation(libs.bundles.sqlite)
|
||||||
implementation(libs.sqldelight.android.driver)
|
|
||||||
implementation(libs.sqldelight.coroutines)
|
|
||||||
implementation(libs.sqldelight.android.paging)
|
|
||||||
|
|
||||||
implementation(kotlinx.reflect)
|
implementation(kotlinx.reflect)
|
||||||
|
|
||||||
@ -208,7 +183,6 @@ dependencies {
|
|||||||
implementation(androidx.splashscreen)
|
implementation(androidx.splashscreen)
|
||||||
implementation(androidx.recyclerview)
|
implementation(androidx.recyclerview)
|
||||||
implementation(androidx.viewpager)
|
implementation(androidx.viewpager)
|
||||||
implementation(androidx.glance)
|
|
||||||
implementation(androidx.profileinstaller)
|
implementation(androidx.profileinstaller)
|
||||||
|
|
||||||
implementation(androidx.bundles.lifecycle)
|
implementation(androidx.bundles.lifecycle)
|
||||||
@ -303,12 +277,6 @@ androidComponents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
withType<Test> {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
withType<LintTask>().configureEach {
|
withType<LintTask>().configureEach {
|
||||||
exclude { it.file.path.contains("generated[\\\\/]".toRegex()) }
|
exclude { it.file.path.contains("generated[\\\\/]".toRegex()) }
|
||||||
@ -346,11 +314,6 @@ tasks {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preBuild {
|
|
||||||
val ktlintTask = if (System.getenv("GITHUB_BASE_REF") == null) formatKotlin else lintKotlin
|
|
||||||
dependsOn(ktlintTask)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
@ -188,7 +188,7 @@
|
|||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".glance.UpdatesGridGlanceReceiver"
|
android:name="tachiyomi.presentation.widget.UpdatesGridGlanceReceiver"
|
||||||
android:enabled="@bool/glance_appwidget_available"
|
android:enabled="@bool/glance_appwidget_available"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:label="@string/label_recent_updates">
|
android:label="@string/label_recent_updates">
|
||||||
|
@ -2,10 +2,10 @@ package eu.kanade.core.prefs
|
|||||||
|
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import eu.kanade.tachiyomi.core.preference.Preference
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import tachiyomi.core.preference.Preference
|
||||||
|
|
||||||
class PreferenceMutableState<T>(
|
class PreferenceMutableState<T>(
|
||||||
private val preference: Preference<T>,
|
private val preference: Preference<T>,
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
package eu.kanade.data.source
|
|
||||||
|
|
||||||
class NoResultsException : Exception()
|
|
@ -1,9 +1,8 @@
|
|||||||
package eu.kanade.data.source
|
package eu.kanade.data.source
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.model.SourceData
|
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
val sourceMapper: (eu.kanade.tachiyomi.source.Source) -> Source = { source ->
|
val sourceMapper: (eu.kanade.tachiyomi.source.Source) -> Source = { source ->
|
||||||
Source(
|
Source(
|
||||||
@ -18,7 +17,3 @@ val sourceMapper: (eu.kanade.tachiyomi.source.Source) -> Source = { source ->
|
|||||||
val catalogueSourceMapper: (CatalogueSource) -> Source = { source ->
|
val catalogueSourceMapper: (CatalogueSource) -> Source = { source ->
|
||||||
sourceMapper(source).copy(supportsLatest = source.supportsLatest)
|
sourceMapper(source).copy(supportsLatest = source.supportsLatest)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sourceDataMapper: (Long, String, String) -> SourceData = { id, lang, name ->
|
|
||||||
SourceData(id, lang, name)
|
|
||||||
}
|
|
||||||
|
@ -6,8 +6,8 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.lang.awaitSingle
|
import tachiyomi.core.util.lang.awaitSingle
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import tachiyomi.core.util.lang.withIOContext
|
||||||
|
|
||||||
abstract class SourcePagingSource(
|
abstract class SourcePagingSource(
|
||||||
protected val source: CatalogueSource,
|
protected val source: CatalogueSource,
|
||||||
@ -60,3 +60,5 @@ class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(sou
|
|||||||
return source.fetchLatestUpdates(currentPage).awaitSingle()
|
return source.fetchLatestUpdates(currentPage).awaitSingle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoResultsException : Exception()
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package eu.kanade.data.source
|
package eu.kanade.data.source
|
||||||
|
|
||||||
import eu.kanade.data.DatabaseHandler
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.model.SourcePagingSourceType
|
import eu.kanade.domain.source.model.SourcePagingSourceType
|
||||||
import eu.kanade.domain.source.model.SourceWithCount
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
@ -11,6 +8,9 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import tachiyomi.data.DatabaseHandler
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
import tachiyomi.domain.source.model.SourceWithCount
|
||||||
|
|
||||||
class SourceRepositoryImpl(
|
class SourceRepositoryImpl(
|
||||||
private val sourceManager: SourceManager,
|
private val sourceManager: SourceManager,
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
package eu.kanade.domain
|
package eu.kanade.domain
|
||||||
|
|
||||||
import eu.kanade.data.category.CategoryRepositoryImpl
|
|
||||||
import eu.kanade.data.chapter.ChapterRepositoryImpl
|
|
||||||
import eu.kanade.data.history.HistoryRepositoryImpl
|
|
||||||
import eu.kanade.data.manga.MangaRepositoryImpl
|
|
||||||
import eu.kanade.data.source.SourceDataRepositoryImpl
|
|
||||||
import eu.kanade.data.source.SourceRepositoryImpl
|
import eu.kanade.data.source.SourceRepositoryImpl
|
||||||
import eu.kanade.data.track.TrackRepositoryImpl
|
|
||||||
import eu.kanade.data.updates.UpdatesRepositoryImpl
|
|
||||||
import eu.kanade.domain.category.interactor.CreateCategoryWithName
|
import eu.kanade.domain.category.interactor.CreateCategoryWithName
|
||||||
import eu.kanade.domain.category.interactor.DeleteCategory
|
import eu.kanade.domain.category.interactor.DeleteCategory
|
||||||
import eu.kanade.domain.category.interactor.GetCategories
|
|
||||||
import eu.kanade.domain.category.interactor.RenameCategory
|
import eu.kanade.domain.category.interactor.RenameCategory
|
||||||
import eu.kanade.domain.category.interactor.ReorderCategory
|
import eu.kanade.domain.category.interactor.ReorderCategory
|
||||||
import eu.kanade.domain.category.interactor.ResetCategoryFlags
|
import eu.kanade.domain.category.interactor.ResetCategoryFlags
|
||||||
@ -18,26 +10,18 @@ import eu.kanade.domain.category.interactor.SetDisplayModeForCategory
|
|||||||
import eu.kanade.domain.category.interactor.SetMangaCategories
|
import eu.kanade.domain.category.interactor.SetMangaCategories
|
||||||
import eu.kanade.domain.category.interactor.SetSortModeForCategory
|
import eu.kanade.domain.category.interactor.SetSortModeForCategory
|
||||||
import eu.kanade.domain.category.interactor.UpdateCategory
|
import eu.kanade.domain.category.interactor.UpdateCategory
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapter
|
import eu.kanade.domain.chapter.interactor.GetChapter
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.interactor.SetMangaDefaultChapterFlags
|
import eu.kanade.domain.chapter.interactor.SetMangaDefaultChapterFlags
|
||||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||||
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
|
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.domain.download.interactor.DeleteDownload
|
import eu.kanade.domain.download.interactor.DeleteDownload
|
||||||
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
|
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
|
||||||
import eu.kanade.domain.extension.interactor.GetExtensionSources
|
import eu.kanade.domain.extension.interactor.GetExtensionSources
|
||||||
import eu.kanade.domain.extension.interactor.GetExtensionsByType
|
import eu.kanade.domain.extension.interactor.GetExtensionsByType
|
||||||
import eu.kanade.domain.history.interactor.GetHistory
|
|
||||||
import eu.kanade.domain.history.interactor.GetNextChapters
|
import eu.kanade.domain.history.interactor.GetNextChapters
|
||||||
import eu.kanade.domain.history.interactor.GetTotalReadDuration
|
|
||||||
import eu.kanade.domain.history.interactor.RemoveHistory
|
|
||||||
import eu.kanade.domain.history.interactor.UpsertHistory
|
|
||||||
import eu.kanade.domain.history.repository.HistoryRepository
|
|
||||||
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import eu.kanade.domain.manga.interactor.GetFavorites
|
import eu.kanade.domain.manga.interactor.GetFavorites
|
||||||
import eu.kanade.domain.manga.interactor.GetLibraryManga
|
import eu.kanade.domain.manga.interactor.GetLibraryManga
|
||||||
@ -48,7 +32,6 @@ import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
|||||||
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
||||||
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.domain.source.interactor.GetEnabledSources
|
import eu.kanade.domain.source.interactor.GetEnabledSources
|
||||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
|
||||||
import eu.kanade.domain.source.interactor.GetRemoteManga
|
import eu.kanade.domain.source.interactor.GetRemoteManga
|
||||||
@ -58,15 +41,32 @@ import eu.kanade.domain.source.interactor.SetMigrateSorting
|
|||||||
import eu.kanade.domain.source.interactor.ToggleLanguage
|
import eu.kanade.domain.source.interactor.ToggleLanguage
|
||||||
import eu.kanade.domain.source.interactor.ToggleSource
|
import eu.kanade.domain.source.interactor.ToggleSource
|
||||||
import eu.kanade.domain.source.interactor.ToggleSourcePin
|
import eu.kanade.domain.source.interactor.ToggleSourcePin
|
||||||
import eu.kanade.domain.source.repository.SourceDataRepository
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import eu.kanade.domain.track.interactor.DeleteTrack
|
import eu.kanade.domain.track.interactor.DeleteTrack
|
||||||
import eu.kanade.domain.track.interactor.GetTracks
|
import eu.kanade.domain.track.interactor.GetTracks
|
||||||
import eu.kanade.domain.track.interactor.GetTracksPerManga
|
import eu.kanade.domain.track.interactor.GetTracksPerManga
|
||||||
import eu.kanade.domain.track.interactor.InsertTrack
|
import eu.kanade.domain.track.interactor.InsertTrack
|
||||||
import eu.kanade.domain.track.repository.TrackRepository
|
import tachiyomi.data.category.CategoryRepositoryImpl
|
||||||
import eu.kanade.domain.updates.interactor.GetUpdates
|
import tachiyomi.data.chapter.ChapterRepositoryImpl
|
||||||
import eu.kanade.domain.updates.repository.UpdatesRepository
|
import tachiyomi.data.history.HistoryRepositoryImpl
|
||||||
|
import tachiyomi.data.manga.MangaRepositoryImpl
|
||||||
|
import tachiyomi.data.source.SourceDataRepositoryImpl
|
||||||
|
import tachiyomi.data.track.TrackRepositoryImpl
|
||||||
|
import tachiyomi.data.updates.UpdatesRepositoryImpl
|
||||||
|
import tachiyomi.domain.category.interactor.GetCategories
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
import tachiyomi.domain.chapter.interactor.ShouldUpdateDbChapter
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
import tachiyomi.domain.history.interactor.GetHistory
|
||||||
|
import tachiyomi.domain.history.interactor.GetTotalReadDuration
|
||||||
|
import tachiyomi.domain.history.interactor.RemoveHistory
|
||||||
|
import tachiyomi.domain.history.interactor.UpsertHistory
|
||||||
|
import tachiyomi.domain.history.repository.HistoryRepository
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
import tachiyomi.domain.source.repository.SourceDataRepository
|
||||||
|
import tachiyomi.domain.track.repository.TrackRepository
|
||||||
|
import tachiyomi.domain.updates.interactor.GetUpdates
|
||||||
|
import tachiyomi.domain.updates.repository.UpdatesRepository
|
||||||
import uy.kohesive.injekt.api.InjektModule
|
import uy.kohesive.injekt.api.InjektModule
|
||||||
import uy.kohesive.injekt.api.InjektRegistrar
|
import uy.kohesive.injekt.api.InjektRegistrar
|
||||||
import uy.kohesive.injekt.api.addFactory
|
import uy.kohesive.injekt.api.addFactory
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.domain.backup.service
|
package eu.kanade.domain.backup.service
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
import eu.kanade.tachiyomi.core.provider.FolderProvider
|
import tachiyomi.core.provider.FolderProvider
|
||||||
|
|
||||||
class BackupPreferences(
|
class BackupPreferences(
|
||||||
private val folderProvider: FolderProvider,
|
private val folderProvider: FolderProvider,
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package eu.kanade.domain.base
|
package eu.kanade.domain.base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
|
||||||
import eu.kanade.tachiyomi.core.preference.getEnum
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues
|
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
|
||||||
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
||||||
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
|
import eu.kanade.tachiyomi.util.system.isReleaseBuildType
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
|
||||||
class BasePreferences(
|
class BasePreferences(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
@ -21,10 +18,7 @@ class BasePreferences(
|
|||||||
|
|
||||||
fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
|
fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
|
||||||
|
|
||||||
fun extensionInstaller() = preferenceStore.getEnum(
|
fun extensionInstaller() = ExtensionInstallerPreference(context, preferenceStore)
|
||||||
"extension_installer",
|
|
||||||
if (DeviceUtil.isMiui) PreferenceValues.ExtensionInstaller.LEGACY else PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
|
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", isPreviewBuildType || isReleaseBuildType)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package eu.kanade.domain.base
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferenceValues.ExtensionInstaller
|
||||||
|
import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
|
||||||
|
import eu.kanade.tachiyomi.util.system.isShizukuInstalled
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import tachiyomi.core.preference.Preference
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
import tachiyomi.core.preference.getEnum
|
||||||
|
|
||||||
|
class ExtensionInstallerPreference(
|
||||||
|
private val context: Context,
|
||||||
|
preferenceStore: PreferenceStore,
|
||||||
|
) : Preference<ExtensionInstaller> {
|
||||||
|
|
||||||
|
private val basePref = preferenceStore.getEnum(key(), defaultValue())
|
||||||
|
|
||||||
|
override fun key() = "extension_installer"
|
||||||
|
|
||||||
|
val entries get() = ExtensionInstaller.values().run {
|
||||||
|
if (context.hasMiuiPackageInstaller) {
|
||||||
|
filter { it != ExtensionInstaller.PACKAGEINSTALLER }
|
||||||
|
} else {
|
||||||
|
toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun defaultValue() = if (context.hasMiuiPackageInstaller) {
|
||||||
|
ExtensionInstaller.LEGACY
|
||||||
|
} else {
|
||||||
|
ExtensionInstaller.PACKAGEINSTALLER
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun check(value: ExtensionInstaller): ExtensionInstaller {
|
||||||
|
when (value) {
|
||||||
|
ExtensionInstaller.PACKAGEINSTALLER -> {
|
||||||
|
if (context.hasMiuiPackageInstaller) return ExtensionInstaller.LEGACY
|
||||||
|
}
|
||||||
|
ExtensionInstaller.SHIZUKU -> {
|
||||||
|
if (!context.isShizukuInstalled) return defaultValue()
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(): ExtensionInstaller {
|
||||||
|
val value = basePref.get()
|
||||||
|
val checkedValue = check(value)
|
||||||
|
if (value != checkedValue) {
|
||||||
|
basePref.set(checkedValue)
|
||||||
|
}
|
||||||
|
return checkedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(value: ExtensionInstaller) {
|
||||||
|
basePref.set(check(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSet() = basePref.isSet()
|
||||||
|
|
||||||
|
override fun delete() = basePref.delete()
|
||||||
|
|
||||||
|
override fun changes() = basePref.changes()
|
||||||
|
|
||||||
|
override fun stateIn(scope: CoroutineScope) = basePref.stateIn(scope)
|
||||||
|
}
|
@ -1,12 +1,11 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.domain.category.model.anyWithName
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
|
||||||
class CreateCategoryWithName(
|
class CreateCategoryWithName(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
@ -23,10 +22,6 @@ class CreateCategoryWithName(
|
|||||||
|
|
||||||
suspend fun await(name: String): Result = withNonCancellableContext {
|
suspend fun await(name: String): Result = withNonCancellableContext {
|
||||||
val categories = categoryRepository.getAll()
|
val categories = categoryRepository.getAll()
|
||||||
if (categories.anyWithName(name)) {
|
|
||||||
return@withNonCancellableContext Result.NameAlreadyExistsError
|
|
||||||
}
|
|
||||||
|
|
||||||
val nextOrder = categories.maxOfOrNull { it.order }?.plus(1) ?: 0
|
val nextOrder = categories.maxOfOrNull { it.order }?.plus(1) ?: 0
|
||||||
val newCategory = Category(
|
val newCategory = Category(
|
||||||
id = 0,
|
id = 0,
|
||||||
@ -46,7 +41,6 @@ class CreateCategoryWithName(
|
|||||||
|
|
||||||
sealed class Result {
|
sealed class Result {
|
||||||
object Success : Result()
|
object Success : Result()
|
||||||
object NameAlreadyExistsError : Result()
|
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
|
||||||
class DeleteCategory(
|
class DeleteCategory(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
|
||||||
import eu.kanade.domain.category.model.anyWithName
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
|
||||||
class RenameCategory(
|
class RenameCategory(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(categoryId: Long, name: String) = withNonCancellableContext {
|
suspend fun await(categoryId: Long, name: String) = withNonCancellableContext {
|
||||||
val categories = categoryRepository.getAll()
|
|
||||||
if (categories.anyWithName(name)) {
|
|
||||||
return@withNonCancellableContext Result.NameAlreadyExistsError
|
|
||||||
}
|
|
||||||
|
|
||||||
val update = CategoryUpdate(
|
val update = CategoryUpdate(
|
||||||
id = categoryId,
|
id = categoryId,
|
||||||
name = name,
|
name = name,
|
||||||
@ -36,7 +30,6 @@ class RenameCategory(
|
|||||||
|
|
||||||
sealed class Result {
|
sealed class Result {
|
||||||
object Success : Result()
|
object Success : Result()
|
||||||
object NameAlreadyExistsError : Result()
|
|
||||||
data class InternalError(val error: Throwable) : Result()
|
data class InternalError(val error: Throwable) : Result()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
|
||||||
class ReorderCategory(
|
class ReorderCategory(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.domain.library.model.plus
|
|
||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
import tachiyomi.domain.library.model.plus
|
||||||
|
|
||||||
class ResetCategoryFlags(
|
class ResetCategoryFlags(
|
||||||
private val preferences: LibraryPreferences,
|
private val preferences: LibraryPreferences,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
|
||||||
import eu.kanade.domain.library.model.plus
|
|
||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
import tachiyomi.domain.library.model.plus
|
||||||
|
|
||||||
class SetDisplayModeForCategory(
|
class SetDisplayModeForCategory(
|
||||||
private val preferences: LibraryPreferences,
|
private val preferences: LibraryPreferences,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class SetMangaCategories(
|
class SetMangaCategories(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
|
||||||
import eu.kanade.domain.library.model.LibrarySort
|
|
||||||
import eu.kanade.domain.library.model.plus
|
|
||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
import tachiyomi.domain.library.model.LibrarySort
|
||||||
|
import tachiyomi.domain.library.model.plus
|
||||||
|
|
||||||
class SetSortModeForCategory(
|
class SetSortModeForCategory(
|
||||||
private val preferences: LibraryPreferences,
|
private val preferences: LibraryPreferences,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.category.interactor
|
package eu.kanade.domain.category.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.category.model.CategoryUpdate
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
import tachiyomi.domain.category.model.CategoryUpdate
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
import tachiyomi.domain.category.repository.CategoryRepository
|
||||||
|
|
||||||
class UpdateCategory(
|
class UpdateCategory(
|
||||||
private val categoryRepository: CategoryRepository,
|
private val categoryRepository: CategoryRepository,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
|
||||||
class GetChapter(
|
class GetChapter(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
|
||||||
class GetChapterByMangaId(
|
class GetChapterByMangaId(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
|
@ -3,8 +3,8 @@ package eu.kanade.domain.chapter.interactor
|
|||||||
import eu.kanade.domain.library.service.LibraryPreferences
|
import eu.kanade.domain.library.service.LibraryPreferences
|
||||||
import eu.kanade.domain.manga.interactor.GetFavorites
|
import eu.kanade.domain.manga.interactor.GetFavorites
|
||||||
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
class SetMangaDefaultChapterFlags(
|
class SetMangaDefaultChapterFlags(
|
||||||
private val libraryPreferences: LibraryPreferences,
|
private val libraryPreferences: LibraryPreferences,
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.domain.download.interactor.DeleteDownload
|
import eu.kanade.domain.download.interactor.DeleteDownload
|
||||||
import eu.kanade.domain.download.service.DownloadPreferences
|
import eu.kanade.domain.download.service.DownloadPreferences
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.model.ChapterUpdate
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class SetReadStatus(
|
class SetReadStatus(
|
||||||
private val downloadPreferences: DownloadPreferences,
|
private val downloadPreferences: DownloadPreferences,
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.data.chapter.CleanupChapterName
|
import eu.kanade.domain.chapter.model.copyFromSChapter
|
||||||
import eu.kanade.data.chapter.NoChaptersException
|
import eu.kanade.domain.chapter.model.toSChapter
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.model.toChapterUpdate
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import eu.kanade.domain.manga.model.toSManga
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
@ -14,6 +11,13 @@ import eu.kanade.tachiyomi.source.isLocal
|
|||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.util.chapter.ChapterRecognition
|
import eu.kanade.tachiyomi.util.chapter.ChapterRecognition
|
||||||
|
import tachiyomi.data.chapter.ChapterSanitizer
|
||||||
|
import tachiyomi.domain.chapter.interactor.ShouldUpdateDbChapter
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.model.NoChaptersException
|
||||||
|
import tachiyomi.domain.chapter.model.toChapterUpdate
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.lang.Long.max
|
import java.lang.Long.max
|
||||||
@ -52,7 +56,7 @@ class SyncChaptersWithSource(
|
|||||||
.mapIndexed { i, sChapter ->
|
.mapIndexed { i, sChapter ->
|
||||||
Chapter.create()
|
Chapter.create()
|
||||||
.copyFromSChapter(sChapter)
|
.copyFromSChapter(sChapter)
|
||||||
.copy(name = CleanupChapterName.await(sChapter.name, manga.title))
|
.copy(name = with(ChapterSanitizer) { sChapter.name.sanitize(manga.title) })
|
||||||
.copy(mangaId = manga.id, sourceOrder = i.toLong())
|
.copy(mangaId = manga.id, sourceOrder = i.toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.model.toChapterUpdate
|
|
||||||
import eu.kanade.domain.track.interactor.InsertTrack
|
import eu.kanade.domain.track.interactor.InsertTrack
|
||||||
import eu.kanade.domain.track.model.Track
|
|
||||||
import eu.kanade.domain.track.model.toDbTrack
|
import eu.kanade.domain.track.model.toDbTrack
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.model.toChapterUpdate
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.domain.chapter.interactor
|
package eu.kanade.domain.chapter.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.chapter.model.ChapterUpdate
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
|
||||||
class UpdateChapter(
|
class UpdateChapter(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
|
@ -2,64 +2,30 @@ package eu.kanade.domain.chapter.model
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter as DbChapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter as DbChapter
|
||||||
|
|
||||||
data class Chapter(
|
// TODO: Remove when all deps are migrated
|
||||||
val id: Long,
|
fun Chapter.toSChapter(): SChapter {
|
||||||
val mangaId: Long,
|
return SChapter.create().also {
|
||||||
val read: Boolean,
|
it.url = url
|
||||||
val bookmark: Boolean,
|
it.name = name
|
||||||
val lastPageRead: Long,
|
it.date_upload = dateUpload
|
||||||
val dateFetch: Long,
|
it.chapter_number = chapterNumber
|
||||||
val sourceOrder: Long,
|
it.scanlator = scanlator
|
||||||
val url: String,
|
|
||||||
val name: String,
|
|
||||||
val dateUpload: Long,
|
|
||||||
val chapterNumber: Float,
|
|
||||||
val scanlator: String?,
|
|
||||||
) {
|
|
||||||
val isRecognizedNumber: Boolean
|
|
||||||
get() = chapterNumber >= 0f
|
|
||||||
|
|
||||||
fun toSChapter(): SChapter {
|
|
||||||
return SChapter.create().also {
|
|
||||||
it.url = url
|
|
||||||
it.name = name
|
|
||||||
it.date_upload = dateUpload
|
|
||||||
it.chapter_number = chapterNumber
|
|
||||||
it.scanlator = scanlator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyFromSChapter(sChapter: SChapter): Chapter {
|
|
||||||
return this.copy(
|
|
||||||
name = sChapter.name,
|
|
||||||
url = sChapter.url,
|
|
||||||
dateUpload = sChapter.date_upload,
|
|
||||||
chapterNumber = sChapter.chapter_number,
|
|
||||||
scanlator = sChapter.scanlator?.ifBlank { null },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create() = Chapter(
|
|
||||||
id = -1,
|
|
||||||
mangaId = -1,
|
|
||||||
read = false,
|
|
||||||
bookmark = false,
|
|
||||||
lastPageRead = 0,
|
|
||||||
dateFetch = 0,
|
|
||||||
sourceOrder = 0,
|
|
||||||
url = "",
|
|
||||||
name = "",
|
|
||||||
dateUpload = -1,
|
|
||||||
chapterNumber = -1f,
|
|
||||||
scanlator = null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove when all deps are migrated
|
fun Chapter.copyFromSChapter(sChapter: SChapter): Chapter {
|
||||||
|
return this.copy(
|
||||||
|
name = sChapter.name,
|
||||||
|
url = sChapter.url,
|
||||||
|
dateUpload = sChapter.date_upload,
|
||||||
|
chapterNumber = sChapter.chapter_number,
|
||||||
|
scanlator = sChapter.scanlator?.ifBlank { null },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun Chapter.toDbChapter(): DbChapter = ChapterImpl().also {
|
fun Chapter.toDbChapter(): DbChapter = ChapterImpl().also {
|
||||||
it.id = id
|
it.id = id
|
||||||
it.manga_id = mangaId
|
it.manga_id = mangaId
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package eu.kanade.domain.chapter.model
|
package eu.kanade.domain.chapter.model
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import eu.kanade.domain.manga.model.downloadedFilter
|
||||||
import eu.kanade.domain.manga.model.TriStateFilter
|
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
||||||
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.TriStateFilter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the view filters to the list of chapters obtained from the database.
|
* Applies the view filters to the list of chapters obtained from the database.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.download.interactor
|
package eu.kanade.domain.download.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
import tachiyomi.core.util.lang.withNonCancellableContext
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
class DeleteDownload(
|
class DeleteDownload(
|
||||||
private val sourceManager: SourceManager,
|
private val sourceManager: SourceManager,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.domain.download.service
|
package eu.kanade.domain.download.service
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
import eu.kanade.tachiyomi.core.provider.FolderProvider
|
import tachiyomi.core.provider.FolderProvider
|
||||||
|
|
||||||
class DownloadPreferences(
|
class DownloadPreferences(
|
||||||
private val folderProvider: FolderProvider,
|
private val folderProvider: FolderProvider,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.history.interactor
|
package eu.kanade.domain.history.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.history.repository.HistoryRepository
|
|
||||||
import eu.kanade.domain.manga.interactor.GetManga
|
import eu.kanade.domain.manga.interactor.GetManga
|
||||||
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
import eu.kanade.tachiyomi.util.chapter.getChapterSort
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.history.repository.HistoryRepository
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class GetNextChapters(
|
class GetNextChapters(
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package eu.kanade.domain.library.service
|
package eu.kanade.domain.library.service
|
||||||
|
|
||||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
|
||||||
import eu.kanade.domain.library.model.LibrarySort
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
|
||||||
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
|
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_HAS_UNREAD
|
import eu.kanade.tachiyomi.data.preference.MANGA_HAS_UNREAD
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED
|
import eu.kanade.tachiyomi.data.preference.MANGA_NON_COMPLETED
|
||||||
import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ
|
import eu.kanade.tachiyomi.data.preference.MANGA_NON_READ
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
import tachiyomi.domain.library.model.LibrarySort
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
class LibraryPreferences(
|
class LibraryPreferences(
|
||||||
private val preferenceStore: PreferenceStore,
|
private val preferenceStore: PreferenceStore,
|
||||||
@ -22,7 +22,7 @@ class LibraryPreferences(
|
|||||||
|
|
||||||
fun landscapeColumns() = preferenceStore.getInt("pref_library_columns_landscape_key", 0)
|
fun landscapeColumns() = preferenceStore.getInt("pref_library_columns_landscape_key", 0)
|
||||||
|
|
||||||
fun libraryUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 24)
|
fun libraryUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 0)
|
||||||
fun libraryUpdateLastTimestamp() = preferenceStore.getLong("library_update_last_timestamp", 0L)
|
fun libraryUpdateLastTimestamp() = preferenceStore.getLong("library_update_last_timestamp", 0L)
|
||||||
|
|
||||||
fun libraryUpdateDeviceRestriction() = preferenceStore.getStringSet("library_update_restriction", setOf(DEVICE_ONLY_ON_WIFI))
|
fun libraryUpdateDeviceRestriction() = preferenceStore.getStringSet("library_update_restriction", setOf(DEVICE_ONLY_ON_WIFI))
|
||||||
@ -56,8 +56,6 @@ class LibraryPreferences(
|
|||||||
|
|
||||||
fun localBadge() = preferenceStore.getBoolean("display_local_badge", true)
|
fun localBadge() = preferenceStore.getBoolean("display_local_badge", true)
|
||||||
|
|
||||||
fun unreadBadge() = preferenceStore.getBoolean("display_unread_badge", true)
|
|
||||||
|
|
||||||
fun languageBadge() = preferenceStore.getBoolean("display_language_badge", false)
|
fun languageBadge() = preferenceStore.getBoolean("display_language_badge", false)
|
||||||
|
|
||||||
fun newShowUpdatesCount() = preferenceStore.getBoolean("library_show_updates_count", true)
|
fun newShowUpdatesCount() = preferenceStore.getBoolean("library_show_updates_count", true)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetDuplicateLibraryManga(
|
class GetDuplicateLibraryManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(title: String, sourceId: Long): Manga? {
|
suspend fun await(title: String): Manga? {
|
||||||
return mangaRepository.getDuplicateLibraryManga(title.lowercase(), sourceId)
|
return mangaRepository.getDuplicateLibraryManga(title.lowercase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetFavorites(
|
class GetFavorites(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.library.model.LibraryManga
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import tachiyomi.domain.library.model.LibraryManga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetLibraryManga(
|
class GetLibraryManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetManga(
|
class GetManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.chapter.repository.ChapterRepository
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class GetMangaWithChapters(
|
class GetMangaWithChapters(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class NetworkToLocalManga(
|
class NetworkToLocalManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class ResetViewerFlags(
|
class ResetViewerFlags(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import eu.kanade.domain.manga.model.MangaUpdate
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class SetMangaChapterFlags(
|
class SetMangaChapterFlags(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.MangaUpdate
|
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||||
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
|
|
||||||
class SetMangaViewerFlags(
|
class SetMangaViewerFlags(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package eu.kanade.domain.manga.interactor
|
package eu.kanade.domain.manga.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.model.MangaUpdate
|
|
||||||
import eu.kanade.domain.manga.model.hasCustomCover
|
import eu.kanade.domain.manga.model.hasCustomCover
|
||||||
import eu.kanade.domain.manga.model.isLocal
|
import eu.kanade.domain.manga.model.isLocal
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaUpdate
|
||||||
|
import tachiyomi.domain.manga.repository.MangaRepository
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package eu.kanade.domain.manga.model
|
package eu.kanade.domain.manga.model
|
||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import nl.adaptivity.xmlutil.serialization.XmlElement
|
import nl.adaptivity.xmlutil.serialization.XmlElement
|
||||||
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
import nl.adaptivity.xmlutil.serialization.XmlSerialName
|
||||||
import nl.adaptivity.xmlutil.serialization.XmlValue
|
import nl.adaptivity.xmlutil.serialization.XmlValue
|
||||||
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
const val COMIC_INFO_FILE = "ComicInfo.xml"
|
const val COMIC_INFO_FILE = "ComicInfo.xml"
|
||||||
|
|
||||||
|
@ -4,214 +4,69 @@ import eu.kanade.domain.base.BasePreferences
|
|||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
|
||||||
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
|
||||||
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.TriStateFilter
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.Serializable
|
|
||||||
|
|
||||||
data class Manga(
|
// TODO: move these into the domain model
|
||||||
val id: Long,
|
val Manga.readingModeType: Long
|
||||||
val source: Long,
|
get() = viewerFlags and ReadingModeType.MASK.toLong()
|
||||||
val favorite: Boolean,
|
|
||||||
val lastUpdate: Long,
|
|
||||||
val dateAdded: Long,
|
|
||||||
val viewerFlags: Long,
|
|
||||||
val chapterFlags: Long,
|
|
||||||
val coverLastModified: Long,
|
|
||||||
val url: String,
|
|
||||||
val title: String,
|
|
||||||
val artist: String?,
|
|
||||||
val author: String?,
|
|
||||||
val description: String?,
|
|
||||||
val genre: List<String>?,
|
|
||||||
val status: Long,
|
|
||||||
val thumbnailUrl: String?,
|
|
||||||
val updateStrategy: UpdateStrategy,
|
|
||||||
val initialized: Boolean,
|
|
||||||
) : Serializable {
|
|
||||||
|
|
||||||
val sorting: Long
|
val Manga.orientationType: Long
|
||||||
get() = chapterFlags and CHAPTER_SORTING_MASK
|
get() = viewerFlags and OrientationType.MASK.toLong()
|
||||||
|
|
||||||
val displayMode: Long
|
val Manga.downloadedFilter: TriStateFilter
|
||||||
get() = chapterFlags and CHAPTER_DISPLAY_MASK
|
get() {
|
||||||
|
if (forceDownloaded()) return TriStateFilter.ENABLED_IS
|
||||||
val unreadFilterRaw: Long
|
return when (downloadedFilterRaw) {
|
||||||
get() = chapterFlags and CHAPTER_UNREAD_MASK
|
Manga.CHAPTER_SHOW_DOWNLOADED -> TriStateFilter.ENABLED_IS
|
||||||
|
Manga.CHAPTER_SHOW_NOT_DOWNLOADED -> TriStateFilter.ENABLED_NOT
|
||||||
val downloadedFilterRaw: Long
|
|
||||||
get() = chapterFlags and CHAPTER_DOWNLOADED_MASK
|
|
||||||
|
|
||||||
val bookmarkedFilterRaw: Long
|
|
||||||
get() = chapterFlags and CHAPTER_BOOKMARKED_MASK
|
|
||||||
|
|
||||||
val readingModeType: Long
|
|
||||||
get() = viewerFlags and ReadingModeType.MASK.toLong()
|
|
||||||
|
|
||||||
val orientationType: Long
|
|
||||||
get() = viewerFlags and OrientationType.MASK.toLong()
|
|
||||||
|
|
||||||
val unreadFilter: TriStateFilter
|
|
||||||
get() = when (unreadFilterRaw) {
|
|
||||||
CHAPTER_SHOW_UNREAD -> TriStateFilter.ENABLED_IS
|
|
||||||
CHAPTER_SHOW_READ -> TriStateFilter.ENABLED_NOT
|
|
||||||
else -> TriStateFilter.DISABLED
|
else -> TriStateFilter.DISABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
val downloadedFilter: TriStateFilter
|
|
||||||
get() {
|
|
||||||
if (forceDownloaded()) return TriStateFilter.ENABLED_IS
|
|
||||||
return when (downloadedFilterRaw) {
|
|
||||||
CHAPTER_SHOW_DOWNLOADED -> TriStateFilter.ENABLED_IS
|
|
||||||
CHAPTER_SHOW_NOT_DOWNLOADED -> TriStateFilter.ENABLED_NOT
|
|
||||||
else -> TriStateFilter.DISABLED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val bookmarkedFilter: TriStateFilter
|
|
||||||
get() = when (bookmarkedFilterRaw) {
|
|
||||||
CHAPTER_SHOW_BOOKMARKED -> TriStateFilter.ENABLED_IS
|
|
||||||
CHAPTER_SHOW_NOT_BOOKMARKED -> TriStateFilter.ENABLED_NOT
|
|
||||||
else -> TriStateFilter.DISABLED
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chaptersFiltered(): Boolean {
|
|
||||||
return unreadFilter != TriStateFilter.DISABLED ||
|
|
||||||
downloadedFilter != TriStateFilter.DISABLED ||
|
|
||||||
bookmarkedFilter != TriStateFilter.DISABLED
|
|
||||||
}
|
|
||||||
|
|
||||||
fun forceDownloaded(): Boolean {
|
|
||||||
return favorite && Injekt.get<BasePreferences>().downloadedOnly().get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sortDescending(): Boolean {
|
|
||||||
return chapterFlags and CHAPTER_SORT_DIR_MASK == CHAPTER_SORT_DESC
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toSManga(): SManga = SManga.create().also {
|
|
||||||
it.url = url
|
|
||||||
it.title = title
|
|
||||||
it.artist = artist
|
|
||||||
it.author = author
|
|
||||||
it.description = description
|
|
||||||
it.genre = genre.orEmpty().joinToString()
|
|
||||||
it.status = status.toInt()
|
|
||||||
it.thumbnail_url = thumbnailUrl
|
|
||||||
it.initialized = initialized
|
|
||||||
}
|
|
||||||
|
|
||||||
fun copyFrom(other: SManga): Manga {
|
|
||||||
val author = other.author ?: author
|
|
||||||
val artist = other.artist ?: artist
|
|
||||||
val description = other.description ?: description
|
|
||||||
val genres = if (other.genre != null) {
|
|
||||||
other.getGenres()
|
|
||||||
} else {
|
|
||||||
genre
|
|
||||||
}
|
|
||||||
val thumbnailUrl = other.thumbnail_url ?: thumbnailUrl
|
|
||||||
return this.copy(
|
|
||||||
author = author,
|
|
||||||
artist = artist,
|
|
||||||
description = description,
|
|
||||||
genre = genres,
|
|
||||||
thumbnailUrl = thumbnailUrl,
|
|
||||||
status = other.status.toLong(),
|
|
||||||
updateStrategy = other.update_strategy,
|
|
||||||
initialized = other.initialized && initialized,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
// Generic filter that does not filter anything
|
|
||||||
const val SHOW_ALL = 0x00000000L
|
|
||||||
|
|
||||||
const val CHAPTER_SORT_DESC = 0x00000000L
|
|
||||||
const val CHAPTER_SORT_ASC = 0x00000001L
|
|
||||||
const val CHAPTER_SORT_DIR_MASK = 0x00000001L
|
|
||||||
|
|
||||||
const val CHAPTER_SHOW_UNREAD = 0x00000002L
|
|
||||||
const val CHAPTER_SHOW_READ = 0x00000004L
|
|
||||||
const val CHAPTER_UNREAD_MASK = 0x00000006L
|
|
||||||
|
|
||||||
const val CHAPTER_SHOW_DOWNLOADED = 0x00000008L
|
|
||||||
const val CHAPTER_SHOW_NOT_DOWNLOADED = 0x00000010L
|
|
||||||
const val CHAPTER_DOWNLOADED_MASK = 0x00000018L
|
|
||||||
|
|
||||||
const val CHAPTER_SHOW_BOOKMARKED = 0x00000020L
|
|
||||||
const val CHAPTER_SHOW_NOT_BOOKMARKED = 0x00000040L
|
|
||||||
const val CHAPTER_BOOKMARKED_MASK = 0x00000060L
|
|
||||||
|
|
||||||
const val CHAPTER_SORTING_SOURCE = 0x00000000L
|
|
||||||
const val CHAPTER_SORTING_NUMBER = 0x00000100L
|
|
||||||
const val CHAPTER_SORTING_UPLOAD_DATE = 0x00000200L
|
|
||||||
const val CHAPTER_SORTING_MASK = 0x00000300L
|
|
||||||
|
|
||||||
const val CHAPTER_DISPLAY_NAME = 0x00000000L
|
|
||||||
const val CHAPTER_DISPLAY_NUMBER = 0x00100000L
|
|
||||||
const val CHAPTER_DISPLAY_MASK = 0x00100000L
|
|
||||||
|
|
||||||
fun create() = Manga(
|
|
||||||
id = -1L,
|
|
||||||
url = "",
|
|
||||||
title = "",
|
|
||||||
source = -1L,
|
|
||||||
favorite = false,
|
|
||||||
lastUpdate = 0L,
|
|
||||||
dateAdded = 0L,
|
|
||||||
viewerFlags = 0L,
|
|
||||||
chapterFlags = 0L,
|
|
||||||
coverLastModified = 0L,
|
|
||||||
artist = null,
|
|
||||||
author = null,
|
|
||||||
description = null,
|
|
||||||
genre = null,
|
|
||||||
status = 0L,
|
|
||||||
thumbnailUrl = null,
|
|
||||||
updateStrategy = UpdateStrategy.ALWAYS_UPDATE,
|
|
||||||
initialized = false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
fun Manga.chaptersFiltered(): Boolean {
|
||||||
|
return unreadFilter != TriStateFilter.DISABLED ||
|
||||||
|
downloadedFilter != TriStateFilter.DISABLED ||
|
||||||
|
bookmarkedFilter != TriStateFilter.DISABLED
|
||||||
|
}
|
||||||
|
fun Manga.forceDownloaded(): Boolean {
|
||||||
|
return favorite && Injekt.get<BasePreferences>().downloadedOnly().get()
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class TriStateFilter {
|
fun Manga.toSManga(): SManga = SManga.create().also {
|
||||||
DISABLED, // Disable filter
|
it.url = url
|
||||||
ENABLED_IS, // Enabled with "is" filter
|
it.title = title
|
||||||
ENABLED_NOT, // Enabled with "not" filter
|
it.artist = artist
|
||||||
|
it.author = author
|
||||||
|
it.description = description
|
||||||
|
it.genre = genre.orEmpty().joinToString()
|
||||||
|
it.status = status.toInt()
|
||||||
|
it.thumbnail_url = thumbnailUrl
|
||||||
|
it.initialized = initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TriStateFilter.toTriStateGroupState(): ExtendedNavigationView.Item.TriStateGroup.State {
|
fun Manga.copyFrom(other: SManga): Manga {
|
||||||
return when (this) {
|
val author = other.author ?: author
|
||||||
TriStateFilter.DISABLED -> ExtendedNavigationView.Item.TriStateGroup.State.IGNORE
|
val artist = other.artist ?: artist
|
||||||
TriStateFilter.ENABLED_IS -> ExtendedNavigationView.Item.TriStateGroup.State.INCLUDE
|
val description = other.description ?: description
|
||||||
TriStateFilter.ENABLED_NOT -> ExtendedNavigationView.Item.TriStateGroup.State.EXCLUDE
|
val genres = if (other.genre != null) {
|
||||||
|
other.getGenres()
|
||||||
|
} else {
|
||||||
|
genre
|
||||||
}
|
}
|
||||||
}
|
val thumbnailUrl = other.thumbnail_url ?: thumbnailUrl
|
||||||
|
return this.copy(
|
||||||
fun Manga.toMangaUpdate(): MangaUpdate {
|
|
||||||
return MangaUpdate(
|
|
||||||
id = id,
|
|
||||||
source = source,
|
|
||||||
favorite = favorite,
|
|
||||||
lastUpdate = lastUpdate,
|
|
||||||
dateAdded = dateAdded,
|
|
||||||
viewerFlags = viewerFlags,
|
|
||||||
chapterFlags = chapterFlags,
|
|
||||||
coverLastModified = coverLastModified,
|
|
||||||
url = url,
|
|
||||||
title = title,
|
|
||||||
artist = artist,
|
|
||||||
author = author,
|
author = author,
|
||||||
|
artist = artist,
|
||||||
description = description,
|
description = description,
|
||||||
genre = genre,
|
genre = genres,
|
||||||
status = status,
|
|
||||||
thumbnailUrl = thumbnailUrl,
|
thumbnailUrl = thumbnailUrl,
|
||||||
updateStrategy = updateStrategy,
|
status = other.status.toLong(),
|
||||||
initialized = initialized,
|
updateStrategy = other.update_strategy,
|
||||||
|
initialized = other.initialized && initialized,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Pin
|
|
||||||
import eu.kanade.domain.source.model.Pins
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import tachiyomi.domain.source.model.Pin
|
||||||
|
import tachiyomi.domain.source.model.Pins
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
class GetEnabledSources(
|
class GetEnabledSources(
|
||||||
private val repository: SourceRepository,
|
private val repository: SourceRepository,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
class GetLanguagesWithSources(
|
class GetLanguagesWithSources(
|
||||||
private val repository: SourceRepository,
|
private val repository: SourceRepository,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
import java.text.Collator
|
import java.text.Collator
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.SourceWithCount
|
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
import eu.kanade.domain.source.repository.SourceRepository
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import tachiyomi.domain.source.model.SourceWithCount
|
||||||
|
|
||||||
class GetSourcesWithNonLibraryManga(
|
class GetSourcesWithNonLibraryManga(
|
||||||
private val repository: SourceRepository,
|
private val repository: SourceRepository,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.core.preference.getAndSet
|
import tachiyomi.core.preference.getAndSet
|
||||||
|
|
||||||
class ToggleLanguage(
|
class ToggleLanguage(
|
||||||
val preferences: SourcePreferences,
|
val preferences: SourcePreferences,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.core.preference.getAndSet
|
import tachiyomi.core.preference.getAndSet
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
class ToggleSource(
|
class ToggleSource(
|
||||||
private val preferences: SourcePreferences,
|
private val preferences: SourcePreferences,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.source.interactor
|
package eu.kanade.domain.source.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.core.preference.getAndSet
|
import tachiyomi.core.preference.getAndSet
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
class ToggleSourcePin(
|
class ToggleSourcePin(
|
||||||
private val preferences: SourcePreferences,
|
private val preferences: SourcePreferences,
|
||||||
|
@ -4,77 +4,13 @@ import androidx.compose.ui.graphics.ImageBitmap
|
|||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
data class Source(
|
val Source.icon: ImageBitmap?
|
||||||
val id: Long,
|
get() {
|
||||||
val lang: String,
|
return Injekt.get<ExtensionManager>().getAppIconForSource(id)
|
||||||
val name: String,
|
?.toBitmap()
|
||||||
val supportsLatest: Boolean,
|
?.asImageBitmap()
|
||||||
val isStub: Boolean,
|
|
||||||
val pin: Pins = Pins.unpinned,
|
|
||||||
val isUsedLast: Boolean = false,
|
|
||||||
) {
|
|
||||||
|
|
||||||
val visualName: String
|
|
||||||
get() = when {
|
|
||||||
lang.isEmpty() -> name
|
|
||||||
else -> "$name (${lang.uppercase()})"
|
|
||||||
}
|
|
||||||
|
|
||||||
val icon: ImageBitmap?
|
|
||||||
get() {
|
|
||||||
return Injekt.get<ExtensionManager>().getAppIconForSource(id)
|
|
||||||
?.toBitmap()
|
|
||||||
?.asImageBitmap()
|
|
||||||
}
|
|
||||||
|
|
||||||
val key: () -> String = {
|
|
||||||
when {
|
|
||||||
isUsedLast -> "$id-lastused"
|
|
||||||
else -> "$id"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sealed class Pin(val code: Int) {
|
|
||||||
object Unpinned : Pin(0b00)
|
|
||||||
object Pinned : Pin(0b01)
|
|
||||||
object Actual : Pin(0b10)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun Pins(builder: Pins.PinsBuilder.() -> Unit = {}): Pins {
|
|
||||||
return Pins.PinsBuilder().apply(builder).flags()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Pins(vararg pins: Pin) = Pins {
|
|
||||||
pins.forEach { +it }
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Pins(val code: Int = Pin.Unpinned.code) {
|
|
||||||
|
|
||||||
operator fun contains(pin: Pin): Boolean = pin.code and code == pin.code
|
|
||||||
|
|
||||||
operator fun plus(pin: Pin): Pins = Pins(code or pin.code)
|
|
||||||
|
|
||||||
operator fun minus(pin: Pin): Pins = Pins(code xor pin.code)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val unpinned = Pins(Pin.Unpinned)
|
|
||||||
|
|
||||||
val pinned = Pins(Pin.Pinned, Pin.Actual)
|
|
||||||
}
|
|
||||||
|
|
||||||
class PinsBuilder(var code: Int = 0) {
|
|
||||||
operator fun Pin.unaryPlus() {
|
|
||||||
this@PinsBuilder.code = code or this@PinsBuilder.code
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun Pin.unaryMinus() {
|
|
||||||
this@PinsBuilder.code = code or this@PinsBuilder.code
|
|
||||||
}
|
|
||||||
|
|
||||||
fun flags(): Pins = Pins(code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.source.repository
|
package eu.kanade.domain.source.repository
|
||||||
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.domain.source.model.SourcePagingSourceType
|
import eu.kanade.domain.source.model.SourcePagingSourceType
|
||||||
import eu.kanade.domain.source.model.SourceWithCount
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
import tachiyomi.domain.source.model.SourceWithCount
|
||||||
|
|
||||||
interface SourceRepository {
|
interface SourceRepository {
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.source.service
|
package eu.kanade.domain.source.service
|
||||||
|
|
||||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
|
||||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
|
||||||
import eu.kanade.tachiyomi.core.preference.getEnum
|
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
import tachiyomi.core.preference.getEnum
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
|
||||||
class SourcePreferences(
|
class SourcePreferences(
|
||||||
private val preferenceStore: PreferenceStore,
|
private val preferenceStore: PreferenceStore,
|
||||||
@ -18,8 +18,6 @@ class SourcePreferences(
|
|||||||
|
|
||||||
fun pinnedSources() = preferenceStore.getStringSet("pinned_catalogues", emptySet())
|
fun pinnedSources() = preferenceStore.getStringSet("pinned_catalogues", emptySet())
|
||||||
|
|
||||||
fun duplicatePinnedSources() = preferenceStore.getBoolean("duplicate_pinned_sources", false)
|
|
||||||
|
|
||||||
fun lastUsedSource() = preferenceStore.getLong("last_catalogue_source", -1)
|
fun lastUsedSource() = preferenceStore.getLong("last_catalogue_source", -1)
|
||||||
|
|
||||||
fun showNsfwSource() = preferenceStore.getBoolean("show_nsfw_source", true)
|
fun showNsfwSource() = preferenceStore.getBoolean("show_nsfw_source", true)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.track.interactor
|
package eu.kanade.domain.track.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.track.repository.TrackRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.track.repository.TrackRepository
|
||||||
|
|
||||||
class DeleteTrack(
|
class DeleteTrack(
|
||||||
private val trackRepository: TrackRepository,
|
private val trackRepository: TrackRepository,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package eu.kanade.domain.track.interactor
|
package eu.kanade.domain.track.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.track.model.Track
|
|
||||||
import eu.kanade.domain.track.repository.TrackRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
|
import tachiyomi.domain.track.repository.TrackRepository
|
||||||
|
|
||||||
class GetTracks(
|
class GetTracks(
|
||||||
private val trackRepository: TrackRepository,
|
private val trackRepository: TrackRepository,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.track.interactor
|
package eu.kanade.domain.track.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.track.repository.TrackRepository
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
import tachiyomi.domain.track.repository.TrackRepository
|
||||||
|
|
||||||
class GetTracksPerManga(
|
class GetTracksPerManga(
|
||||||
private val trackRepository: TrackRepository,
|
private val trackRepository: TrackRepository,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.domain.track.interactor
|
package eu.kanade.domain.track.interactor
|
||||||
|
|
||||||
import eu.kanade.domain.track.model.Track
|
|
||||||
import eu.kanade.domain.track.repository.TrackRepository
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
|
import tachiyomi.domain.track.repository.TrackRepository
|
||||||
|
|
||||||
class InsertTrack(
|
class InsertTrack(
|
||||||
private val trackRepository: TrackRepository,
|
private val trackRepository: TrackRepository,
|
||||||
|
@ -1,31 +1,16 @@
|
|||||||
package eu.kanade.domain.track.model
|
package eu.kanade.domain.track.model
|
||||||
|
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track as DbTrack
|
import eu.kanade.tachiyomi.data.database.models.Track as DbTrack
|
||||||
|
|
||||||
data class Track(
|
fun Track.copyPersonalFrom(other: Track): Track {
|
||||||
val id: Long,
|
return this.copy(
|
||||||
val mangaId: Long,
|
lastChapterRead = other.lastChapterRead,
|
||||||
val syncId: Long,
|
score = other.score,
|
||||||
val remoteId: Long,
|
status = other.status,
|
||||||
val libraryId: Long?,
|
startDate = other.startDate,
|
||||||
val title: String,
|
finishDate = other.finishDate,
|
||||||
val lastChapterRead: Double,
|
)
|
||||||
val totalChapters: Long,
|
|
||||||
val status: Long,
|
|
||||||
val score: Float,
|
|
||||||
val remoteUrl: String,
|
|
||||||
val startDate: Long,
|
|
||||||
val finishDate: Long,
|
|
||||||
) {
|
|
||||||
fun copyPersonalFrom(other: Track): Track {
|
|
||||||
return this.copy(
|
|
||||||
lastChapterRead = other.lastChapterRead,
|
|
||||||
score = other.score,
|
|
||||||
status = other.status,
|
|
||||||
startDate = other.startDate,
|
|
||||||
finishDate = other.finishDate,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Track.toDbTrack(): DbTrack = DbTrack.create(syncId).also {
|
fun Track.toDbTrack(): DbTrack = DbTrack.create(syncId).also {
|
||||||
|
@ -14,9 +14,9 @@ import eu.kanade.domain.track.interactor.InsertTrack
|
|||||||
import eu.kanade.domain.track.model.toDbTrack
|
import eu.kanade.domain.track.model.toDbTrack
|
||||||
import eu.kanade.domain.track.store.DelayedTrackingStore
|
import eu.kanade.domain.track.store.DelayedTrackingStore
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.lang.withIOContext
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -31,30 +31,33 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
|
|||||||
val trackManager = Injekt.get<TrackManager>()
|
val trackManager = Injekt.get<TrackManager>()
|
||||||
val delayedTrackingStore = Injekt.get<DelayedTrackingStore>()
|
val delayedTrackingStore = Injekt.get<DelayedTrackingStore>()
|
||||||
|
|
||||||
withIOContext {
|
val results = withIOContext {
|
||||||
val tracks = delayedTrackingStore.getItems().mapNotNull {
|
delayedTrackingStore.getItems()
|
||||||
val track = getTracks.awaitOne(it.trackId)
|
.mapNotNull {
|
||||||
if (track == null) {
|
val track = getTracks.awaitOne(it.trackId)
|
||||||
delayedTrackingStore.remove(it.trackId)
|
if (track == null) {
|
||||||
}
|
delayedTrackingStore.remove(it.trackId)
|
||||||
track
|
}
|
||||||
}
|
track?.copy(lastChapterRead = it.lastChapterRead.toDouble())
|
||||||
|
}
|
||||||
tracks.forEach { track ->
|
.mapNotNull { track ->
|
||||||
try {
|
try {
|
||||||
val service = trackManager.getService(track.syncId)
|
val service = trackManager.getService(track.syncId)
|
||||||
if (service != null && service.isLogged) {
|
if (service != null && service.isLogged) {
|
||||||
service.update(track.toDbTrack(), true)
|
logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" }
|
||||||
insertTrack.await(track)
|
service.update(track.toDbTrack(), true)
|
||||||
|
insertTrack.await(track)
|
||||||
|
}
|
||||||
|
delayedTrackingStore.remove(track.id)
|
||||||
|
null
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logcat(LogPriority.ERROR, e)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
delayedTrackingStore.remove(track.id)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logcat(LogPriority.ERROR, e)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.success()
|
return if (results.isNotEmpty()) Result.failure() else Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package eu.kanade.domain.track.service
|
package eu.kanade.domain.track.service
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
|
||||||
class TrackPreferences(
|
class TrackPreferences(
|
||||||
private val preferenceStore: PreferenceStore,
|
private val preferenceStore: PreferenceStore,
|
||||||
|
@ -2,9 +2,9 @@ package eu.kanade.domain.track.store
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import eu.kanade.domain.track.model.Track
|
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
import tachiyomi.core.util.system.logcat
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
|
|
||||||
class DelayedTrackingStore(context: Context) {
|
class DelayedTrackingStore(context: Context) {
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ import android.os.Build
|
|||||||
import eu.kanade.domain.ui.model.AppTheme
|
import eu.kanade.domain.ui.model.AppTheme
|
||||||
import eu.kanade.domain.ui.model.TabletUiMode
|
import eu.kanade.domain.ui.model.TabletUiMode
|
||||||
import eu.kanade.domain.ui.model.ThemeMode
|
import eu.kanade.domain.ui.model.ThemeMode
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
|
||||||
import eu.kanade.tachiyomi.core.preference.getEnum
|
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
import eu.kanade.tachiyomi.util.system.isDynamicColorAvailable
|
||||||
|
import tachiyomi.core.preference.PreferenceStore
|
||||||
|
import tachiyomi.core.preference.getEnum
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.presentation.browse
|
package eu.kanade.presentation.browse
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.grid.GridCells
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.HelpOutline
|
import androidx.compose.material.icons.outlined.HelpOutline
|
||||||
@ -11,26 +12,30 @@ import androidx.compose.material3.SnackbarHostState
|
|||||||
import androidx.compose.material3.SnackbarResult
|
import androidx.compose.material3.SnackbarResult
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import eu.kanade.data.source.NoResultsException
|
import eu.kanade.data.source.NoResultsException
|
||||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid
|
import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid
|
||||||
import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid
|
import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid
|
||||||
import eu.kanade.presentation.browse.components.BrowseSourceList
|
import eu.kanade.presentation.browse.components.BrowseSourceList
|
||||||
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
import eu.kanade.presentation.components.EmptyScreenAction
|
import eu.kanade.presentation.components.EmptyScreenAction
|
||||||
import eu.kanade.presentation.components.LoadingScreen
|
import eu.kanade.presentation.components.LoadingScreen
|
||||||
|
import eu.kanade.presentation.components.Scaffold
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceContent(
|
fun BrowseSourceContent(
|
||||||
source: CatalogueSource?,
|
source: Source?,
|
||||||
mangaList: LazyPagingItems<StateFlow<Manga>>,
|
mangaList: LazyPagingItems<StateFlow<Manga>>,
|
||||||
columns: GridCells,
|
columns: GridCells,
|
||||||
displayMode: LibraryDisplayMode,
|
displayMode: LibraryDisplayMode,
|
||||||
@ -139,3 +144,24 @@ fun BrowseSourceContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MissingSourceScreen(
|
||||||
|
source: SourceManager.StubSource,
|
||||||
|
navigateUp: () -> Unit,
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
topBar = { scrollBehavior ->
|
||||||
|
AppBar(
|
||||||
|
title = source.name,
|
||||||
|
navigateUp = navigateUp,
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) { paddingValues ->
|
||||||
|
EmptyScreen(
|
||||||
|
message = source.getSourceNotInstalledException().message!!,
|
||||||
|
modifier = Modifier.padding(paddingValues),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,7 +2,6 @@ package eu.kanade.presentation.browse
|
|||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -32,7 +31,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -43,7 +41,6 @@ import eu.kanade.presentation.components.EmptyScreen
|
|||||||
import eu.kanade.presentation.components.FastScrollLazyColumn
|
import eu.kanade.presentation.components.FastScrollLazyColumn
|
||||||
import eu.kanade.presentation.components.LoadingScreen
|
import eu.kanade.presentation.components.LoadingScreen
|
||||||
import eu.kanade.presentation.components.PullRefresh
|
import eu.kanade.presentation.components.PullRefresh
|
||||||
import eu.kanade.presentation.components.WarningBanner
|
|
||||||
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
|
import eu.kanade.presentation.manga.components.DotSeparatorNoSpaceText
|
||||||
import eu.kanade.presentation.theme.header
|
import eu.kanade.presentation.theme.header
|
||||||
import eu.kanade.presentation.util.padding
|
import eu.kanade.presentation.util.padding
|
||||||
@ -55,14 +52,13 @@ import eu.kanade.tachiyomi.extension.model.Extension
|
|||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
|
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionUiModel
|
||||||
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsState
|
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsState
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExtensionScreen(
|
fun ExtensionScreen(
|
||||||
state: ExtensionsState,
|
state: ExtensionsState,
|
||||||
contentPadding: PaddingValues,
|
contentPadding: PaddingValues,
|
||||||
searchQuery: String? = null,
|
searchQuery: String?,
|
||||||
onLongClickItem: (Extension) -> Unit,
|
onLongClickItem: (Extension) -> Unit,
|
||||||
onClickItemCancel: (Extension) -> Unit,
|
onClickItemCancel: (Extension) -> Unit,
|
||||||
onInstallExtension: (Extension.Available) -> Unit,
|
onInstallExtension: (Extension.Available) -> Unit,
|
||||||
@ -123,102 +119,79 @@ private fun ExtensionContent(
|
|||||||
onClickUpdateAll: () -> Unit,
|
onClickUpdateAll: () -> Unit,
|
||||||
) {
|
) {
|
||||||
var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
|
var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
|
||||||
val showMiuiWarning = DeviceUtil.isMiui && !DeviceUtil.isMiuiOptimizationDisabled()
|
|
||||||
val uriHandler = LocalUriHandler.current
|
|
||||||
|
|
||||||
FastScrollLazyColumn(
|
FastScrollLazyColumn(
|
||||||
contentPadding = if (showMiuiWarning) {
|
contentPadding = contentPadding + topSmallPaddingValues,
|
||||||
contentPadding
|
|
||||||
} else {
|
|
||||||
contentPadding + topSmallPaddingValues
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
if (showMiuiWarning) {
|
state.items.forEach { (header, items) ->
|
||||||
item {
|
item(
|
||||||
WarningBanner(
|
contentType = "header",
|
||||||
textRes = R.string.ext_miui_warning,
|
key = "extensionHeader-${header.hashCode()}",
|
||||||
modifier = Modifier
|
) {
|
||||||
.padding(bottom = MaterialTheme.padding.small)
|
when (header) {
|
||||||
.clickable {
|
is ExtensionUiModel.Header.Resource -> {
|
||||||
uriHandler.openUri("https://tachiyomi.org/extensions")
|
val action: @Composable RowScope.() -> Unit =
|
||||||
},
|
if (header.textRes == R.string.ext_updates_pending) {
|
||||||
)
|
{
|
||||||
}
|
Button(onClick = { onClickUpdateAll() }) {
|
||||||
}
|
Text(
|
||||||
|
text = stringResource(R.string.ext_update_all),
|
||||||
items(
|
style = LocalTextStyle.current.copy(
|
||||||
items = state.items,
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
contentType = {
|
),
|
||||||
when (it) {
|
)
|
||||||
is ExtensionUiModel.Header -> "header"
|
|
||||||
is ExtensionUiModel.Item -> "item"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
key = {
|
|
||||||
when (it) {
|
|
||||||
is ExtensionUiModel.Header -> "extensionHeader-${it.hashCode()}"
|
|
||||||
is ExtensionUiModel.Item -> "extension-${it.hashCode()}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) { item ->
|
|
||||||
when (item) {
|
|
||||||
is ExtensionUiModel.Header.Resource -> {
|
|
||||||
val action: @Composable RowScope.() -> Unit =
|
|
||||||
if (item.textRes == R.string.ext_updates_pending) {
|
|
||||||
{
|
|
||||||
Button(onClick = { onClickUpdateAll() }) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.ext_update_all),
|
|
||||||
style = LocalTextStyle.current.copy(
|
|
||||||
color = MaterialTheme.colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
ExtensionHeader(
|
|
||||||
textRes = item.textRes,
|
|
||||||
modifier = Modifier.animateItemPlacement(),
|
|
||||||
action = action,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is ExtensionUiModel.Header.Text -> {
|
|
||||||
ExtensionHeader(
|
|
||||||
text = item.text,
|
|
||||||
modifier = Modifier.animateItemPlacement(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is ExtensionUiModel.Item -> {
|
|
||||||
ExtensionItem(
|
|
||||||
modifier = Modifier.animateItemPlacement(),
|
|
||||||
item = item,
|
|
||||||
onClickItem = {
|
|
||||||
when (it) {
|
|
||||||
is Extension.Available -> onInstallExtension(it)
|
|
||||||
is Extension.Installed -> onOpenExtension(it)
|
|
||||||
is Extension.Untrusted -> { trustState = it }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongClickItem = onLongClickItem,
|
|
||||||
onClickItemCancel = onClickItemCancel,
|
|
||||||
onClickItemAction = {
|
|
||||||
when (it) {
|
|
||||||
is Extension.Available -> onInstallExtension(it)
|
|
||||||
is Extension.Installed -> {
|
|
||||||
if (it.hasUpdate) {
|
|
||||||
onUpdateExtension(it)
|
|
||||||
} else {
|
|
||||||
onOpenExtension(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Extension.Untrusted -> { trustState = it }
|
} else {
|
||||||
|
{}
|
||||||
}
|
}
|
||||||
},
|
ExtensionHeader(
|
||||||
)
|
textRes = header.textRes,
|
||||||
|
modifier = Modifier.animateItemPlacement(),
|
||||||
|
action = action,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ExtensionUiModel.Header.Text -> {
|
||||||
|
ExtensionHeader(
|
||||||
|
text = header.text,
|
||||||
|
modifier = Modifier.animateItemPlacement(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items(
|
||||||
|
items = items,
|
||||||
|
contentType = { "item" },
|
||||||
|
key = { "extension-${it.hashCode()}" },
|
||||||
|
) { item ->
|
||||||
|
ExtensionItem(
|
||||||
|
modifier = Modifier.animateItemPlacement(),
|
||||||
|
item = item,
|
||||||
|
onClickItem = {
|
||||||
|
when (it) {
|
||||||
|
is Extension.Available -> onInstallExtension(it)
|
||||||
|
is Extension.Installed -> onOpenExtension(it)
|
||||||
|
is Extension.Untrusted -> { trustState = it }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongClickItem = onLongClickItem,
|
||||||
|
onClickItemCancel = onClickItemCancel,
|
||||||
|
onClickItemAction = {
|
||||||
|
when (it) {
|
||||||
|
is Extension.Available -> onInstallExtension(it)
|
||||||
|
is Extension.Installed -> {
|
||||||
|
if (it.hasUpdate) {
|
||||||
|
onUpdateExtension(it)
|
||||||
|
} else {
|
||||||
|
onOpenExtension(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Extension.Untrusted -> { trustState = it }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trustState != null) {
|
if (trustState != null) {
|
||||||
|
@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
|
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
|
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
|
||||||
@ -22,6 +21,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchState
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchState
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GlobalSearchScreen(
|
fun GlobalSearchScreen(
|
||||||
@ -71,16 +71,13 @@ fun GlobalSearchContent(
|
|||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
) {
|
) {
|
||||||
items.forEach { (source, result) ->
|
items.forEach { (source, result) ->
|
||||||
item {
|
item(key = source.id) {
|
||||||
GlobalSearchResultItem(
|
GlobalSearchResultItem(
|
||||||
title = source.name,
|
title = source.name,
|
||||||
subtitle = LocaleHelper.getDisplayName(source.lang),
|
subtitle = LocaleHelper.getDisplayName(source.lang),
|
||||||
onClick = { onClickSource(source) },
|
onClick = { onClickSource(source) },
|
||||||
) {
|
) {
|
||||||
when (result) {
|
when (result) {
|
||||||
is SearchItemResult.Error -> {
|
|
||||||
GlobalSearchErrorResultItem(message = result.throwable.message)
|
|
||||||
}
|
|
||||||
SearchItemResult.Loading -> {
|
SearchItemResult.Loading -> {
|
||||||
GlobalSearchLoadingResultItem()
|
GlobalSearchLoadingResultItem()
|
||||||
}
|
}
|
||||||
@ -104,6 +101,9 @@ fun GlobalSearchContent(
|
|||||||
onLongClick = onLongClickItem,
|
onLongClick = onLongClickItem,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is SearchItemResult.Error -> {
|
||||||
|
GlobalSearchErrorResultItem(message = result.throwable.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
import eu.kanade.presentation.components.FastScrollLazyColumn
|
import eu.kanade.presentation.components.FastScrollLazyColumn
|
||||||
@ -13,6 +12,7 @@ import eu.kanade.presentation.components.Scaffold
|
|||||||
import eu.kanade.presentation.manga.components.BaseMangaListItem
|
import eu.kanade.presentation.manga.components.BaseMangaListItem
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaState
|
import eu.kanade.tachiyomi.ui.browse.migration.manga.MigrateMangaState
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MigrateMangaScreen(
|
fun MigrateMangaScreen(
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.presentation.browse
|
|||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchEmptyResultItem
|
import eu.kanade.presentation.browse.components.GlobalSearchEmptyResultItem
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
|
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
|
||||||
@ -16,6 +15,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchState
|
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchState
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MigrateSearchScreen(
|
fun MigrateSearchScreen(
|
||||||
@ -67,16 +67,13 @@ fun MigrateSearchContent(
|
|||||||
contentPadding = contentPadding,
|
contentPadding = contentPadding,
|
||||||
) {
|
) {
|
||||||
items.forEach { (source, result) ->
|
items.forEach { (source, result) ->
|
||||||
item {
|
item(key = source.id) {
|
||||||
GlobalSearchResultItem(
|
GlobalSearchResultItem(
|
||||||
title = if (source.id == sourceId) "▶ ${source.name}" else source.name,
|
title = if (source.id == sourceId) "▶ ${source.name}" else source.name,
|
||||||
subtitle = LocaleHelper.getDisplayName(source.lang),
|
subtitle = LocaleHelper.getDisplayName(source.lang),
|
||||||
onClick = { onClickSource(source) },
|
onClick = { onClickSource(source) },
|
||||||
) {
|
) {
|
||||||
when (result) {
|
when (result) {
|
||||||
is SearchItemResult.Error -> {
|
|
||||||
GlobalSearchErrorResultItem(message = result.throwable.message)
|
|
||||||
}
|
|
||||||
SearchItemResult.Loading -> {
|
SearchItemResult.Loading -> {
|
||||||
GlobalSearchLoadingResultItem()
|
GlobalSearchLoadingResultItem()
|
||||||
}
|
}
|
||||||
@ -93,6 +90,9 @@ fun MigrateSearchContent(
|
|||||||
onLongClick = onLongClickItem,
|
onLongClick = onLongClickItem,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is SearchItemResult.Error -> {
|
||||||
|
GlobalSearchErrorResultItem(message = result.throwable.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.browse.components.SourceIcon
|
import eu.kanade.presentation.browse.components.SourceIcon
|
||||||
import eu.kanade.presentation.components.Badge
|
import eu.kanade.presentation.components.Badge
|
||||||
@ -41,6 +39,7 @@ import eu.kanade.presentation.util.topSmallPaddingValues
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceState
|
import eu.kanade.tachiyomi.ui.browse.migration.sources.MigrateSourceState
|
||||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MigrateSourceScreen(
|
fun MigrateSourceScreen(
|
||||||
@ -164,7 +163,7 @@ private fun MigrateSourceItem(
|
|||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
)
|
)
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
if (sourceLangString != null) {
|
if (sourceLangString != null) {
|
||||||
|
@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
@ -18,6 +17,7 @@ import eu.kanade.presentation.more.settings.widget.SwitchPreferenceWidget
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterState
|
import eu.kanade.tachiyomi.ui.browse.source.SourcesFilterState
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SourcesFilterScreen(
|
fun SourcesFilterScreen(
|
||||||
|
@ -21,8 +21,6 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.source.model.Pin
|
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.presentation.browse.components.BaseSourceItem
|
import eu.kanade.presentation.browse.components.BaseSourceItem
|
||||||
import eu.kanade.presentation.components.EmptyScreen
|
import eu.kanade.presentation.components.EmptyScreen
|
||||||
import eu.kanade.presentation.components.LoadingScreen
|
import eu.kanade.presentation.components.LoadingScreen
|
||||||
@ -36,6 +34,8 @@ import eu.kanade.tachiyomi.source.LocalSource
|
|||||||
import eu.kanade.tachiyomi.ui.browse.source.SourcesState
|
import eu.kanade.tachiyomi.ui.browse.source.SourcesState
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listing
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.domain.source.model.Pin
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SourcesScreen(
|
fun SourcesScreen(
|
||||||
|
@ -9,10 +9,10 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import eu.kanade.domain.source.model.Source
|
|
||||||
import eu.kanade.presentation.util.padding
|
import eu.kanade.presentation.util.padding
|
||||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BaseSourceItem(
|
fun BaseSourceItem(
|
||||||
|
@ -27,11 +27,13 @@ import androidx.compose.ui.res.painterResource
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import eu.kanade.domain.source.model.Source
|
import eu.kanade.domain.source.model.icon
|
||||||
import eu.kanade.presentation.util.rememberResourceBitmapPainter
|
import eu.kanade.presentation.util.rememberResourceBitmapPainter
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
|
import tachiyomi.core.util.lang.withIOContext
|
||||||
|
import tachiyomi.domain.source.model.Source
|
||||||
|
|
||||||
private val defaultModifier = Modifier
|
private val defaultModifier = Modifier
|
||||||
.height(40.dp)
|
.height(40.dp)
|
||||||
@ -60,13 +62,20 @@ fun SourceIcon(
|
|||||||
modifier = modifier.then(defaultModifier),
|
modifier = modifier.then(defaultModifier),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
source.id == LocalSource.ID -> {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(R.mipmap.ic_local_source),
|
painter = painterResource(R.mipmap.ic_local_source),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = modifier.then(defaultModifier),
|
modifier = modifier.then(defaultModifier),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
else -> {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(R.mipmap.ic_default_source),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = modifier.then(defaultModifier),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,17 +99,17 @@ fun ExtensionIcon(
|
|||||||
is Extension.Installed -> {
|
is Extension.Installed -> {
|
||||||
val icon by extension.getIcon(density)
|
val icon by extension.getIcon(density)
|
||||||
when (icon) {
|
when (icon) {
|
||||||
Result.Error -> Image(
|
|
||||||
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_local_source),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
Result.Loading -> Box(modifier = modifier)
|
Result.Loading -> Box(modifier = modifier)
|
||||||
is Result.Success -> Image(
|
is Result.Success -> Image(
|
||||||
bitmap = (icon as Result.Success<ImageBitmap>).value,
|
bitmap = (icon as Result.Success<ImageBitmap>).value,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
|
Result.Error -> Image(
|
||||||
|
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_default_source),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = modifier,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Extension.Untrusted -> Image(
|
is Extension.Untrusted -> Image(
|
||||||
|
@ -11,13 +11,13 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.model.MangaCover
|
|
||||||
import eu.kanade.presentation.browse.InLibraryBadge
|
import eu.kanade.presentation.browse.InLibraryBadge
|
||||||
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
||||||
import eu.kanade.presentation.components.MangaComfortableGridItem
|
import eu.kanade.presentation.components.MangaComfortableGridItem
|
||||||
import eu.kanade.presentation.util.plus
|
import eu.kanade.presentation.util.plus
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaCover
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceComfortableGrid(
|
fun BrowseSourceComfortableGrid(
|
||||||
|
@ -11,13 +11,13 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.model.MangaCover
|
|
||||||
import eu.kanade.presentation.browse.InLibraryBadge
|
import eu.kanade.presentation.browse.InLibraryBadge
|
||||||
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
||||||
import eu.kanade.presentation.components.MangaCompactGridItem
|
import eu.kanade.presentation.components.MangaCompactGridItem
|
||||||
import eu.kanade.presentation.util.plus
|
import eu.kanade.presentation.util.plus
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaCover
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceCompactGrid(
|
fun BrowseSourceCompactGrid(
|
||||||
|
@ -7,8 +7,8 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RemoveMangaDialog(
|
fun RemoveMangaDialog(
|
||||||
|
@ -8,14 +8,14 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.paging.compose.LazyPagingItems
|
import androidx.paging.compose.LazyPagingItems
|
||||||
import androidx.paging.compose.items
|
import androidx.paging.compose.items
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.model.MangaCover
|
|
||||||
import eu.kanade.presentation.browse.InLibraryBadge
|
import eu.kanade.presentation.browse.InLibraryBadge
|
||||||
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
||||||
import eu.kanade.presentation.components.LazyColumn
|
import eu.kanade.presentation.components.LazyColumn
|
||||||
import eu.kanade.presentation.components.MangaListItem
|
import eu.kanade.presentation.components.MangaListItem
|
||||||
import eu.kanade.presentation.util.plus
|
import eu.kanade.presentation.util.plus
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.MangaCover
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceList(
|
fun BrowseSourceList(
|
||||||
|
@ -13,7 +13,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.library.model.LibraryDisplayMode
|
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
import eu.kanade.presentation.components.AppBarActions
|
import eu.kanade.presentation.components.AppBarActions
|
||||||
import eu.kanade.presentation.components.AppBarTitle
|
import eu.kanade.presentation.components.AppBarTitle
|
||||||
@ -21,14 +20,15 @@ import eu.kanade.presentation.components.DropdownMenu
|
|||||||
import eu.kanade.presentation.components.RadioMenuItem
|
import eu.kanade.presentation.components.RadioMenuItem
|
||||||
import eu.kanade.presentation.components.SearchToolbar
|
import eu.kanade.presentation.components.SearchToolbar
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
|
import eu.kanade.tachiyomi.source.Source
|
||||||
|
import tachiyomi.domain.library.model.LibraryDisplayMode
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BrowseSourceToolbar(
|
fun BrowseSourceToolbar(
|
||||||
searchQuery: String?,
|
searchQuery: String?,
|
||||||
onSearchQueryChange: (String?) -> Unit,
|
onSearchQueryChange: (String?) -> Unit,
|
||||||
source: CatalogueSource?,
|
source: Source?,
|
||||||
displayMode: LibraryDisplayMode,
|
displayMode: LibraryDisplayMode,
|
||||||
onDisplayModeChange: (LibraryDisplayMode) -> Unit,
|
onDisplayModeChange: (LibraryDisplayMode) -> Unit,
|
||||||
navigateUp: () -> Unit,
|
navigateUp: () -> Unit,
|
||||||
|
@ -5,10 +5,10 @@ import androidx.compose.foundation.layout.width
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.manga.model.MangaCover
|
|
||||||
import eu.kanade.presentation.browse.InLibraryBadge
|
import eu.kanade.presentation.browse.InLibraryBadge
|
||||||
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
import eu.kanade.presentation.components.CommonMangaItemDefaults
|
||||||
import eu.kanade.presentation.components.MangaComfortableGridItem
|
import eu.kanade.presentation.components.MangaComfortableGridItem
|
||||||
|
import tachiyomi.domain.manga.model.MangaCover
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GlobalSearchCard(
|
fun GlobalSearchCard(
|
||||||
@ -18,7 +18,7 @@ fun GlobalSearchCard(
|
|||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.width(128.dp)) {
|
Box(modifier = Modifier.width(96.dp)) {
|
||||||
MangaComfortableGridItem(
|
MangaComfortableGridItem(
|
||||||
title = title,
|
title = title,
|
||||||
coverData = cover,
|
coverData = cover,
|
@ -8,9 +8,9 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import eu.kanade.domain.manga.model.Manga
|
|
||||||
import eu.kanade.domain.manga.model.asMangaCover
|
|
||||||
import eu.kanade.presentation.util.padding
|
import eu.kanade.presentation.util.padding
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.manga.model.asMangaCover
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GlobalSearchCardRow(
|
fun GlobalSearchCardRow(
|
||||||
@ -20,14 +20,11 @@ fun GlobalSearchCardRow(
|
|||||||
onLongClick: (Manga) -> Unit,
|
onLongClick: (Manga) -> Unit,
|
||||||
) {
|
) {
|
||||||
LazyRow(
|
LazyRow(
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(MaterialTheme.padding.small),
|
||||||
horizontal = MaterialTheme.padding.medium,
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.tiny),
|
||||||
vertical = MaterialTheme.padding.small,
|
|
||||||
),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
|
||||||
) {
|
) {
|
||||||
items(titles) { title ->
|
items(titles) {
|
||||||
val title by getManga(title)
|
val title by getManga(it)
|
||||||
GlobalSearchCard(
|
GlobalSearchCard(
|
||||||
title = title.title,
|
title = title.title,
|
||||||
cover = title.asMangaCover(),
|
cover = title.asMangaCover(),
|
||||||
|
@ -3,8 +3,8 @@ package eu.kanade.presentation.category
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
||||||
val Category.visualName: String
|
val Category.visualName: String
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -7,7 +7,6 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.presentation.category.components.CategoryContent
|
import eu.kanade.presentation.category.components.CategoryContent
|
||||||
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
import eu.kanade.presentation.category.components.CategoryFloatingActionButton
|
||||||
import eu.kanade.presentation.components.AppBar
|
import eu.kanade.presentation.components.AppBar
|
||||||
@ -18,6 +17,7 @@ import eu.kanade.presentation.util.plus
|
|||||||
import eu.kanade.presentation.util.topSmallPaddingValues
|
import eu.kanade.presentation.util.topSmallPaddingValues
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.category.CategoryScreenState
|
import eu.kanade.tachiyomi.ui.category.CategoryScreenState
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryScreen(
|
fun CategoryScreen(
|
||||||
|
@ -4,11 +4,12 @@ import androidx.compose.foundation.layout.Arrangement
|
|||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.presentation.components.LazyColumn
|
import eu.kanade.presentation.components.LazyColumn
|
||||||
|
import eu.kanade.presentation.util.padding
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryContent(
|
fun CategoryContent(
|
||||||
@ -23,7 +24,7 @@ fun CategoryContent(
|
|||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = lazyListState,
|
state = lazyListState,
|
||||||
contentPadding = paddingValues,
|
contentPadding = paddingValues,
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
items = categories,
|
items = categories,
|
||||||
|
@ -14,26 +14,32 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryCreateDialog(
|
fun CategoryCreateDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onCreate: (String) -> Unit,
|
onCreate: (String) -> Unit,
|
||||||
|
categories: List<Category>,
|
||||||
) {
|
) {
|
||||||
var name by remember { mutableStateOf("") }
|
var name by remember { mutableStateOf("") }
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val nameAlreadyExists = remember(name) { categories.anyWithName(name) }
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = {
|
TextButton(
|
||||||
onCreate(name)
|
enabled = name.isNotEmpty() && !nameAlreadyExists,
|
||||||
onDismissRequest()
|
onClick = {
|
||||||
},) {
|
onCreate(name)
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
) {
|
||||||
Text(text = stringResource(R.string.action_add))
|
Text(text = stringResource(R.string.action_add))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -47,13 +53,15 @@ fun CategoryCreateDialog(
|
|||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier.focusRequester(focusRequester),
|
||||||
.focusRequester(focusRequester),
|
|
||||||
value = name,
|
value = name,
|
||||||
onValueChange = { name = it },
|
onValueChange = { name = it },
|
||||||
label = {
|
label = { Text(text = stringResource(R.string.name)) },
|
||||||
Text(text = stringResource(R.string.name))
|
supportingText = {
|
||||||
|
val msgRes = if (name.isNotEmpty() && nameAlreadyExists) R.string.error_category_exists else R.string.information_required_plain
|
||||||
|
Text(text = stringResource(msgRes))
|
||||||
},
|
},
|
||||||
|
isError = name.isNotEmpty() && nameAlreadyExists,
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -70,18 +78,25 @@ fun CategoryCreateDialog(
|
|||||||
fun CategoryRenameDialog(
|
fun CategoryRenameDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onRename: (String) -> Unit,
|
onRename: (String) -> Unit,
|
||||||
|
categories: List<Category>,
|
||||||
category: Category,
|
category: Category,
|
||||||
) {
|
) {
|
||||||
var name by remember { mutableStateOf(category.name) }
|
var name by remember { mutableStateOf(category.name) }
|
||||||
|
var valueHasChanged by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val nameAlreadyExists = remember(name) { categories.anyWithName(name) }
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = {
|
TextButton(
|
||||||
onRename(name)
|
enabled = valueHasChanged && !nameAlreadyExists,
|
||||||
onDismissRequest()
|
onClick = {
|
||||||
},) {
|
onRename(name)
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
) {
|
||||||
Text(text = stringResource(android.R.string.ok))
|
Text(text = stringResource(android.R.string.ok))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -95,13 +110,18 @@ fun CategoryRenameDialog(
|
|||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier.focusRequester(focusRequester),
|
||||||
.focusRequester(focusRequester),
|
|
||||||
value = name,
|
value = name,
|
||||||
onValueChange = { name = it },
|
onValueChange = {
|
||||||
label = {
|
valueHasChanged = name != it
|
||||||
Text(text = stringResource(R.string.name))
|
name = it
|
||||||
},
|
},
|
||||||
|
label = { Text(text = stringResource(R.string.name)) },
|
||||||
|
supportingText = {
|
||||||
|
val msgRes = if (valueHasChanged && nameAlreadyExists) R.string.error_category_exists else R.string.information_required_plain
|
||||||
|
Text(text = stringResource(msgRes))
|
||||||
|
},
|
||||||
|
isError = valueHasChanged && nameAlreadyExists,
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -143,3 +163,7 @@ fun CategoryDeleteDialog(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun List<Category>.anyWithName(name: String): Boolean {
|
||||||
|
return any { name == it.name }
|
||||||
|
}
|
||||||
|
@ -20,9 +20,9 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.presentation.util.padding
|
import eu.kanade.presentation.util.padding
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryListItem(
|
fun CategoryListItem(
|
||||||
|
@ -48,6 +48,8 @@ import eu.kanade.presentation.util.runOnEnterKeyPressed
|
|||||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
|
||||||
|
const val SEARCH_DEBOUNCE_MILLIS = 250L
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppBar(
|
fun AppBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
@ -22,10 +22,10 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.core.prefs.CheckboxState
|
import eu.kanade.core.prefs.CheckboxState
|
||||||
import eu.kanade.domain.category.model.Category
|
|
||||||
import eu.kanade.presentation.category.visualName
|
import eu.kanade.presentation.category.visualName
|
||||||
import eu.kanade.presentation.util.padding
|
import eu.kanade.presentation.util.padding
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import tachiyomi.domain.category.model.Category
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChangeCategoryDialog(
|
fun ChangeCategoryDialog(
|
||||||
@ -80,7 +80,7 @@ fun ChangeCategoryDialog(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.action_add))
|
Text(text = stringResource(android.R.string.ok))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -62,7 +62,7 @@ private const val GridSelectedCoverAlpha = 0.76f
|
|||||||
fun MangaCompactGridItem(
|
fun MangaCompactGridItem(
|
||||||
isSelected: Boolean = false,
|
isSelected: Boolean = false,
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
coverData: eu.kanade.domain.manga.model.MangaCover,
|
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
coverBadgeStart: @Composable (RowScope.() -> Unit)? = null,
|
coverBadgeStart: @Composable (RowScope.() -> Unit)? = null,
|
||||||
coverBadgeEnd: @Composable (RowScope.() -> Unit)? = null,
|
coverBadgeEnd: @Composable (RowScope.() -> Unit)? = null,
|
||||||
@ -162,7 +162,7 @@ private fun BoxScope.CoverTextOverlay(
|
|||||||
fun MangaComfortableGridItem(
|
fun MangaComfortableGridItem(
|
||||||
isSelected: Boolean = false,
|
isSelected: Boolean = false,
|
||||||
title: String,
|
title: String,
|
||||||
coverData: eu.kanade.domain.manga.model.MangaCover,
|
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeStart: (@Composable RowScope.() -> Unit)? = null,
|
||||||
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
coverBadgeEnd: (@Composable RowScope.() -> Unit)? = null,
|
||||||
@ -330,7 +330,7 @@ private fun Modifier.selectedOutline(
|
|||||||
fun MangaListItem(
|
fun MangaListItem(
|
||||||
isSelected: Boolean = false,
|
isSelected: Boolean = false,
|
||||||
title: String,
|
title: String,
|
||||||
coverData: eu.kanade.domain.manga.model.MangaCover,
|
coverData: tachiyomi.domain.manga.model.MangaCover,
|
||||||
coverAlpha: Float = 1f,
|
coverAlpha: Float = 1f,
|
||||||
badge: @Composable (RowScope.() -> Unit),
|
badge: @Composable (RowScope.() -> Unit),
|
||||||
onLongClick: () -> Unit,
|
onLongClick: () -> Unit,
|
||||||
|
@ -44,6 +44,7 @@ fun DeleteLibraryMangaDialog(
|
|||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
|
enabled = list.any { it.isChecked },
|
||||||
onClick = {
|
onClick = {
|
||||||
onDismissRequest()
|
onDismissRequest()
|
||||||
onConfirm(
|
onConfirm(
|
||||||
@ -63,9 +64,11 @@ fun DeleteLibraryMangaDialog(
|
|||||||
list.forEach { state ->
|
list.forEach { state ->
|
||||||
val onCheck = {
|
val onCheck = {
|
||||||
val index = list.indexOf(state)
|
val index = list.indexOf(state)
|
||||||
val mutableList = list.toMutableList()
|
if (index != -1) {
|
||||||
mutableList[index] = state.next() as CheckboxState.State<Int>
|
val mutableList = list.toMutableList()
|
||||||
list = mutableList.toList()
|
mutableList[index] = state.next() as CheckboxState.State<Int>
|
||||||
|
list = mutableList.toList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
|
@ -9,14 +9,12 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DuplicateMangaDialog(
|
fun DuplicateMangaDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
onOpenManga: () -> Unit,
|
onOpenManga: () -> Unit,
|
||||||
duplicateFrom: Source,
|
|
||||||
) {
|
) {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
@ -46,12 +44,7 @@ fun DuplicateMangaDialog(
|
|||||||
Text(text = stringResource(R.string.are_you_sure))
|
Text(text = stringResource(R.string.are_you_sure))
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
Text(
|
Text(text = stringResource(R.string.confirm_add_duplicate_manga))
|
||||||
text = stringResource(
|
|
||||||
id = R.string.confirm_manga_add_duplicate,
|
|
||||||
duplicateFrom.name,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.presentation.theme.TachiyomiTheme
|
import eu.kanade.presentation.theme.TachiyomiTheme
|
||||||
import eu.kanade.presentation.util.ThemePreviews
|
import eu.kanade.presentation.util.ThemePreviews
|
||||||
|
import eu.kanade.presentation.util.padding
|
||||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -79,7 +80,7 @@ fun EmptyScreen(
|
|||||||
start = 24.dp,
|
start = 24.dp,
|
||||||
end = 24.dp,
|
end = 24.dp,
|
||||||
),
|
),
|
||||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
|
||||||
) {
|
) {
|
||||||
actions.forEach {
|
actions.forEach {
|
||||||
ActionButton(
|
ActionButton(
|
||||||
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.layout.windowInsetsPadding
|
import androidx.compose.foundation.layout.windowInsetsPadding
|
||||||
import androidx.compose.foundation.selection.selectableGroup
|
import androidx.compose.foundation.selection.selectableGroup
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.NavigationRailDefaults
|
import androidx.compose.material3.NavigationRailDefaults
|
||||||
import androidx.compose.material3.contentColorFor
|
import androidx.compose.material3.contentColorFor
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -18,6 +19,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import eu.kanade.presentation.util.padding
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Center-aligned M3 Navigation rail
|
* Center-aligned M3 Navigation rail
|
||||||
@ -44,14 +46,14 @@ fun NavigationRail(
|
|||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.windowInsetsPadding(windowInsets)
|
.windowInsetsPadding(windowInsets)
|
||||||
.widthIn(min = 80.dp)
|
.widthIn(min = 80.dp)
|
||||||
.padding(vertical = 4.dp)
|
.padding(vertical = MaterialTheme.padding.tiny)
|
||||||
.selectableGroup(),
|
.selectableGroup(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.CenterVertically),
|
verticalArrangement = Arrangement.spacedBy(MaterialTheme.padding.tiny, alignment = Alignment.CenterVertically),
|
||||||
) {
|
) {
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
header()
|
header()
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(MaterialTheme.padding.small))
|
||||||
}
|
}
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
|
@ -240,13 +240,16 @@ private fun ScaffoldLayout(
|
|||||||
)
|
)
|
||||||
}.fastMap { it.measure(looseConstraints) }
|
}.fastMap { it.measure(looseConstraints) }
|
||||||
|
|
||||||
val bottomBarHeight = bottomBarPlaceables.fastMaxBy { it.height }?.height
|
val bottomBarHeight = bottomBarPlaceables
|
||||||
|
.fastMaxBy { it.height }
|
||||||
|
?.height
|
||||||
|
?.takeIf { it != 0 }
|
||||||
val fabOffsetFromBottom = fabPlacement?.let {
|
val fabOffsetFromBottom = fabPlacement?.let {
|
||||||
max(bottomBarHeight ?: 0, bottomInset) + it.height + FabSpacing.roundToPx()
|
max(bottomBarHeight ?: 0, bottomInset) + it.height + FabSpacing.roundToPx()
|
||||||
}
|
}
|
||||||
|
|
||||||
val snackbarOffsetFromBottom = if (snackbarHeight != 0) {
|
val snackbarOffsetFromBottom = if (snackbarHeight != 0) {
|
||||||
snackbarHeight + (fabOffsetFromBottom ?: bottomBarHeight ?: bottomInset)
|
snackbarHeight + (fabOffsetFromBottom ?: max(bottomBarHeight ?: 0, bottomInset))
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.ContentAlpha
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowDownward
|
import androidx.compose.material.icons.filled.ArrowDownward
|
||||||
import androidx.compose.material.icons.filled.ArrowUpward
|
import androidx.compose.material.icons.filled.ArrowUpward
|
||||||
@ -21,7 +22,7 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.kanade.domain.manga.model.TriStateFilter
|
import tachiyomi.domain.manga.model.TriStateFilter
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TriStateItem(
|
fun TriStateItem(
|
||||||
@ -46,6 +47,8 @@ fun TriStateItem(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(24.dp),
|
horizontalArrangement = Arrangement.spacedBy(24.dp),
|
||||||
) {
|
) {
|
||||||
|
val stateAlpha = if (onClick != null) 1f else ContentAlpha.disabled
|
||||||
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = when (state) {
|
imageVector = when (state) {
|
||||||
TriStateFilter.DISABLED -> Icons.Rounded.CheckBoxOutlineBlank
|
TriStateFilter.DISABLED -> Icons.Rounded.CheckBoxOutlineBlank
|
||||||
@ -54,13 +57,17 @@ fun TriStateItem(
|
|||||||
},
|
},
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = if (state == TriStateFilter.DISABLED) {
|
tint = if (state == TriStateFilter.DISABLED) {
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant
|
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = stateAlpha)
|
||||||
} else {
|
} else {
|
||||||
MaterialTheme.colorScheme.primary
|
when (onClick) {
|
||||||
|
null -> MaterialTheme.colorScheme.onSurface.copy(alpha = ContentAlpha.disabled)
|
||||||
|
else -> MaterialTheme.colorScheme.primary
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = label,
|
text = label,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface.copy(alpha = stateAlpha),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user