mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
feat: Extension repo backend
This commit is contained in:
parent
7c88f3895a
commit
534642ea57
12 changed files with 132 additions and 61 deletions
|
@ -35,8 +35,8 @@ android {
|
||||||
minSdk = AndroidConfig.minSdk
|
minSdk = AndroidConfig.minSdk
|
||||||
targetSdk = AndroidConfig.targetSdk
|
targetSdk = AndroidConfig.targetSdk
|
||||||
applicationId = "eu.kanade.tachiyomi"
|
applicationId = "eu.kanade.tachiyomi"
|
||||||
versionCode = 111
|
versionCode = 112
|
||||||
versionName = "1.7.4"
|
versionName = "1.7.5"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
multiDexEnabled = true
|
multiDexEnabled = true
|
||||||
|
|
||||||
|
@ -179,6 +179,7 @@ dependencies {
|
||||||
implementation(libs.firebase.crashlytics)
|
implementation(libs.firebase.crashlytics)
|
||||||
|
|
||||||
implementation(androidx.lifecycle.viewmodel)
|
implementation(androidx.lifecycle.viewmodel)
|
||||||
|
implementation(compose.lifecycle.viewmodel)
|
||||||
implementation(androidx.lifecycle.livedata)
|
implementation(androidx.lifecycle.livedata)
|
||||||
implementation(androidx.lifecycle.common)
|
implementation(androidx.lifecycle.common)
|
||||||
implementation(androidx.lifecycle.process)
|
implementation(androidx.lifecycle.process)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package dev.yokai.presentation.source
|
package dev.yokai.presentation.extension.repo
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
||||||
|
|
||||||
class SourceRepoController :
|
class ExtensionRepoController :
|
||||||
BaseComposeController() {
|
BaseComposeController() {
|
||||||
|
|
||||||
override fun getTitle(): String {
|
override fun getTitle(): String {
|
||||||
|
@ -14,7 +14,7 @@ class SourceRepoController :
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent() {
|
override fun ScreenContent() {
|
||||||
SourceRepoScreen(
|
ExtensionRepoScreen(
|
||||||
title = getTitle(),
|
title = getTitle(),
|
||||||
onBackPress = router::handleBack,
|
onBackPress = router::handleBack,
|
||||||
)
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.yokai.presentation.source
|
package dev.yokai.presentation.extension.repo
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
@ -14,7 +14,7 @@ import dev.yokai.presentation.YokaiScaffold
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SourceRepoScreen(
|
fun ExtensionRepoScreen(
|
||||||
title: String,
|
title: String,
|
||||||
onBackPress: () -> Unit,
|
onBackPress: () -> Unit,
|
||||||
) {
|
) {
|
|
@ -0,0 +1,72 @@
|
||||||
|
package dev.yokai.presentation.extension.repo
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dev.yokai.domain.source.SourcePreferences
|
||||||
|
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||||
|
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||||
|
import eu.kanade.tachiyomi.util.system.launchIO
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import okhttp3.internal.toImmutableList
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
class ExtensionRepoViewModel :
|
||||||
|
ViewModel() {
|
||||||
|
|
||||||
|
private val sourcePreferences: SourcePreferences by injectLazy()
|
||||||
|
private val _repoState: MutableStateFlow<ExtensionRepoState> = MutableStateFlow(ExtensionRepoState.Loading)
|
||||||
|
val repoState: StateFlow<ExtensionRepoState> = _repoState.asStateFlow()
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
getRepo().collectLatest { repos ->
|
||||||
|
_repoState.value = ExtensionRepoState.Success(repos = repos.toImmutableList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fun addRepo(url: String): Result {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
if (!url.matches(repoRegex))
|
||||||
|
return Result.InvalidUrl
|
||||||
|
|
||||||
|
sourcePreferences.extensionRepos() += url.substringBeforeLast("/index.min.json")
|
||||||
|
|
||||||
|
return Result.Success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fun deleteRepo(repo: String) {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
sourcePreferences.extensionRepos() -= repo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRepo() =
|
||||||
|
sourcePreferences.extensionRepos().changes()
|
||||||
|
.map { it.sortedWith(String.CASE_INSENSITIVE_ORDER) }
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class ExtensionRepoState {
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data object Loading : ExtensionRepoState()
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class Success(
|
||||||
|
val repos: List<String>,
|
||||||
|
) : ExtensionRepoState() {
|
||||||
|
|
||||||
|
val isEmpty: Boolean
|
||||||
|
get() = repos.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val repoRegex = """^https://.*/index\.min\.json$""".toRegex()
|
|
@ -4,8 +4,11 @@ import android.content.Context
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import dev.yokai.domain.source.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
import eu.kanade.tachiyomi.data.preference.minusAssign
|
||||||
|
import eu.kanade.tachiyomi.data.preference.plusAssign
|
||||||
|
import eu.kanade.tachiyomi.extension.api.ExtensionApi
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.InstallStep
|
import eu.kanade.tachiyomi.extension.model.InstallStep
|
||||||
import eu.kanade.tachiyomi.extension.model.LoadResult
|
import eu.kanade.tachiyomi.extension.model.LoadResult
|
||||||
|
@ -20,6 +23,7 @@ import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
|
@ -44,7 +48,7 @@ class ExtensionManager(
|
||||||
/**
|
/**
|
||||||
* API where all the available extensions can be found.
|
* API where all the available extensions can be found.
|
||||||
*/
|
*/
|
||||||
private val api = ExtensionGithubApi()
|
private val api = ExtensionApi()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The installer which installs, updates and uninstalls the extensions.
|
* The installer which installs, updates and uninstalls the extensions.
|
||||||
|
@ -435,6 +439,7 @@ class ExtensionManager(
|
||||||
val name: String,
|
val name: String,
|
||||||
val versionCode: Long,
|
val versionCode: Long,
|
||||||
val libVersion: Double,
|
val libVersion: Double,
|
||||||
|
val repoUrl: String? = null,
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
constructor(extension: Extension.Available) : this(
|
constructor(extension: Extension.Available) : this(
|
||||||
apkName = extension.apkName,
|
apkName = extension.apkName,
|
||||||
|
@ -442,6 +447,7 @@ class ExtensionManager(
|
||||||
name = extension.name,
|
name = extension.name,
|
||||||
versionCode = extension.versionCode,
|
versionCode = extension.versionCode,
|
||||||
libVersion = extension.libVersion,
|
libVersion = extension.libVersion,
|
||||||
|
repoUrl = extension.repoUrl,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.updater.AppDownloadInstallJob
|
import eu.kanade.tachiyomi.data.updater.AppDownloadInstallJob
|
||||||
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
import eu.kanade.tachiyomi.extension.api.ExtensionApi
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
||||||
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
||||||
|
@ -44,7 +44,7 @@ class ExtensionUpdateJob(private val context: Context, workerParams: WorkerParam
|
||||||
|
|
||||||
override suspend fun doWork(): Result = coroutineScope {
|
override suspend fun doWork(): Result = coroutineScope {
|
||||||
val pendingUpdates = try {
|
val pendingUpdates = try {
|
||||||
ExtensionGithubApi().checkForUpdates(context)
|
ExtensionApi().checkForUpdates(context)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
return@coroutineScope Result.failure()
|
return@coroutineScope Result.failure()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package eu.kanade.tachiyomi.extension.api
|
package eu.kanade.tachiyomi.extension.api
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import dev.yokai.domain.source.SourcePreferences
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import eu.kanade.tachiyomi.extension.model.LoadResult
|
import eu.kanade.tachiyomi.extension.model.LoadResult
|
||||||
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
import eu.kanade.tachiyomi.util.system.withIOContext
|
import eu.kanade.tachiyomi.util.system.withIOContext
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
@ -17,44 +18,19 @@ import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
internal class ExtensionGithubApi {
|
internal class ExtensionApi {
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
private val networkService: NetworkHelper by injectLazy()
|
private val networkService: NetworkHelper by injectLazy()
|
||||||
|
private val sourcePreferences: SourcePreferences by injectLazy()
|
||||||
private var requiresFallbackSource = false
|
|
||||||
|
|
||||||
suspend fun findExtensions(): List<Extension.Available> {
|
suspend fun findExtensions(): List<Extension.Available> {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val githubResponse = if (requiresFallbackSource) {
|
val extensions = sourcePreferences.extensionRepos().get().flatMap { getExtensions(it) }
|
||||||
null
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
networkService.client
|
|
||||||
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
|
||||||
.await()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
Timber.e(e, "Failed to get extensions from GitHub")
|
|
||||||
requiresFallbackSource = true
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val response = githubResponse ?: run {
|
|
||||||
networkService.client
|
|
||||||
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
|
|
||||||
.await()
|
|
||||||
}
|
|
||||||
|
|
||||||
val extensions = with(json) {
|
|
||||||
response
|
|
||||||
.parseAs<List<ExtensionJsonObject>>()
|
|
||||||
.toExtensions()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sanity check - a small number of extensions probably means something broke
|
// Sanity check - a small number of extensions probably means something broke
|
||||||
// with the repo generator
|
// with the repo generator
|
||||||
if (extensions.size < 100) {
|
if (extensions.size < 50) {
|
||||||
throw Exception()
|
throw Exception()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +38,25 @@ internal class ExtensionGithubApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getExtensions(
|
||||||
|
repoBaseUrl: String,
|
||||||
|
): List<Extension.Available> {
|
||||||
|
return try {
|
||||||
|
val response = networkService.client
|
||||||
|
.newCall(GET("$repoBaseUrl/index.min.json"))
|
||||||
|
.awaitSuccess()
|
||||||
|
|
||||||
|
with(json) {
|
||||||
|
response
|
||||||
|
.parseAs<List<ExtensionJsonObject>>()
|
||||||
|
.toExtensions(repoBaseUrl)
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Timber.e(e, "Failed to get extensions from $repoBaseUrl")
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun checkForUpdates(context: Context, prefetchedExtensions: List<Extension.Available>? = null): List<Extension.Available> {
|
suspend fun checkForUpdates(context: Context, prefetchedExtensions: List<Extension.Available>? = null): List<Extension.Available> {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val extensions = prefetchedExtensions ?: findExtensions()
|
val extensions = prefetchedExtensions ?: findExtensions()
|
||||||
|
@ -89,7 +84,7 @@ internal class ExtensionGithubApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<ExtensionJsonObject>.toExtensions(): List<Extension.Available> {
|
private fun List<ExtensionJsonObject>.toExtensions(repoUrl: String): List<Extension.Available> {
|
||||||
return this
|
return this
|
||||||
.filter {
|
.filter {
|
||||||
val libVersion = it.extractLibVersion()
|
val libVersion = it.extractLibVersion()
|
||||||
|
@ -108,21 +103,14 @@ internal class ExtensionGithubApi {
|
||||||
hasChangelog = it.hasChangelog == 1,
|
hasChangelog = it.hasChangelog == 1,
|
||||||
sources = it.sources ?: emptyList(),
|
sources = it.sources ?: emptyList(),
|
||||||
apkName = it.apk,
|
apkName = it.apk,
|
||||||
iconUrl = "${getUrlPrefix()}icon/${it.pkg}.png",
|
iconUrl = "${repoUrl}icon/${it.pkg}.png",
|
||||||
|
repoUrl = repoUrl,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(extension: ExtensionManager.ExtensionInfo): String {
|
fun getApkUrl(extension: ExtensionManager.ExtensionInfo): String {
|
||||||
return "${getUrlPrefix()}apk/${extension.apkName}"
|
return "${extension.repoUrl}apk/${extension.apkName}"
|
||||||
}
|
|
||||||
|
|
||||||
private fun getUrlPrefix(): String {
|
|
||||||
return if (requiresFallbackSource) {
|
|
||||||
FALLBACK_REPO_URL_PREFIX
|
|
||||||
} else {
|
|
||||||
REPO_URL_PREFIX
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ExtensionJsonObject.extractLibVersion(): Double {
|
private fun ExtensionJsonObject.extractLibVersion(): Double {
|
||||||
|
@ -130,8 +118,10 @@ internal class ExtensionGithubApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/keiyoushi/extensions/repo/"
|
private const val BASE_URL = "https://raw.githubusercontent.com/"
|
||||||
const val FALLBACK_REPO_URL_PREFIX = "https://gcore.jsdelivr.net/gh/keiyoushi/extensions@repo/"
|
private const val REPO_URL_PREFIX = "${BASE_URL}keiyoushi/extensions/repo/"
|
||||||
|
private const val FALLBACK_BASE_URL = "https://gcore.jsdelivr.net/gh/"
|
||||||
|
private const val FALLBACK_REPO_URL_PREFIX = "${FALLBACK_BASE_URL}keiyoushi/extensions@repo/"
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
private data class ExtensionJsonObject(
|
private data class ExtensionJsonObject(
|
|
@ -33,6 +33,7 @@ sealed class Extension {
|
||||||
val isObsolete: Boolean = false,
|
val isObsolete: Boolean = false,
|
||||||
val isUnofficial: Boolean = false,
|
val isUnofficial: Boolean = false,
|
||||||
val isShared: Boolean,
|
val isShared: Boolean,
|
||||||
|
val repoUrl: String? = null,
|
||||||
) : Extension()
|
) : Extension()
|
||||||
|
|
||||||
data class Available(
|
data class Available(
|
||||||
|
@ -48,6 +49,7 @@ sealed class Extension {
|
||||||
val apkName: String,
|
val apkName: String,
|
||||||
val iconUrl: String,
|
val iconUrl: String,
|
||||||
val sources: List<AvailableSource>,
|
val sources: List<AvailableSource>,
|
||||||
|
val repoUrl: String? = null,
|
||||||
) : Extension()
|
) : Extension()
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
|
@ -164,9 +164,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openRepo() {
|
private fun openRepo() {
|
||||||
// TODO
|
val url = getUrl(presenter.extension?.repoUrl)
|
||||||
// val url = getUrl(extension.repoUrl)
|
|
||||||
val url = getUrl()
|
|
||||||
openInBrowser(url)
|
openInBrowser(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ import eu.kanade.tachiyomi.data.updater.AppUpdateResult
|
||||||
import eu.kanade.tachiyomi.data.updater.RELEASE_URL
|
import eu.kanade.tachiyomi.data.updater.RELEASE_URL
|
||||||
import eu.kanade.tachiyomi.databinding.MainActivityBinding
|
import eu.kanade.tachiyomi.databinding.MainActivityBinding
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
import eu.kanade.tachiyomi.extension.api.ExtensionApi
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
import eu.kanade.tachiyomi.ui.base.MaterialMenuSheet
|
||||||
import eu.kanade.tachiyomi.ui.base.SmallToolbarInterface
|
import eu.kanade.tachiyomi.ui.base.SmallToolbarInterface
|
||||||
|
@ -955,7 +955,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
extensionManager.findAvailableExtensions()
|
extensionManager.findAvailableExtensions()
|
||||||
val pendingUpdates = ExtensionGithubApi().checkForUpdates(
|
val pendingUpdates = ExtensionApi().checkForUpdates(
|
||||||
this@MainActivity,
|
this@MainActivity,
|
||||||
extensionManager.availableExtensionsFlow.value.takeIf { it.isNotEmpty() },
|
extensionManager.availableExtensionsFlow.value.takeIf { it.isNotEmpty() },
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import android.os.Build
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import androidx.preference.SwitchPreferenceCompat
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import dev.yokai.presentation.source.SourceRepoController
|
import dev.yokai.presentation.extension.repo.ExtensionRepoController
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
|
@ -42,7 +42,7 @@ class SettingsBrowseController : SettingsController() {
|
||||||
titleRes = R.string.extensions
|
titleRes = R.string.extensions
|
||||||
preference {
|
preference {
|
||||||
titleRes = R.string.source_repos
|
titleRes = R.string.source_repos
|
||||||
onClick { router.pushController(SourceRepoController().withFadeTransaction()) }
|
onClick { router.pushController(ExtensionRepoController().withFadeTransaction()) }
|
||||||
// TODO: Enable once it's finished
|
// TODO: Enable once it's finished
|
||||||
summary = "Temporarily disabled, will be enabled once it's fully implemented"
|
summary = "Temporarily disabled, will be enabled once it's fully implemented"
|
||||||
isEnabled = BuildConfig.DEBUG
|
isEnabled = BuildConfig.DEBUG
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
[versions]
|
[versions]
|
||||||
compose = "1.5.3"
|
compose = "1.5.3"
|
||||||
|
lifecycle = "2.6.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
animation = { module = "androidx.compose.animation:animation", version.ref = "compose" }
|
animation = { module = "androidx.compose.animation:animation", version.ref = "compose" }
|
||||||
foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
|
foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" }
|
||||||
material = { module = "androidx.compose.material:material", version.ref = "compose" }
|
material = { module = "androidx.compose.material:material", version.ref = "compose" }
|
||||||
material3 = { module = "androidx.compose.material3:material3", version = "1.1.2" }
|
material3 = { module = "androidx.compose.material3:material3", version = "1.1.2" }
|
||||||
|
lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
|
||||||
ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
|
ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
|
||||||
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
|
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
|
||||||
ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
|
ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue