diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsTab.kt index be6d243b8..bc91ea121 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsTab.kt @@ -1,8 +1,15 @@ package eu.kanade.tachiyomi.ui.browse.extension +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow import eu.kanade.presentation.browse.ExtensionScreen @@ -12,6 +19,7 @@ import eu.kanade.presentation.more.settings.screen.browse.ExtensionReposScreen import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsScreen import eu.kanade.tachiyomi.ui.webview.WebViewScreen +import eu.kanade.tachiyomi.util.system.isPackageInstalled import kotlinx.collections.immutable.persistentListOf import tachiyomi.i18n.MR import tachiyomi.presentation.core.i18n.stringResource @@ -21,7 +29,10 @@ fun extensionsTab( extensionsScreenModel: ExtensionsScreenModel, ): TabContent { val navigator = LocalNavigator.currentOrThrow + val context = LocalContext.current + val state by extensionsScreenModel.state.collectAsState() + var privateExtensionToUninstall by remember { mutableStateOf(null) } return TabContent( titleRes = MR.strings.label_extensions, @@ -45,7 +56,13 @@ fun extensionsTab( onLongClickItem = { extension -> when (extension) { is Extension.Available -> extensionsScreenModel.installExtension(extension) - else -> extensionsScreenModel.uninstallExtension(extension) + else -> { + if (context.isPackageInstalled(extension.pkgName)) { + extensionsScreenModel.uninstallExtension(extension) + } else { + privateExtensionToUninstall = extension + } + } } }, onClickItemCancel = extensionsScreenModel::cancelInstallUpdateExtension, @@ -68,6 +85,50 @@ fun extensionsTab( onUpdateExtension = extensionsScreenModel::updateExtension, onRefresh = extensionsScreenModel::findAvailableExtensions, ) + + privateExtensionToUninstall?.let { extension -> + ExtensionUninstallConfirmation( + extensionName = extension.name, + onClickConfirm = { + extensionsScreenModel.uninstallExtension(extension) + }, + onDismissRequest = { + privateExtensionToUninstall = null + }, + ) + } }, ) } + +@Composable +private fun ExtensionUninstallConfirmation( + extensionName: String, + onClickConfirm: () -> Unit, + onDismissRequest: () -> Unit, +) { + AlertDialog( + title = { + Text(text = stringResource(MR.strings.ext_confirm_remove)) + }, + text = { + Text(text = stringResource(MR.strings.remove_private_extension_message, extensionName)) + }, + confirmButton = { + TextButton( + onClick = { + onClickConfirm() + onDismissRequest() + }, + ) { + Text(text = stringResource(MR.strings.ext_remove)) + } + }, + dismissButton = { + TextButton(onClick = onDismissRequest) { + Text(text = stringResource(MR.strings.action_cancel)) + } + }, + onDismissRequest = onDismissRequest, + ) +} diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index ffd19e5ed..f9e4d1ed6 100644 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -326,10 +326,13 @@ Trust Untrusted Uninstall + Remove + Remove Extension? App info Untrusted extension Malicious extensions can read any stored login credentials or execute arbitrary code.\n\nBy trusting this extension, you accept these risks. This extension is no longer available. It may not function properly and can cause issues with the app. Uninstalling it is recommended. + Do you really want to remove \"%s\" extension? Failed to fetch available extensions Version Language