mirror of
https://github.com/mihonapp/mihon.git
synced 2025-06-28 20:17:51 +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 |
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,26 +2,11 @@ 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,
|
|
||||||
val read: Boolean,
|
|
||||||
val bookmark: Boolean,
|
|
||||||
val lastPageRead: Long,
|
|
||||||
val dateFetch: Long,
|
|
||||||
val sourceOrder: Long,
|
|
||||||
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 {
|
return SChapter.create().also {
|
||||||
it.url = url
|
it.url = url
|
||||||
it.name = name
|
it.name = name
|
||||||
@ -31,7 +16,7 @@ data class Chapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copyFromSChapter(sChapter: SChapter): Chapter {
|
fun Chapter.copyFromSChapter(sChapter: SChapter): Chapter {
|
||||||
return this.copy(
|
return this.copy(
|
||||||
name = sChapter.name,
|
name = sChapter.name,
|
||||||
url = sChapter.url,
|
url = sChapter.url,
|
||||||
@ -41,25 +26,6 @@ data class Chapter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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.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,95 +4,39 @@ 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,
|
|
||||||
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
|
|
||||||
get() = chapterFlags and CHAPTER_SORTING_MASK
|
|
||||||
|
|
||||||
val displayMode: Long
|
|
||||||
get() = chapterFlags and CHAPTER_DISPLAY_MASK
|
|
||||||
|
|
||||||
val unreadFilterRaw: Long
|
|
||||||
get() = chapterFlags and CHAPTER_UNREAD_MASK
|
|
||||||
|
|
||||||
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()
|
get() = viewerFlags and ReadingModeType.MASK.toLong()
|
||||||
|
|
||||||
val orientationType: Long
|
val Manga.orientationType: Long
|
||||||
get() = viewerFlags and OrientationType.MASK.toLong()
|
get() = viewerFlags and OrientationType.MASK.toLong()
|
||||||
|
|
||||||
val unreadFilter: TriStateFilter
|
val Manga.downloadedFilter: TriStateFilter
|
||||||
get() = when (unreadFilterRaw) {
|
|
||||||
CHAPTER_SHOW_UNREAD -> TriStateFilter.ENABLED_IS
|
|
||||||
CHAPTER_SHOW_READ -> TriStateFilter.ENABLED_NOT
|
|
||||||
else -> TriStateFilter.DISABLED
|
|
||||||
}
|
|
||||||
|
|
||||||
val downloadedFilter: TriStateFilter
|
|
||||||
get() {
|
get() {
|
||||||
if (forceDownloaded()) return TriStateFilter.ENABLED_IS
|
if (forceDownloaded()) return TriStateFilter.ENABLED_IS
|
||||||
return when (downloadedFilterRaw) {
|
return when (downloadedFilterRaw) {
|
||||||
CHAPTER_SHOW_DOWNLOADED -> TriStateFilter.ENABLED_IS
|
Manga.CHAPTER_SHOW_DOWNLOADED -> TriStateFilter.ENABLED_IS
|
||||||
CHAPTER_SHOW_NOT_DOWNLOADED -> TriStateFilter.ENABLED_NOT
|
Manga.CHAPTER_SHOW_NOT_DOWNLOADED -> TriStateFilter.ENABLED_NOT
|
||||||
else -> TriStateFilter.DISABLED
|
else -> TriStateFilter.DISABLED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun Manga.chaptersFiltered(): Boolean {
|
||||||
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 ||
|
return unreadFilter != TriStateFilter.DISABLED ||
|
||||||
downloadedFilter != TriStateFilter.DISABLED ||
|
downloadedFilter != TriStateFilter.DISABLED ||
|
||||||
bookmarkedFilter != TriStateFilter.DISABLED
|
bookmarkedFilter != TriStateFilter.DISABLED
|
||||||
}
|
}
|
||||||
|
fun Manga.forceDownloaded(): Boolean {
|
||||||
fun forceDownloaded(): Boolean {
|
|
||||||
return favorite && Injekt.get<BasePreferences>().downloadedOnly().get()
|
return favorite && Injekt.get<BasePreferences>().downloadedOnly().get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sortDescending(): Boolean {
|
fun Manga.toSManga(): SManga = SManga.create().also {
|
||||||
return chapterFlags and CHAPTER_SORT_DIR_MASK == CHAPTER_SORT_DESC
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toSManga(): SManga = SManga.create().also {
|
|
||||||
it.url = url
|
it.url = url
|
||||||
it.title = title
|
it.title = title
|
||||||
it.artist = artist
|
it.artist = artist
|
||||||
@ -104,7 +48,7 @@ data class Manga(
|
|||||||
it.initialized = initialized
|
it.initialized = initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copyFrom(other: SManga): Manga {
|
fun Manga.copyFrom(other: SManga): Manga {
|
||||||
val author = other.author ?: author
|
val author = other.author ?: author
|
||||||
val artist = other.artist ?: artist
|
val artist = other.artist ?: artist
|
||||||
val description = other.description ?: description
|
val description = other.description ?: description
|
||||||
@ -126,95 +70,6 @@ data class Manga(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class TriStateFilter {
|
|
||||||
DISABLED, // Disable filter
|
|
||||||
ENABLED_IS, // Enabled with "is" filter
|
|
||||||
ENABLED_NOT, // Enabled with "not" filter
|
|
||||||
}
|
|
||||||
|
|
||||||
fun TriStateFilter.toTriStateGroupState(): ExtendedNavigationView.Item.TriStateGroup.State {
|
|
||||||
return when (this) {
|
|
||||||
TriStateFilter.DISABLED -> ExtendedNavigationView.Item.TriStateGroup.State.IGNORE
|
|
||||||
TriStateFilter.ENABLED_IS -> ExtendedNavigationView.Item.TriStateGroup.State.INCLUDE
|
|
||||||
TriStateFilter.ENABLED_NOT -> ExtendedNavigationView.Item.TriStateGroup.State.EXCLUDE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
description = description,
|
|
||||||
genre = genre,
|
|
||||||
status = status,
|
|
||||||
thumbnailUrl = thumbnailUrl,
|
|
||||||
updateStrategy = updateStrategy,
|
|
||||||
initialized = initialized,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SManga.toDomainManga(sourceId: Long): Manga {
|
fun SManga.toDomainManga(sourceId: Long): Manga {
|
||||||
return Manga.create().copy(
|
return Manga.create().copy(
|
||||||
url = url,
|
url = url,
|
||||||
|
@ -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,
|
|
||||||
val lang: String,
|
|
||||||
val name: String,
|
|
||||||
val supportsLatest: Boolean,
|
|
||||||
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() {
|
get() {
|
||||||
return Injekt.get<ExtensionManager>().getAppIconForSource(id)
|
return Injekt.get<ExtensionManager>().getAppIconForSource(id)
|
||||||
?.toBitmap()
|
?.toBitmap()
|
||||||
?.asImageBitmap()
|
?.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,23 +1,9 @@
|
|||||||
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,
|
|
||||||
val mangaId: Long,
|
|
||||||
val syncId: Long,
|
|
||||||
val remoteId: Long,
|
|
||||||
val libraryId: Long?,
|
|
||||||
val title: String,
|
|
||||||
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(
|
return this.copy(
|
||||||
lastChapterRead = other.lastChapterRead,
|
lastChapterRead = other.lastChapterRead,
|
||||||
score = other.score,
|
score = other.score,
|
||||||
@ -26,7 +12,6 @@ data class Track(
|
|||||||
finishDate = other.finishDate,
|
finishDate = other.finishDate,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun Track.toDbTrack(): DbTrack = DbTrack.create(syncId).also {
|
fun Track.toDbTrack(): DbTrack = DbTrack.create(syncId).also {
|
||||||
it.id = id
|
it.id = id
|
||||||
|
@ -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()
|
||||||
|
.mapNotNull {
|
||||||
val track = getTracks.awaitOne(it.trackId)
|
val track = getTracks.awaitOne(it.trackId)
|
||||||
if (track == null) {
|
if (track == null) {
|
||||||
delayedTrackingStore.remove(it.trackId)
|
delayedTrackingStore.remove(it.trackId)
|
||||||
}
|
}
|
||||||
track
|
track?.copy(lastChapterRead = it.lastChapterRead.toDouble())
|
||||||
}
|
}
|
||||||
|
.mapNotNull { track ->
|
||||||
tracks.forEach { 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) {
|
||||||
|
logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" }
|
||||||
service.update(track.toDbTrack(), true)
|
service.update(track.toDbTrack(), true)
|
||||||
insertTrack.await(track)
|
insertTrack.await(track)
|
||||||
}
|
}
|
||||||
delayedTrackingStore.remove(track.id)
|
delayedTrackingStore.remove(track.id)
|
||||||
|
null
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logcat(LogPriority.ERROR, e)
|
logcat(LogPriority.ERROR, e)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,48 +119,19 @@ 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 {
|
|
||||||
uriHandler.openUri("https://tachiyomi.org/extensions")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
items(
|
|
||||||
items = state.items,
|
|
||||||
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 -> {
|
is ExtensionUiModel.Header.Resource -> {
|
||||||
val action: @Composable RowScope.() -> Unit =
|
val action: @Composable RowScope.() -> Unit =
|
||||||
if (item.textRes == R.string.ext_updates_pending) {
|
if (header.textRes == R.string.ext_updates_pending) {
|
||||||
{
|
{
|
||||||
Button(onClick = { onClickUpdateAll() }) {
|
Button(onClick = { onClickUpdateAll() }) {
|
||||||
Text(
|
Text(
|
||||||
@ -179,18 +146,25 @@ private fun ExtensionContent(
|
|||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
ExtensionHeader(
|
ExtensionHeader(
|
||||||
textRes = item.textRes,
|
textRes = header.textRes,
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItemPlacement(),
|
||||||
action = action,
|
action = action,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ExtensionUiModel.Header.Text -> {
|
is ExtensionUiModel.Header.Text -> {
|
||||||
ExtensionHeader(
|
ExtensionHeader(
|
||||||
text = item.text,
|
text = header.text,
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItemPlacement(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is ExtensionUiModel.Item -> {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items(
|
||||||
|
items = items,
|
||||||
|
contentType = { "item" },
|
||||||
|
key = { "extension-${it.hashCode()}" },
|
||||||
|
) { item ->
|
||||||
ExtensionItem(
|
ExtensionItem(
|
||||||
modifier = Modifier.animateItemPlacement(),
|
modifier = Modifier.animateItemPlacement(),
|
||||||
item = item,
|
item = item,
|
||||||
@ -220,7 +194,6 @@ private fun ExtensionContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (trustState != null) {
|
if (trustState != null) {
|
||||||
ExtensionTrustDialog(
|
ExtensionTrustDialog(
|
||||||
onClickConfirm = {
|
onClickConfirm = {
|
||||||
|
@ -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(
|
||||||
|
enabled = name.isNotEmpty() && !nameAlreadyExists,
|
||||||
|
onClick = {
|
||||||
onCreate(name)
|
onCreate(name)
|
||||||
onDismissRequest()
|
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(
|
||||||
|
enabled = valueHasChanged && !nameAlreadyExists,
|
||||||
|
onClick = {
|
||||||
onRename(name)
|
onRename(name)
|
||||||
onDismissRequest()
|
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,10 +64,12 @@ fun DeleteLibraryMangaDialog(
|
|||||||
list.forEach { state ->
|
list.forEach { state ->
|
||||||
val onCheck = {
|
val onCheck = {
|
||||||
val index = list.indexOf(state)
|
val index = list.indexOf(state)
|
||||||
|
if (index != -1) {
|
||||||
val mutableList = list.toMutableList()
|
val mutableList = list.toMutableList()
|
||||||
mutableList[index] = state.next() as CheckboxState.State<Int>
|
mutableList[index] = state.next() as CheckboxState.State<Int>
|
||||||
list = mutableList.toList()
|
list = mutableList.toList()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -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