2
.github/workflows/build_pull_request.yml
vendored
|
@ -36,4 +36,4 @@ jobs:
|
|||
- name: Build app and run unit tests
|
||||
uses: gradle/gradle-command-action@v2
|
||||
with:
|
||||
arguments: assembleStandardRelease testStandardReleaseUnitTest
|
||||
arguments: lintKotlin assembleStandardRelease testStandardReleaseUnitTest
|
2
.github/workflows/build_push.yml
vendored
|
@ -32,7 +32,7 @@ jobs:
|
|||
- name: Build app and run unit tests
|
||||
uses: gradle/gradle-command-action@v2
|
||||
with:
|
||||
arguments: assembleStandardRelease testStandardReleaseUnitTest
|
||||
arguments: lintKotlin assembleStandardRelease testStandardReleaseUnitTest
|
||||
|
||||
# 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.jmailen.gradle.kotlinter.tasks.LintTask
|
||||
|
||||
|
@ -8,7 +7,6 @@ plugins {
|
|||
kotlin("android")
|
||||
kotlin("plugin.serialization")
|
||||
id("com.github.zellius.shortcut-helper")
|
||||
id("com.squareup.sqldelight")
|
||||
}
|
||||
|
||||
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
|
||||
|
@ -22,13 +20,9 @@ val SUPPORTED_ABIS = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
|||
|
||||
android {
|
||||
namespace = "eu.kanade.tachiyomi"
|
||||
compileSdk = AndroidConfig.compileSdk
|
||||
ndkVersion = AndroidConfig.ndk
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "xyz.jmir.tachiyomi.mi"
|
||||
minSdk = AndroidConfig.minSdk
|
||||
targetSdk = AndroidConfig.targetSdk
|
||||
versionCode = 94
|
||||
versionName = "0.14.3"
|
||||
|
||||
|
@ -142,38 +136,13 @@ android {
|
|||
composeOptions {
|
||||
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"
|
||||
sourceFolders = listOf("sqldelight")
|
||||
}
|
||||
database("AnimeDatabase") {
|
||||
packageName = "eu.kanade.tachiyomi.mi"
|
||||
dialect = "sqlite:3.24"
|
||||
sourceFolders = listOf("sqldelightanime")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":i18n"))
|
||||
implementation(project(":core"))
|
||||
implementation(project(":source-api"))
|
||||
|
||||
coreLibraryDesugaring(libs.desugar)
|
||||
implementation(project(":data"))
|
||||
|
||||
// Compose
|
||||
implementation(platform(compose.bom))
|
||||
|
@ -196,9 +165,6 @@ dependencies {
|
|||
implementation(androidx.paging.compose)
|
||||
|
||||
implementation(libs.bundles.sqlite)
|
||||
implementation(libs.sqldelight.android.driver)
|
||||
implementation(libs.sqldelight.coroutines)
|
||||
implementation(libs.sqldelight.android.paging)
|
||||
|
||||
implementation(kotlinx.reflect)
|
||||
|
||||
|
@ -323,12 +289,6 @@ androidComponents {
|
|||
}
|
||||
|
||||
tasks {
|
||||
withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
withType<LintTask>().configureEach {
|
||||
exclude { it.file.path.contains("generated[\\\\/]".toRegex()) }
|
||||
|
@ -366,11 +326,6 @@ tasks {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
preBuild {
|
||||
val ktlintTask = if (System.getenv("GITHUB_BASE_REF") == null) formatKotlin else lintKotlin
|
||||
dependsOn(ktlintTask)
|
||||
}
|
||||
}
|
||||
|
||||
buildscript {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.data.category.anime
|
||||
|
||||
import eu.kanade.data.category.categoryMapper
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.category.anime.repository.AnimeCategoryRepository
|
||||
import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.domain.category.model.CategoryUpdate
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
|
||||
class AnimeCategoryRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.data.category.manga
|
||||
|
||||
import eu.kanade.data.category.categoryMapper
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.category.manga.repository.MangaCategoryRepository
|
||||
import eu.kanade.domain.category.model.Category
|
||||
import eu.kanade.domain.category.model.CategoryUpdate
|
||||
import eu.kanade.tachiyomi.Database
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.Database
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaCategoryRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package eu.kanade.data.entries.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.data.listOfStringsAdapter
|
||||
import eu.kanade.data.updateStrategyAdapter
|
||||
import eu.kanade.domain.entries.anime.model.Anime
|
||||
import eu.kanade.domain.entries.anime.model.AnimeUpdate
|
||||
import eu.kanade.domain.entries.anime.repository.AnimeRepository
|
||||
|
@ -11,6 +8,9 @@ import eu.kanade.tachiyomi.util.system.logcat
|
|||
import eu.kanade.tachiyomi.util.system.toLong
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import tachiyomi.data.listOfStringsAdapter
|
||||
import tachiyomi.data.updateStrategyAdapter
|
||||
|
||||
class AnimeRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package eu.kanade.data.entries.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.data.listOfStringsAdapter
|
||||
import eu.kanade.data.updateStrategyAdapter
|
||||
import eu.kanade.domain.entries.manga.model.Manga
|
||||
import eu.kanade.domain.entries.manga.model.MangaUpdate
|
||||
import eu.kanade.domain.entries.manga.repository.MangaRepository
|
||||
|
@ -11,6 +8,9 @@ import eu.kanade.tachiyomi.util.system.logcat
|
|||
import eu.kanade.tachiyomi.util.system.toLong
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
import tachiyomi.data.listOfStringsAdapter
|
||||
import tachiyomi.data.updateStrategyAdapter
|
||||
|
||||
class MangaRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.data.history.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.history.anime.model.AnimeHistoryUpdate
|
||||
import eu.kanade.domain.history.anime.model.AnimeHistoryWithRelations
|
||||
import eu.kanade.domain.history.anime.repository.AnimeHistoryRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class AnimeHistoryRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package eu.kanade.data.history.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.history.manga.model.MangaHistoryUpdate
|
||||
import eu.kanade.domain.history.manga.model.MangaHistoryWithRelations
|
||||
import eu.kanade.domain.history.manga.repository.MangaHistoryRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaHistoryRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.data.items.chapter
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.items.chapter.model.Chapter
|
||||
import eu.kanade.domain.items.chapter.model.ChapterUpdate
|
||||
import eu.kanade.domain.items.chapter.repository.ChapterRepository
|
||||
|
@ -8,6 +7,7 @@ import eu.kanade.tachiyomi.util.system.logcat
|
|||
import eu.kanade.tachiyomi.util.system.toLong
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class ChapterRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.data.items.episode
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.items.episode.model.Episode
|
||||
import eu.kanade.domain.items.episode.model.EpisodeUpdate
|
||||
import eu.kanade.domain.items.episode.repository.EpisodeRepository
|
||||
|
@ -8,6 +7,7 @@ import eu.kanade.tachiyomi.util.system.logcat
|
|||
import eu.kanade.tachiyomi.util.system.toLong
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class EpisodeRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.source.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.source.anime.model.AnimeSourceData
|
||||
import eu.kanade.domain.source.anime.repository.AnimeSourceDataRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class AnimeSourceDataRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.data.source.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.source.anime.model.AnimeSource
|
||||
import eu.kanade.domain.source.anime.model.AnimeSourcePagingSourceType
|
||||
import eu.kanade.domain.source.anime.model.AnimeSourceWithCount
|
||||
|
@ -11,6 +10,7 @@ import eu.kanade.tachiyomi.source.anime.AnimeSourceManager
|
|||
import eu.kanade.tachiyomi.source.anime.LocalAnimeSource
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class AnimeSourceRepositoryImpl(
|
||||
private val sourceManager: AnimeSourceManager,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.source.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.source.manga.model.MangaSourceData
|
||||
import eu.kanade.domain.source.manga.repository.MangaSourceDataRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaSourceDataRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.data.source.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.source.manga.model.MangaSourceWithCount
|
||||
import eu.kanade.domain.source.manga.model.Source
|
||||
import eu.kanade.domain.source.manga.model.SourcePagingSourceType
|
||||
|
@ -11,6 +10,7 @@ import eu.kanade.tachiyomi.source.manga.MangaSourceManager
|
|||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaSourceRepositoryImpl(
|
||||
private val sourceManager: MangaSourceManager,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.track.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.track.anime.model.AnimeTrack
|
||||
import eu.kanade.domain.track.anime.repository.AnimeTrackRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class AnimeTrackRepositoryImpl(
|
||||
private val handler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.track.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.track.manga.model.MangaTrack
|
||||
import eu.kanade.domain.track.manga.repository.MangaTrackRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaTrackRepositoryImpl(
|
||||
private val handler: MangaDatabaseHandler,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.updates.anime
|
||||
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.updates.anime.model.AnimeUpdatesWithRelations
|
||||
import eu.kanade.domain.updates.anime.repository.AnimeUpdatesRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
|
||||
class AnimeUpdatesRepositoryImpl(
|
||||
private val databaseHandler: AnimeDatabaseHandler,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.updates.manga
|
||||
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.updates.manga.model.MangaUpdatesWithRelations
|
||||
import eu.kanade.domain.updates.manga.repository.MangaUpdatesRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
|
||||
class MangaUpdatesRepositoryImpl(
|
||||
private val databaseHandler: MangaDatabaseHandler,
|
||||
|
|
|
@ -4,9 +4,6 @@ import android.content.Context
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
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
|
||||
|
||||
class BasePreferences(
|
||||
val context: Context,
|
||||
|
@ -21,10 +18,7 @@ class BasePreferences(
|
|||
|
||||
fun automaticExtUpdates() = preferenceStore.getBoolean("automatic_ext_updates", true)
|
||||
|
||||
fun extensionInstaller() = preferenceStore.getEnum(
|
||||
"extension_installer",
|
||||
if (DeviceUtil.isMiui) PreferenceValues.ExtensionInstaller.LEGACY else PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER,
|
||||
)
|
||||
fun extensionInstaller() = ExtensionInstallerPreference(context, preferenceStore)
|
||||
|
||||
// acra is disabled
|
||||
fun acraEnabled() = preferenceStore.getBoolean("acra.enable", false)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package eu.kanade.domain.base
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.core.preference.Preference
|
||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
||||
import eu.kanade.tachiyomi.core.preference.getEnum
|
||||
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
|
||||
|
||||
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,7 +1,6 @@
|
|||
package eu.kanade.presentation.browse.anime
|
||||
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
@ -30,7 +29,6 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
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.LoadingScreen
|
||||
import eu.kanade.presentation.components.PullRefresh
|
||||
import eu.kanade.presentation.components.WarningBanner
|
||||
import eu.kanade.presentation.entries.DotSeparatorNoSpaceText
|
||||
import eu.kanade.presentation.util.padding
|
||||
import eu.kanade.presentation.util.plus
|
||||
|
@ -54,7 +51,6 @@ import eu.kanade.tachiyomi.extension.InstallStep
|
|||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.ui.browse.anime.extension.AnimeExtensionUiModel
|
||||
import eu.kanade.tachiyomi.ui.browse.anime.extension.AnimeExtensionsState
|
||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
|
||||
@Composable
|
||||
|
@ -122,29 +118,10 @@ private fun AnimeExtensionContent(
|
|||
onClickUpdateAll: () -> Unit,
|
||||
) {
|
||||
var trustState by remember { mutableStateOf<AnimeExtension.Untrusted?>(null) }
|
||||
val showMiuiWarning = DeviceUtil.isMiui && DeviceUtil.miuiMajorVersion >= 13 && !DeviceUtil.isMiuiOptimizationDisabled()
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
FastScrollLazyColumn(
|
||||
contentPadding = if (showMiuiWarning) {
|
||||
contentPadding
|
||||
} else {
|
||||
contentPadding + topSmallPaddingValues
|
||||
},
|
||||
contentPadding = contentPadding + topSmallPaddingValues,
|
||||
) {
|
||||
if (showMiuiWarning) {
|
||||
item {
|
||||
WarningBanner(
|
||||
textRes = R.string.ext_miui_warning,
|
||||
modifier = Modifier
|
||||
.padding(bottom = MaterialTheme.padding.small)
|
||||
.clickable {
|
||||
uriHandler.openUri("https://tachiyomi.org/extensions")
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
state.items.forEach { (header, items) ->
|
||||
item(
|
||||
contentType = "header",
|
||||
|
|
|
@ -31,6 +31,7 @@ import eu.kanade.domain.source.anime.model.AnimeSource
|
|||
import eu.kanade.presentation.util.rememberResourceBitmapPainter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.source.anime.LocalAnimeSource
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
|
||||
private val defaultModifier = Modifier
|
||||
|
@ -60,13 +61,20 @@ fun AnimeSourceIcon(
|
|||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
source.id == LocalAnimeSource.ID -> {
|
||||
Image(
|
||||
painter = painterResource(R.mipmap.ic_local_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Image(
|
||||
painter = painterResource(R.mipmap.ic_default_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,17 +98,17 @@ fun AnimeExtensionIcon(
|
|||
is AnimeExtension.Installed -> {
|
||||
val icon by extension.getIcon(density)
|
||||
when (icon) {
|
||||
is Result.Error -> Image(
|
||||
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_local_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
is Result.Loading -> Box(modifier = modifier)
|
||||
is Result.Success -> Image(
|
||||
bitmap = (icon as Result.Success<ImageBitmap>).value,
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
Result.Error -> Image(
|
||||
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_default_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
is AnimeExtension.Untrusted -> Image(
|
||||
|
|
|
@ -2,7 +2,6 @@ package eu.kanade.presentation.browse.manga
|
|||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
@ -32,7 +31,6 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
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.LoadingScreen
|
||||
import eu.kanade.presentation.components.PullRefresh
|
||||
import eu.kanade.presentation.components.WarningBanner
|
||||
import eu.kanade.presentation.entries.DotSeparatorNoSpaceText
|
||||
import eu.kanade.presentation.theme.header
|
||||
import eu.kanade.presentation.util.padding
|
||||
|
@ -55,7 +52,6 @@ import eu.kanade.tachiyomi.extension.InstallStep
|
|||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import eu.kanade.tachiyomi.ui.browse.manga.extension.MangaExtensionUiModel
|
||||
import eu.kanade.tachiyomi.ui.browse.manga.extension.MangaExtensionsState
|
||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
|
||||
@Composable
|
||||
|
@ -123,29 +119,10 @@ private fun ExtensionContent(
|
|||
onClickUpdateAll: () -> Unit,
|
||||
) {
|
||||
var trustState by remember { mutableStateOf<MangaExtension.Untrusted?>(null) }
|
||||
val showMiuiWarning = DeviceUtil.isMiui && DeviceUtil.miuiMajorVersion >= 13 && !DeviceUtil.isMiuiOptimizationDisabled()
|
||||
val uriHandler = LocalUriHandler.current
|
||||
|
||||
FastScrollLazyColumn(
|
||||
contentPadding = if (showMiuiWarning) {
|
||||
contentPadding
|
||||
} else {
|
||||
contentPadding + topSmallPaddingValues
|
||||
},
|
||||
contentPadding = contentPadding + topSmallPaddingValues,
|
||||
) {
|
||||
if (showMiuiWarning) {
|
||||
item {
|
||||
WarningBanner(
|
||||
textRes = R.string.ext_miui_warning,
|
||||
modifier = Modifier
|
||||
.padding(bottom = MaterialTheme.padding.small)
|
||||
.clickable {
|
||||
uriHandler.openUri("https://tachiyomi.org/extensions")
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
state.items.forEach { (header, items) ->
|
||||
item(
|
||||
contentType = "header",
|
||||
|
|
|
@ -31,6 +31,7 @@ import eu.kanade.domain.source.manga.model.Source
|
|||
import eu.kanade.presentation.util.rememberResourceBitmapPainter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import eu.kanade.tachiyomi.source.manga.LocalMangaSource
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
|
||||
private val defaultModifier = Modifier
|
||||
|
@ -60,13 +61,20 @@ fun MangaSourceIcon(
|
|||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
source.id == LocalMangaSource.ID -> {
|
||||
Image(
|
||||
painter = painterResource(R.mipmap.ic_local_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Image(
|
||||
painter = painterResource(R.mipmap.ic_default_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier.then(defaultModifier),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,17 +98,17 @@ fun MangaExtensionIcon(
|
|||
is MangaExtension.Installed -> {
|
||||
val icon by extension.getIcon(density)
|
||||
when (icon) {
|
||||
Result.Error -> Image(
|
||||
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_local_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
Result.Loading -> Box(modifier = modifier)
|
||||
is Result.Success -> Image(
|
||||
bitmap = (icon as Result.Success<ImageBitmap>).value,
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
Result.Error -> Image(
|
||||
bitmap = ImageBitmap.imageResource(id = R.mipmap.ic_default_source),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
is MangaExtension.Untrusted -> Image(
|
||||
|
|
|
@ -47,13 +47,13 @@ import eu.kanade.presentation.components.LoadingScreen
|
|||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.util.selectedBackground
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.update
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ import eu.kanade.presentation.components.FastScrollLazyColumn
|
|||
import eu.kanade.presentation.components.LoadingScreen
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.util.selectedBackground
|
||||
import eu.kanade.tachiyomi.Database
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
|
@ -54,6 +53,7 @@ import eu.kanade.tachiyomi.util.lang.withNonCancellableContext
|
|||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.update
|
||||
import tachiyomi.data.Database
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
|
|
|
@ -54,8 +54,7 @@ import eu.kanade.tachiyomi.network.PREF_DOH_SHECAN
|
|||
import eu.kanade.tachiyomi.util.CrashLogUtil
|
||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||
import eu.kanade.tachiyomi.util.system.isPackageInstalled
|
||||
import eu.kanade.tachiyomi.util.system.isShizukuInstalled
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.powerManager
|
||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
||||
|
@ -63,7 +62,6 @@ import eu.kanade.tachiyomi.util.system.toast
|
|||
import kotlinx.coroutines.launch
|
||||
import logcat.LogPriority
|
||||
import okhttp3.Headers
|
||||
import rikka.sui.Sui
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
@ -354,6 +352,7 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||
): Preference.PreferenceGroup {
|
||||
val context = LocalContext.current
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val extensionInstallerPref = basePreferences.extensionInstaller()
|
||||
var shizukuMissing by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
if (shizukuMissing) {
|
||||
|
@ -383,19 +382,13 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||
title = stringResource(R.string.label_extensions),
|
||||
preferenceItems = listOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = basePreferences.extensionInstaller(),
|
||||
pref = extensionInstallerPref,
|
||||
title = stringResource(R.string.ext_installer_pref),
|
||||
entries = PreferenceValues.ExtensionInstaller.values()
|
||||
.run {
|
||||
if (DeviceUtil.isMiui) {
|
||||
filter { it != PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER }
|
||||
} else {
|
||||
toList()
|
||||
}
|
||||
}.associateWith { stringResource(it.titleResId) },
|
||||
entries = extensionInstallerPref.entries
|
||||
.associateWith { stringResource(it.titleResId) },
|
||||
onValueChanged = {
|
||||
if (it == PreferenceValues.ExtensionInstaller.SHIZUKU &&
|
||||
!(context.isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui())
|
||||
!context.isShizukuInstalled
|
||||
) {
|
||||
shizukuMissing = true
|
||||
false
|
||||
|
|
|
@ -24,8 +24,6 @@ import coil.decode.GifDecoder
|
|||
import coil.decode.ImageDecoderDecoder
|
||||
import coil.disk.DiskCache
|
||||
import coil.util.DebugLogger
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.DomainModule
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
|
@ -60,6 +58,8 @@ import logcat.AndroidLogcatLogger
|
|||
import logcat.LogPriority
|
||||
import logcat.LogcatLogger
|
||||
import org.conscrypt.Conscrypt
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
|
|
@ -10,13 +10,6 @@ import data.History
|
|||
import data.Mangas
|
||||
import dataanime.Animehistory
|
||||
import dataanime.Animes
|
||||
import eu.kanade.data.dateAdapter
|
||||
import eu.kanade.data.handlers.anime.AndroidAnimeDatabaseHandler
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.data.handlers.manga.AndroidMangaDatabaseHandler
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.data.listOfStringsAdapter
|
||||
import eu.kanade.data.updateStrategyAdapter
|
||||
import eu.kanade.domain.backup.service.BackupPreferences
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.download.service.DownloadPreferences
|
||||
|
@ -45,7 +38,6 @@ import eu.kanade.tachiyomi.data.saver.ImageSaver
|
|||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import eu.kanade.tachiyomi.network.JavaScriptEngine
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||
|
@ -61,6 +53,15 @@ import nl.adaptivity.xmlutil.XmlDeclMode
|
|||
import nl.adaptivity.xmlutil.core.XmlVersion
|
||||
import nl.adaptivity.xmlutil.serialization.UnknownChildHandler
|
||||
import nl.adaptivity.xmlutil.serialization.XML
|
||||
import tachiyomi.data.Database
|
||||
import tachiyomi.data.dateAdapter
|
||||
import tachiyomi.data.handlers.anime.AndroidAnimeDatabaseHandler
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import tachiyomi.data.handlers.manga.AndroidMangaDatabaseHandler
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
import tachiyomi.data.listOfStringsAdapter
|
||||
import tachiyomi.data.updateStrategyAdapter
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
import uy.kohesive.injekt.api.InjektModule
|
||||
import uy.kohesive.injekt.api.InjektRegistrar
|
||||
import uy.kohesive.injekt.api.addSingleton
|
||||
|
|
|
@ -10,9 +10,6 @@ import data.Manga_sync
|
|||
import data.Mangas
|
||||
import dataanime.Anime_sync
|
||||
import dataanime.Animes
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.data.updateStrategyAdapter
|
||||
import eu.kanade.domain.backup.service.BackupPreferences
|
||||
import eu.kanade.domain.category.anime.interactor.GetAnimeCategories
|
||||
import eu.kanade.domain.category.manga.interactor.GetMangaCategories
|
||||
|
@ -72,6 +69,9 @@ import logcat.LogPriority
|
|||
import okio.buffer
|
||||
import okio.gzip
|
||||
import okio.sink
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
import tachiyomi.data.updateStrategyAdapter
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.FileOutputStream
|
||||
|
|
|
@ -334,7 +334,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||
val obj = response.jsonObject
|
||||
return track.apply {
|
||||
val isRereading = obj["is_rereading"]!!.jsonPrimitive.boolean
|
||||
status = if (isRereading) MyAnimeList.REREADING else getStatus(obj["status"]!!.jsonPrimitive.content)
|
||||
status = if (isRereading) MyAnimeList.REREADING else getStatus(obj["status"]?.jsonPrimitive?.content)
|
||||
last_chapter_read = obj["num_chapters_read"]!!.jsonPrimitive.float
|
||||
score = obj["score"]!!.jsonPrimitive.int.toFloat()
|
||||
obj["start_date"]?.let {
|
||||
|
|
|
@ -38,7 +38,7 @@ fun AnimeTrack.toMyAnimeListStatus() = when (status) {
|
|||
else -> null
|
||||
}
|
||||
|
||||
fun getStatus(status: String) = when (status) {
|
||||
fun getStatus(status: String?) = when (status) {
|
||||
"reading" -> MyAnimeList.READING
|
||||
"watching" -> MyAnimeList.WATCHING
|
||||
"completed" -> MyAnimeList.COMPLETED
|
||||
|
|
|
@ -5,9 +5,11 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
/**
|
||||
* Activity used to install extensions, because we can only receive the result of the installation
|
||||
|
@ -15,6 +17,11 @@ import uy.kohesive.injekt.api.get
|
|||
*/
|
||||
class AnimeExtensionInstallActivity : Activity() {
|
||||
|
||||
// MIUI package installer bug workaround
|
||||
private var ignoreUntil = 0L
|
||||
private var ignoreResult = false
|
||||
private var hasIgnoredResult = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
@ -23,6 +30,11 @@ class AnimeExtensionInstallActivity : Activity() {
|
|||
.putExtra(Intent.EXTRA_RETURN_RESULT, true)
|
||||
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
if (hasMiuiPackageInstaller) {
|
||||
ignoreResult = true
|
||||
ignoreUntil = System.nanoTime() + 1.seconds.inWholeNanoseconds
|
||||
}
|
||||
|
||||
try {
|
||||
startActivityForResult(installIntent, INSTALL_REQUEST_CODE)
|
||||
} catch (error: Exception) {
|
||||
|
@ -33,12 +45,24 @@ class AnimeExtensionInstallActivity : Activity() {
|
|||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (ignoreResult && System.nanoTime() < ignoreUntil) {
|
||||
hasIgnoredResult = true
|
||||
return
|
||||
}
|
||||
if (requestCode == INSTALL_REQUEST_CODE) {
|
||||
checkInstallationResult(resultCode)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (hasIgnoredResult) {
|
||||
checkInstallationResult(RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkInstallationResult(resultCode: Int) {
|
||||
val downloadId = intent.extras!!.getLong(AnimeExtensionInstaller.EXTRA_DOWNLOAD_ID)
|
||||
val extensionManager = Injekt.get<AnimeExtensionManager>()
|
||||
|
|
|
@ -5,9 +5,11 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.util.system.hasMiuiPackageInstaller
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
/**
|
||||
* Activity used to install extensions, because we can only receive the result of the installation
|
||||
|
@ -15,6 +17,11 @@ import uy.kohesive.injekt.api.get
|
|||
*/
|
||||
class MangaExtensionInstallActivity : Activity() {
|
||||
|
||||
// MIUI package installer bug workaround
|
||||
private var ignoreUntil = 0L
|
||||
private var ignoreResult = false
|
||||
private var hasIgnoredResult = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
|
@ -23,6 +30,11 @@ class MangaExtensionInstallActivity : Activity() {
|
|||
.putExtra(Intent.EXTRA_RETURN_RESULT, true)
|
||||
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
if (hasMiuiPackageInstaller) {
|
||||
ignoreResult = true
|
||||
ignoreUntil = System.nanoTime() + 1.seconds.inWholeNanoseconds
|
||||
}
|
||||
|
||||
try {
|
||||
startActivityForResult(installIntent, INSTALL_REQUEST_CODE)
|
||||
} catch (error: Exception) {
|
||||
|
@ -33,12 +45,24 @@ class MangaExtensionInstallActivity : Activity() {
|
|||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (ignoreResult && System.nanoTime() < ignoreUntil) {
|
||||
hasIgnoredResult = true
|
||||
return
|
||||
}
|
||||
if (requestCode == INSTALL_REQUEST_CODE) {
|
||||
checkInstallationResult(resultCode)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
if (hasIgnoredResult) {
|
||||
checkInstallationResult(RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkInstallationResult(resultCode: Int) {
|
||||
val downloadId = intent.extras!!.getLong(MangaExtensionInstaller.EXTRA_DOWNLOAD_ID)
|
||||
val extensionManager = Injekt.get<MangaExtensionManager>()
|
||||
|
|
|
@ -40,7 +40,6 @@ import coil.request.ImageRequest
|
|||
import coil.size.Precision
|
||||
import coil.size.Scale
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import eu.kanade.data.handlers.anime.AnimeDatabaseHandler
|
||||
import eu.kanade.domain.entries.anime.model.AnimeCover
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.core.security.SecurityPreferences
|
||||
|
@ -55,6 +54,7 @@ import eu.kanade.tachiyomi.util.Constants
|
|||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import kotlinx.coroutines.MainScope
|
||||
import tachiyomi.data.handlers.anime.AnimeDatabaseHandler
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
|
|
@ -41,7 +41,6 @@ import coil.request.ImageRequest
|
|||
import coil.size.Precision
|
||||
import coil.size.Scale
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import eu.kanade.data.handlers.manga.MangaDatabaseHandler
|
||||
import eu.kanade.domain.entries.manga.model.MangaCover
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.core.security.SecurityPreferences
|
||||
|
@ -55,6 +54,7 @@ import eu.kanade.tachiyomi.util.Constants
|
|||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import kotlinx.coroutines.MainScope
|
||||
import tachiyomi.data.handlers.manga.MangaDatabaseHandler
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
|
|
@ -17,7 +17,7 @@ fun SAnime.copyFrom(other: Animes) {
|
|||
}
|
||||
|
||||
if (other.genre != null) {
|
||||
genre = other.genre.joinToString(separator = ", ")
|
||||
genre = other.genre!!.joinToString(separator = ", ")
|
||||
}
|
||||
|
||||
if (other.thumbnail_url != null) {
|
||||
|
|
|
@ -17,7 +17,7 @@ fun SManga.copyFrom(other: Mangas) {
|
|||
}
|
||||
|
||||
if (other.genre != null) {
|
||||
genre = other.genre.joinToString(separator = ", ")
|
||||
genre = other.genre!!.joinToString(separator = ", ")
|
||||
}
|
||||
|
||||
if (other.thumbnail_url != null) {
|
||||
|
|
|
@ -50,6 +50,7 @@ import eu.kanade.tachiyomi.R
|
|||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.databinding.ReaderActivityBinding
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderViewModel.SetAsCoverResult.AddToLibraryFirst
|
||||
|
@ -315,6 +316,8 @@ class ReaderActivity : BaseActivity() {
|
|||
menu.findItem(R.id.action_bookmark).isVisible = !isChapterBookmarked
|
||||
menu.findItem(R.id.action_remove_bookmark).isVisible = isChapterBookmarked
|
||||
|
||||
menu.findItem(R.id.action_open_in_web_view).isVisible = viewModel.getSource() is HttpSource
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1028,10 +1031,10 @@ class ReaderActivity : BaseActivity() {
|
|||
.onEach { theme ->
|
||||
binding.readerContainer.setBackgroundResource(
|
||||
when (theme) {
|
||||
0 -> android.R.color.white
|
||||
0 -> R.color.md_white_1000
|
||||
2 -> R.color.reader_background_dark
|
||||
3 -> automaticBackgroundColor()
|
||||
else -> android.R.color.black
|
||||
else -> R.color.md_black_1000
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -1086,7 +1089,7 @@ class ReaderActivity : BaseActivity() {
|
|||
return if (baseContext.isNightMode()) {
|
||||
R.color.reader_background_dark
|
||||
} else {
|
||||
android.R.color.white
|
||||
R.color.md_white_1000
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
|
|||
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
|
||||
import eu.kanade.tachiyomi.util.lang.truncateCenter
|
||||
import logcat.LogPriority
|
||||
import rikka.sui.Sui
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
@ -348,6 +349,10 @@ fun Context.isPackageInstalled(packageName: String): Boolean {
|
|||
}
|
||||
}
|
||||
|
||||
val Context.hasMiuiPackageInstaller get() = isPackageInstalled("com.miui.packageinstaller")
|
||||
|
||||
val Context.isShizukuInstalled get() = isPackageInstalled("moe.shizuku.privileged.api") || Sui.isSui()
|
||||
|
||||
fun Context.isInstalledFromFDroid(): Boolean {
|
||||
val installerPackageName = try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
|
|
BIN
app/src/main/res/mipmap-hdpi/ic_default_source.webp
Normal file
After Width: | Height: | Size: 882 B |
Before Width: | Height: | Size: 882 B After Width: | Height: | Size: 1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_default_source.webp
Normal file
After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 610 B |
BIN
app/src/main/res/mipmap-xhdpi/ic_default_source.webp
Normal file
After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_default_source.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_default_source.webp
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.5 KiB |
|
@ -1,32 +1,58 @@
|
|||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.BasePlugin
|
||||
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath(libs.android.shortcut.gradle)
|
||||
classpath(libs.google.services.gradle)
|
||||
classpath(libs.google.crashlytics.gradle)
|
||||
classpath(libs.aboutLibraries.gradle)
|
||||
classpath(kotlinx.serialization.gradle)
|
||||
classpath(libs.sqldelight.gradle)
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
alias(androidx.plugins.application) apply false
|
||||
alias(androidx.plugins.library) apply false
|
||||
alias(androidx.plugins.test) apply false
|
||||
alias(kotlinx.plugins.android) apply false
|
||||
alias(libs.plugins.kotlinter)
|
||||
alias(kotlinx.plugins.serialization) apply false
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply<org.jmailen.gradle.kotlinter.KotlinterPlugin>()
|
||||
tasks.withType<KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
}
|
||||
|
||||
kotlinter {
|
||||
experimentalRules = true
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
disabledRules = arrayOf(
|
||||
"experimental:argument-list-wrapping", // Doesn't play well with Android Studio
|
||||
"filename", // Often broken to give a more general name
|
||||
)
|
||||
plugins.withType<BasePlugin> {
|
||||
plugins.apply("tachiyomi.lint")
|
||||
configure<BaseExtension> {
|
||||
compileSdkVersion(AndroidConfig.compileSdk)
|
||||
defaultConfig {
|
||||
minSdk = AndroidConfig.minSdk
|
||||
targetSdk = AndroidConfig.targetSdk
|
||||
ndk {
|
||||
version = AndroidConfig.ndk
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
add("coreLibraryDesugaring", libs.desugar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinLibs.versions.kotlin.version.get()}")
|
||||
implementation(androidxLibs.gradle)
|
||||
|
||||
implementation(kotlinLibs.gradle)
|
||||
implementation(libs.kotlinter)
|
||||
implementation(gradleApi())
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
create("androidxLibs") {
|
||||
from(files("../gradle/androidx.versions.toml"))
|
||||
}
|
||||
create("kotlinLibs") {
|
||||
from(files("../gradle/kotlinx.versions.toml"))
|
||||
}
|
||||
|
|
21
buildSrc/src/main/kotlin/tachiyomi.lint.gradle.kts
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
import org.jmailen.gradle.kotlinter.KotlinterExtension
|
||||
import org.jmailen.gradle.kotlinter.KotlinterPlugin
|
||||
|
||||
apply<KotlinterPlugin>()
|
||||
|
||||
extensions.configure<KotlinterExtension>("kotlinter") {
|
||||
experimentalRules = true
|
||||
|
||||
disabledRules = arrayOf(
|
||||
"experimental:argument-list-wrapping", // Doesn't play well with Android Studio
|
||||
"filename", // Often broken to give a more general name
|
||||
)
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<DefaultTask>("preBuild").configure {
|
||||
if (!System.getenv("CI").toBoolean())
|
||||
dependsOn("formatKotlin")
|
||||
}
|
||||
}
|
|
@ -6,21 +6,6 @@ plugins {
|
|||
|
||||
android {
|
||||
namespace = "eu.kanade.tachiyomi.core"
|
||||
compileSdk = AndroidConfig.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
minSdk = AndroidConfig.minSdk
|
||||
targetSdk = AndroidConfig.targetSdk
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
1
data/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
33
data/build.gradle.kts
Normal file
|
@ -0,0 +1,33 @@
|
|||
plugins {
|
||||
id("com.android.library")
|
||||
kotlin("android")
|
||||
id("com.squareup.sqldelight")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "tachiyomi.data"
|
||||
|
||||
defaultConfig {
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
sqldelight {
|
||||
database("Database") {
|
||||
packageName = "tachiyomi.data"
|
||||
dialect = "sqlite:3.24"
|
||||
sourceFolders = listOf("sqldelight")
|
||||
}
|
||||
database("AnimeDatabase") {
|
||||
packageName = "tachiyomi.mi.data"
|
||||
dialect = "sqlite:3.24"
|
||||
sourceFolders = listOf("sqldelightanime")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":source-api"))
|
||||
api(libs.sqldelight.android.driver)
|
||||
api(libs.sqldelight.coroutines)
|
||||
api(libs.sqldelight.android.paging)
|
||||
}
|
0
data/consumer-rules.pro
Normal file
21
data/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
4
data/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.data
|
||||
package tachiyomi.data
|
||||
|
||||
import com.squareup.sqldelight.ColumnAdapter
|
||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.data.handlers.anime
|
||||
package tachiyomi.data.handlers.anime
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import com.squareup.sqldelight.Query
|
||||
|
@ -7,11 +7,11 @@ import com.squareup.sqldelight.runtime.coroutines.asFlow
|
|||
import com.squareup.sqldelight.runtime.coroutines.mapToList
|
||||
import com.squareup.sqldelight.runtime.coroutines.mapToOne
|
||||
import com.squareup.sqldelight.runtime.coroutines.mapToOneOrNull
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
|
||||
class AndroidAnimeDatabaseHandler(
|
||||
val db: AnimeDatabase,
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.handlers.anime
|
||||
package tachiyomi.data.handlers.anime
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import com.squareup.sqldelight.Query
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
|
||||
interface AnimeDatabaseHandler {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.data.handlers.anime
|
||||
package tachiyomi.data.handlers.anime
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Job
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.handlers.anime
|
||||
package tachiyomi.data.handlers.anime
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import com.squareup.sqldelight.Query
|
||||
import eu.kanade.tachiyomi.mi.AnimeDatabase
|
||||
import tachiyomi.mi.data.AnimeDatabase
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class QueryPagingAnimeSource<RowType : Any>(
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.data.handlers.manga
|
||||
package tachiyomi.data.handlers.manga
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import com.squareup.sqldelight.Query
|
||||
|
@ -7,11 +7,11 @@ import com.squareup.sqldelight.runtime.coroutines.asFlow
|
|||
import com.squareup.sqldelight.runtime.coroutines.mapToList
|
||||
import com.squareup.sqldelight.runtime.coroutines.mapToOne
|
||||
import com.squareup.sqldelight.runtime.coroutines.mapToOneOrNull
|
||||
import eu.kanade.tachiyomi.Database
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import tachiyomi.data.Database
|
||||
|
||||
class AndroidMangaDatabaseHandler(
|
||||
val db: Database,
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.handlers.manga
|
||||
package tachiyomi.data.handlers.manga
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import com.squareup.sqldelight.Query
|
||||
import eu.kanade.tachiyomi.Database
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import tachiyomi.data.Database
|
||||
|
||||
interface MangaDatabaseHandler {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package eu.kanade.data.handlers.manga
|
||||
package tachiyomi.data.handlers.manga
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Job
|
|
@ -1,9 +1,9 @@
|
|||
package eu.kanade.data.handlers.manga
|
||||
package tachiyomi.data.handlers.manga
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import com.squareup.sqldelight.Query
|
||||
import eu.kanade.tachiyomi.Database
|
||||
import tachiyomi.data.Database
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class QueryPagingMangaSource<RowType : Any>(
|