mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
refactor: Rework Dialog
This commit is contained in:
parent
1a16d84e61
commit
49b10c1b4f
14 changed files with 223 additions and 130 deletions
|
@ -5,8 +5,13 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||||
|
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
||||||
|
import eu.kanade.tachiyomi.util.compose.LocalDialogHostState
|
||||||
|
import yokai.domain.DialogHostState
|
||||||
import yokai.presentation.theme.YokaiTheme
|
import yokai.presentation.theme.YokaiTheme
|
||||||
|
|
||||||
abstract class BaseComposeController(bundle: Bundle? = null) :
|
abstract class BaseComposeController(bundle: Bundle? = null) :
|
||||||
|
@ -25,8 +30,14 @@ abstract class BaseComposeController(bundle: Bundle? = null) :
|
||||||
)
|
)
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||||
setContent {
|
setContent {
|
||||||
|
val dialogHostState = remember { DialogHostState() }
|
||||||
YokaiTheme {
|
YokaiTheme {
|
||||||
ScreenContent()
|
CompositionLocalProvider(
|
||||||
|
LocalDialogHostState provides dialogHostState,
|
||||||
|
LocalBackPress provides router::handleBack,
|
||||||
|
) {
|
||||||
|
ScreenContent()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1014,7 +1014,12 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
showNotificationPermissionPrompt()
|
showNotificationPermissionPrompt()
|
||||||
AppUpdateNotifier.releasePageUrl = result.release.releaseLink
|
AppUpdateNotifier.releasePageUrl = result.release.releaseLink
|
||||||
AboutController.NewUpdateDialogController(body, url, isBeta).showDialog(router)
|
if (
|
||||||
|
// FIXME: Show Compose version of NewUpdateDialog for AboutController
|
||||||
|
router.backstack.lastOrNull()?.controller !is AboutController
|
||||||
|
) {
|
||||||
|
AboutController.NewUpdateDialogController(body, url, isBeta).showDialog(router)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
} catch (error: Exception) {
|
||||||
|
@ -1037,6 +1042,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
||||||
|
|
||||||
@SuppressLint("MissingSuperCall")
|
@SuppressLint("MissingSuperCall")
|
||||||
override fun onNewIntent(intent: Intent) {
|
override fun onNewIntent(intent: Intent) {
|
||||||
|
splashState.ready = true
|
||||||
if (!handleIntentAction(intent)) {
|
if (!handleIntentAction(intent)) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1098,11 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
||||||
SHORTCUT_UPDATE_NOTES -> {
|
SHORTCUT_UPDATE_NOTES -> {
|
||||||
val extras = intent.extras ?: return false
|
val extras = intent.extras ?: return false
|
||||||
if (router.backstack.isEmpty()) nav.selectedItemId = R.id.nav_library
|
if (router.backstack.isEmpty()) nav.selectedItemId = R.id.nav_library
|
||||||
if (router.backstack.lastOrNull()?.controller !is AboutController.NewUpdateDialogController) {
|
if (
|
||||||
|
router.backstack.lastOrNull()?.controller !is AboutController.NewUpdateDialogController &&
|
||||||
|
// FIXME: Show Compose version of NewUpdateDialog for AboutController
|
||||||
|
router.backstack.lastOrNull()?.controller !is AboutController
|
||||||
|
) {
|
||||||
AboutController.NewUpdateDialogController(extras).showDialog(router)
|
AboutController.NewUpdateDialogController(extras).showDialog(router)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1132,6 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
|
|
||||||
splashState.ready = true
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,24 @@
|
||||||
package eu.kanade.tachiyomi.ui.more
|
package eu.kanade.tachiyomi.ui.more
|
||||||
|
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.Spanned
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import cafe.adriel.voyager.core.stack.StackEvent
|
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
import cafe.adriel.voyager.transitions.CrossfadeTransition
|
import cafe.adriel.voyager.transitions.CrossfadeTransition
|
||||||
import eu.kanade.tachiyomi.data.updater.AppDownloadInstallJob
|
import eu.kanade.tachiyomi.data.updater.AppDownloadInstallJob
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalRouter
|
|
||||||
import eu.kanade.tachiyomi.util.system.materialAlertDialog
|
import eu.kanade.tachiyomi.util.system.materialAlertDialog
|
||||||
import eu.kanade.tachiyomi.util.view.setNegativeButton
|
import eu.kanade.tachiyomi.util.view.setNegativeButton
|
||||||
import eu.kanade.tachiyomi.util.view.setPositiveButton
|
import eu.kanade.tachiyomi.util.view.setPositiveButton
|
||||||
import eu.kanade.tachiyomi.util.view.setTitle
|
import eu.kanade.tachiyomi.util.view.setTitle
|
||||||
import io.noties.markwon.Markwon
|
import io.noties.markwon.Markwon
|
||||||
import yokai.domain.ComposableAlertDialog
|
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.presentation.settings.screen.about.AboutScreen
|
import yokai.presentation.settings.screen.about.AboutScreen
|
||||||
import android.R as AR
|
import android.R as AR
|
||||||
|
@ -34,17 +30,12 @@ class AboutController : BaseComposeController() {
|
||||||
Navigator(
|
Navigator(
|
||||||
screen = AboutScreen(),
|
screen = AboutScreen(),
|
||||||
content = {
|
content = {
|
||||||
CompositionLocalProvider(
|
CrossfadeTransition(navigator = it)
|
||||||
LocalAlertDialog provides ComposableAlertDialog(null),
|
|
||||||
LocalBackPress provides router::handleBack,
|
|
||||||
LocalRouter provides router,
|
|
||||||
) {
|
|
||||||
CrossfadeTransition(navigator = it)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use [DialogHostState.showNewUpdateDialog] instead", ReplaceWith("DialogHostState.showNewUpdateDialog()"))
|
||||||
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
||||||
|
|
||||||
constructor(body: String, url: String, isBeta: Boolean?) : this(
|
constructor(body: String, url: String, isBeta: Boolean?) : this(
|
||||||
|
@ -56,9 +47,7 @@ class AboutController : BaseComposeController() {
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
val releaseBody = (args.getString(BODY_KEY) ?: "")
|
val info = activity!!.parseReleaseNotes(args.getString(BODY_KEY) ?: "")
|
||||||
.replace("""---(\R|.)*Checksums(\R|.)*""".toRegex(), "")
|
|
||||||
val info = Markwon.create(activity!!).toMarkdown(releaseBody)
|
|
||||||
|
|
||||||
val isOnA12 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
val isOnA12 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
val isBeta = args.getBoolean(IS_BETA, false)
|
val isBeta = args.getBoolean(IS_BETA, false)
|
||||||
|
@ -96,3 +85,8 @@ class AboutController : BaseComposeController() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.parseReleaseNotes(releaseNotes: String): Spanned {
|
||||||
|
val releaseBody = releaseNotes.replace("""---(\R|.)*Checksums(\R|.)*""".toRegex(), "")
|
||||||
|
return Markwon.create(this).toMarkdown(releaseBody)
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.ui.setting
|
package eu.kanade.tachiyomi.ui.setting
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
|
||||||
import yokai.domain.ComposableAlertDialog
|
|
||||||
import yokai.presentation.settings.ComposableSettings
|
import yokai.presentation.settings.ComposableSettings
|
||||||
|
|
||||||
abstract class SettingsComposeController: BaseComposeController(), SettingsControllerInterface {
|
abstract class SettingsComposeController: BaseComposeController(), SettingsControllerInterface {
|
||||||
|
@ -18,11 +14,6 @@ abstract class SettingsComposeController: BaseComposeController(), SettingsContr
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent() {
|
override fun ScreenContent() {
|
||||||
CompositionLocalProvider(
|
getComposableSettings().Content()
|
||||||
LocalAlertDialog provides ComposableAlertDialog(null),
|
|
||||||
LocalBackPress provides router::handleBack,
|
|
||||||
) {
|
|
||||||
getComposableSettings().Content()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@ import androidx.compose.runtime.ProvidableCompositionLocal
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.staticCompositionLocalOf
|
import androidx.compose.runtime.staticCompositionLocalOf
|
||||||
import com.bluelinelabs.conductor.Router
|
import com.bluelinelabs.conductor.Router
|
||||||
import yokai.domain.ComposableAlertDialog
|
import yokai.domain.DialogHostState
|
||||||
|
|
||||||
val <T> ProvidableCompositionLocal<T?>.currentOrThrow
|
val <T> ProvidableCompositionLocal<T?>.currentOrThrow
|
||||||
@Composable
|
@Composable
|
||||||
get(): T = this.current ?: throw RuntimeException("CompositionLocal is null")
|
get(): T = this.current ?: throw RuntimeException("CompositionLocal is null")
|
||||||
|
|
||||||
val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositionLocalOf { null }
|
val LocalBackPress: ProvidableCompositionLocal<(() -> Unit)?> = staticCompositionLocalOf { null }
|
||||||
val LocalAlertDialog: ProvidableCompositionLocal<ComposableAlertDialog?> = compositionLocalOf { null }
|
val LocalDialogHostState: ProvidableCompositionLocal<DialogHostState?> = compositionLocalOf { null }
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
message = "Scheduled for removal once Conductor is fully replaced by Voyager",
|
message = "Scheduled for removal once Conductor is fully replaced by Voyager",
|
||||||
replaceWith = ReplaceWith("LocalNavigator", "cafe.adriel.voyager.navigator.LocalNavigator"),
|
replaceWith = ReplaceWith("LocalNavigator", "cafe.adriel.voyager.navigator.LocalNavigator"),
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package yokai.domain
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
|
|
||||||
class ComposableAlertDialog(initial: (@Composable () -> Unit)?) {
|
|
||||||
var content: (@Composable () -> Unit)? by mutableStateOf(initial)
|
|
||||||
}
|
|
28
app/src/main/java/yokai/domain/DialogHostState.kt
Normal file
28
app/src/main/java/yokai/domain/DialogHostState.kt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package yokai.domain
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import kotlinx.coroutines.CancellableContinuation
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
|
||||||
|
typealias ComposableDialog = (@Composable () -> Unit)?
|
||||||
|
typealias ComposableDialogState = MutableState<ComposableDialog>
|
||||||
|
|
||||||
|
class DialogHostState(initial: ComposableDialog = null) : ComposableDialogState by mutableStateOf(initial) {
|
||||||
|
val mutex = Mutex()
|
||||||
|
|
||||||
|
fun closeDialog() {
|
||||||
|
value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend inline fun <R> dialog(crossinline dialog: @Composable (CancellableContinuation<R>) -> Unit) = mutex.withLock {
|
||||||
|
try {
|
||||||
|
suspendCancellableCoroutine { cont -> value = { dialog(cont) } }
|
||||||
|
} finally {
|
||||||
|
closeDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,7 @@
|
||||||
package yokai.presentation.extension.repo
|
package yokai.presentation.extension.repo
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseComposeController
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
|
||||||
import yokai.domain.ComposableAlertDialog
|
|
||||||
|
|
||||||
class ExtensionRepoController() :
|
class ExtensionRepoController() :
|
||||||
BaseComposeController() {
|
BaseComposeController() {
|
||||||
|
@ -18,14 +14,9 @@ class ExtensionRepoController() :
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun ScreenContent() {
|
override fun ScreenContent() {
|
||||||
CompositionLocalProvider(
|
ExtensionRepoScreen(
|
||||||
LocalAlertDialog provides ComposableAlertDialog(null),
|
title = "Extension Repos",
|
||||||
LocalBackPress provides router::handleBack,
|
repoUrl = repoUrl,
|
||||||
) {
|
)
|
||||||
ExtensionRepoScreen(
|
|
||||||
title = "Extension Repos",
|
|
||||||
repoUrl = repoUrl,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
@ -26,13 +27,14 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import dev.icerock.moko.resources.compose.stringResource
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
||||||
|
import eu.kanade.tachiyomi.util.compose.LocalDialogHostState
|
||||||
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
||||||
import eu.kanade.tachiyomi.util.isTablet
|
import eu.kanade.tachiyomi.util.isTablet
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import yokai.domain.ComposableAlertDialog
|
import kotlinx.coroutines.launch
|
||||||
|
import yokai.domain.DialogHostState
|
||||||
import yokai.domain.extension.repo.model.ExtensionRepo
|
import yokai.domain.extension.repo.model.ExtensionRepo
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.presentation.AppBarType
|
import yokai.presentation.AppBarType
|
||||||
|
@ -51,10 +53,12 @@ fun ExtensionRepoScreen(
|
||||||
) {
|
) {
|
||||||
val onBackPress = LocalBackPress.currentOrThrow
|
val onBackPress = LocalBackPress.currentOrThrow
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val alertDialog = LocalDialogHostState.currentOrThrow
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val repoState by viewModel.repoState.collectAsState()
|
val repoState by viewModel.repoState.collectAsState()
|
||||||
var inputText by remember { mutableStateOf("") }
|
var inputText by remember { mutableStateOf("") }
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
val alertDialog = LocalAlertDialog.currentOrThrow
|
|
||||||
|
|
||||||
YokaiScaffold(
|
YokaiScaffold(
|
||||||
onNavigationIconClicked = onBackPress,
|
onNavigationIconClicked = onBackPress,
|
||||||
|
@ -79,7 +83,7 @@ fun ExtensionRepoScreen(
|
||||||
|
|
||||||
val repos = (repoState as ExtensionRepoState.Success).repos
|
val repos = (repoState as ExtensionRepoState.Success).repos
|
||||||
|
|
||||||
alertDialog.content?.let { it() }
|
alertDialog.value?.invoke()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.padding(innerPadding),
|
modifier = Modifier.padding(innerPadding),
|
||||||
|
@ -113,7 +117,7 @@ fun ExtensionRepoScreen(
|
||||||
ExtensionRepoItem(
|
ExtensionRepoItem(
|
||||||
extensionRepo = repo,
|
extensionRepo = repo,
|
||||||
onDeleteClick = { repoToDelete ->
|
onDeleteClick = { repoToDelete ->
|
||||||
alertDialog.content = { ExtensionRepoDeletePrompt(repoToDelete, alertDialog, viewModel) }
|
scope.launch { alertDialog.awaitExtensionRepoDeletePrompt(repoToDelete, viewModel) }
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -127,46 +131,45 @@ fun ExtensionRepoScreen(
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.event.collectLatest { event ->
|
viewModel.event.collectLatest { event ->
|
||||||
if (event is ExtensionRepoEvent.LocalizedMessage)
|
when (event) {
|
||||||
context.toast(event.stringRes)
|
is ExtensionRepoEvent.NoOp -> {}
|
||||||
if (event is ExtensionRepoEvent.Success)
|
is ExtensionRepoEvent.LocalizedMessage -> context.toast(event.stringRes)
|
||||||
inputText = ""
|
is ExtensionRepoEvent.Success -> inputText = ""
|
||||||
if (event is ExtensionRepoEvent.ShowDialog)
|
is ExtensionRepoEvent.ShowDialog -> {
|
||||||
alertDialog.content = {
|
when(event.dialog) {
|
||||||
if (event.dialog is RepoDialog.Conflict) {
|
is RepoDialog.Conflict -> {
|
||||||
ExtensionRepoReplacePrompt(
|
alertDialog.awaitExtensionRepoReplacePrompt(
|
||||||
oldRepo = event.dialog.oldRepo,
|
oldRepo = event.dialog.oldRepo,
|
||||||
newRepo = event.dialog.newRepo,
|
newRepo = event.dialog.newRepo,
|
||||||
onDismissRequest = { alertDialog.content = null },
|
onMigrate = { viewModel.replaceRepo(event.dialog.newRepo) },
|
||||||
onMigrate = { viewModel.replaceRepo(event.dialog.newRepo) },
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
suspend fun DialogHostState.awaitExtensionRepoReplacePrompt(
|
||||||
fun ExtensionRepoReplacePrompt(
|
|
||||||
oldRepo: ExtensionRepo,
|
oldRepo: ExtensionRepo,
|
||||||
newRepo: ExtensionRepo,
|
newRepo: ExtensionRepo,
|
||||||
onDismissRequest: () -> Unit,
|
|
||||||
onMigrate: () -> Unit,
|
onMigrate: () -> Unit,
|
||||||
) {
|
): Unit = dialog { cont ->
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = { cont.cancel() },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
onMigrate()
|
onMigrate()
|
||||||
onDismissRequest()
|
cont.cancel()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(MR.strings.action_replace_repo))
|
Text(text = stringResource(MR.strings.action_replace_repo))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(onClick = onDismissRequest) {
|
TextButton(onClick = { cont.cancel() }) {
|
||||||
Text(text = stringResource(AR.string.cancel))
|
Text(text = stringResource(AR.string.cancel))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -179,8 +182,10 @@ fun ExtensionRepoReplacePrompt(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
suspend fun DialogHostState.awaitExtensionRepoDeletePrompt(
|
||||||
fun ExtensionRepoDeletePrompt(repoToDelete: String, alertDialog: ComposableAlertDialog, viewModel: ExtensionRepoViewModel) {
|
repoToDelete: String,
|
||||||
|
viewModel: ExtensionRepoViewModel,
|
||||||
|
): Unit = dialog { cont ->
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
title = {
|
title = {
|
||||||
|
@ -199,12 +204,12 @@ fun ExtensionRepoDeletePrompt(repoToDelete: String, alertDialog: ComposableAlert
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onDismissRequest = { alertDialog.content = null },
|
onDismissRequest = { cont.cancel() },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.deleteRepo(repoToDelete)
|
viewModel.deleteRepo(repoToDelete)
|
||||||
alertDialog.content = null
|
cont.cancel()
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
|
@ -215,7 +220,7 @@ fun ExtensionRepoDeletePrompt(repoToDelete: String, alertDialog: ComposableAlert
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(onClick = { alertDialog.content = null }) {
|
TextButton(onClick = { cont.cancel() }) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(MR.strings.cancel),
|
text = stringResource(MR.strings.cancel),
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
|
|
@ -17,8 +17,8 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEachIndexed
|
import androidx.compose.ui.util.fastForEachIndexed
|
||||||
import eu.kanade.tachiyomi.core.storage.preference.collectAsState
|
import eu.kanade.tachiyomi.core.storage.preference.collectAsState
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
import eu.kanade.tachiyomi.util.compose.LocalBackPress
|
||||||
|
import eu.kanade.tachiyomi.util.compose.LocalDialogHostState
|
||||||
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -44,7 +44,7 @@ fun SettingsScaffold(
|
||||||
val preferences: PreferencesHelper by injectLazy()
|
val preferences: PreferencesHelper by injectLazy()
|
||||||
val useLargeAppBar by preferences.useLargeToolbar().collectAsState()
|
val useLargeAppBar by preferences.useLargeToolbar().collectAsState()
|
||||||
val onBackPress = LocalBackPress.currentOrThrow
|
val onBackPress = LocalBackPress.currentOrThrow
|
||||||
val alertDialog = LocalAlertDialog.currentOrThrow
|
val alertDialog = LocalDialogHostState.currentOrThrow
|
||||||
|
|
||||||
YokaiScaffold(
|
YokaiScaffold(
|
||||||
onNavigationIconClicked = onBackPress,
|
onNavigationIconClicked = onBackPress,
|
||||||
|
@ -54,7 +54,7 @@ fun SettingsScaffold(
|
||||||
scrollBehavior = appBarScrollBehavior,
|
scrollBehavior = appBarScrollBehavior,
|
||||||
snackbarHost = snackbarHost,
|
snackbarHost = snackbarHost,
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
alertDialog.content?.let { it() }
|
alertDialog.value?.invoke()
|
||||||
|
|
||||||
content(innerPadding)
|
content(innerPadding)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,10 @@ import eu.kanade.tachiyomi.data.backup.restore.BackupRestoreJob
|
||||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalAlertDialog
|
import eu.kanade.tachiyomi.util.compose.LocalDialogHostState
|
||||||
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
||||||
import eu.kanade.tachiyomi.util.relativeTimeSpanString
|
import eu.kanade.tachiyomi.util.relativeTimeSpanString
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
import eu.kanade.tachiyomi.util.system.e
|
|
||||||
import eu.kanade.tachiyomi.util.system.launchNonCancellableIO
|
import eu.kanade.tachiyomi.util.system.launchNonCancellableIO
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.system.withUIContext
|
import eu.kanade.tachiyomi.util.system.withUIContext
|
||||||
|
@ -57,9 +56,9 @@ import yokai.presentation.component.preference.storageLocationText
|
||||||
import yokai.presentation.component.preference.widget.BasePreferenceWidget
|
import yokai.presentation.component.preference.widget.BasePreferenceWidget
|
||||||
import yokai.presentation.component.preference.widget.PrefsHorizontalPadding
|
import yokai.presentation.component.preference.widget.PrefsHorizontalPadding
|
||||||
import yokai.presentation.settings.ComposableSettings
|
import yokai.presentation.settings.ComposableSettings
|
||||||
import yokai.presentation.settings.screen.data.CreateBackup
|
|
||||||
import yokai.presentation.settings.screen.data.RestoreBackup
|
|
||||||
import yokai.presentation.settings.screen.data.StorageInfo
|
import yokai.presentation.settings.screen.data.StorageInfo
|
||||||
|
import yokai.presentation.settings.screen.data.awaitCreateBackup
|
||||||
|
import yokai.presentation.settings.screen.data.awaitRestoreBackup
|
||||||
import yokai.presentation.settings.screen.data.storageLocationPicker
|
import yokai.presentation.settings.screen.data.storageLocationPicker
|
||||||
import yokai.util.lang.getString
|
import yokai.util.lang.getString
|
||||||
|
|
||||||
|
@ -101,7 +100,7 @@ object SettingsDataScreen : ComposableSettings {
|
||||||
private fun getBackupAndRestoreGroup(backupPreferences: BackupPreferences): Preference.PreferenceGroup {
|
private fun getBackupAndRestoreGroup(backupPreferences: BackupPreferences): Preference.PreferenceGroup {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val alertDialog = LocalAlertDialog.currentOrThrow
|
val alertDialog = LocalDialogHostState.currentOrThrow
|
||||||
val extensionManager = remember { Injekt.get<ExtensionManager>() }
|
val extensionManager = remember { Injekt.get<ExtensionManager>() }
|
||||||
val storageManager = remember { Injekt.get<StorageManager>() }
|
val storageManager = remember { Injekt.get<StorageManager>() }
|
||||||
|
|
||||||
|
@ -122,14 +121,11 @@ object SettingsDataScreen : ComposableSettings {
|
||||||
Pair(null, e)
|
Pair(null, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
alertDialog.content = {
|
scope.launch {
|
||||||
RestoreBackup(
|
alertDialog.awaitRestoreBackup(
|
||||||
context = context,
|
context = context,
|
||||||
uri = it,
|
uri = it,
|
||||||
pair = results,
|
pair = results,
|
||||||
onDismissRequest = {
|
|
||||||
alertDialog.content = null
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,11 +162,10 @@ object SettingsDataScreen : ComposableSettings {
|
||||||
return@SegmentedButton
|
return@SegmentedButton
|
||||||
}
|
}
|
||||||
|
|
||||||
alertDialog.content = {
|
scope.launch {
|
||||||
CreateBackup(
|
alertDialog.awaitCreateBackup(
|
||||||
context = context,
|
context = context,
|
||||||
uri = dir.uri,
|
uri = dir.uri,
|
||||||
onDismissRequest = { alertDialog.content = null },
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package yokai.presentation.settings.screen.about
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import com.google.android.material.textview.MaterialTextView
|
||||||
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
|
import eu.kanade.tachiyomi.data.updater.AppDownloadInstallJob
|
||||||
|
import eu.kanade.tachiyomi.ui.more.parseReleaseNotes
|
||||||
|
import java.io.Serializable
|
||||||
|
import yokai.domain.DialogHostState
|
||||||
|
import yokai.i18n.MR
|
||||||
|
|
||||||
|
data class NewUpdateData(
|
||||||
|
val body: String,
|
||||||
|
val url: String,
|
||||||
|
val isBeta: Boolean?,
|
||||||
|
) : Serializable
|
||||||
|
|
||||||
|
suspend fun DialogHostState.awaitNewUpdateDialog(
|
||||||
|
data: NewUpdateData,
|
||||||
|
onDismiss: () -> Unit = {},
|
||||||
|
): Unit = dialog { cont ->
|
||||||
|
val context = LocalContext.current
|
||||||
|
val appContext = context.applicationContext
|
||||||
|
|
||||||
|
val isOnA12 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
|
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = {
|
||||||
|
onDismiss()
|
||||||
|
cont.cancel()
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
if (data.isBeta == true) {
|
||||||
|
MR.strings.new_beta_version_available
|
||||||
|
} else {
|
||||||
|
MR.strings.new_version_available
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = {
|
||||||
|
AppDownloadInstallJob.start(appContext, data.url, true)
|
||||||
|
onDismiss()
|
||||||
|
cont.cancel()
|
||||||
|
}) {
|
||||||
|
Text(text = stringResource(if (isOnA12) MR.strings.update else MR.strings.download))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
onDismiss()
|
||||||
|
cont.cancel()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(MR.strings.ignore))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = { MarkdownText(data.body) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun MarkdownText(text: String) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
AndroidView(
|
||||||
|
factory = {
|
||||||
|
MaterialTextView(it)
|
||||||
|
},
|
||||||
|
update = {
|
||||||
|
it.text = context.parseReleaseNotes(text)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -27,7 +27,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import co.touchlab.kermit.Logger
|
import co.touchlab.kermit.Logger
|
||||||
import com.bluelinelabs.conductor.Router
|
|
||||||
import dev.icerock.moko.resources.compose.stringResource
|
import dev.icerock.moko.resources.compose.stringResource
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.core.storage.preference.asDateFormat
|
import eu.kanade.tachiyomi.core.storage.preference.asDateFormat
|
||||||
|
@ -36,9 +35,8 @@ import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
|
||||||
import eu.kanade.tachiyomi.data.updater.AppUpdateNotifier
|
import eu.kanade.tachiyomi.data.updater.AppUpdateNotifier
|
||||||
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
|
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.ui.more.AboutController.NewUpdateDialogController
|
|
||||||
import eu.kanade.tachiyomi.util.CrashLogUtil
|
import eu.kanade.tachiyomi.util.CrashLogUtil
|
||||||
import eu.kanade.tachiyomi.util.compose.LocalRouter
|
import eu.kanade.tachiyomi.util.compose.LocalDialogHostState
|
||||||
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
import eu.kanade.tachiyomi.util.compose.currentOrThrow
|
||||||
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
||||||
import eu.kanade.tachiyomi.util.system.isOnline
|
import eu.kanade.tachiyomi.util.system.isOnline
|
||||||
|
@ -52,6 +50,7 @@ import java.util.Locale
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import yokai.domain.DialogHostState
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.presentation.component.preference.widget.TextPreferenceWidget
|
import yokai.presentation.component.preference.widget.TextPreferenceWidget
|
||||||
import yokai.presentation.core.components.LinkIcon
|
import yokai.presentation.core.components.LinkIcon
|
||||||
|
@ -68,7 +67,7 @@ class AboutScreen : Screen() {
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val navigator = LocalNavigator.currentOrThrow
|
val navigator = LocalNavigator.currentOrThrow
|
||||||
val router = LocalRouter.currentOrThrow
|
val dialogHostState = LocalDialogHostState.currentOrThrow
|
||||||
val uriHandler = LocalUriHandler.current
|
val uriHandler = LocalUriHandler.current
|
||||||
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
|
@ -109,7 +108,7 @@ class AboutScreen : Screen() {
|
||||||
onPreferenceClick = {
|
onPreferenceClick = {
|
||||||
if (context.isOnline()) {
|
if (context.isOnline()) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
context.checkVersion(router)
|
context.checkVersion(dialogHostState)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.toast(MR.strings.no_network_connection)
|
context.toast(MR.strings.no_network_connection)
|
||||||
|
@ -193,7 +192,7 @@ class AboutScreen : Screen() {
|
||||||
else -> "Release ${BuildConfig.VERSION_NAME}"
|
else -> "Release ${BuildConfig.VERSION_NAME}"
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun Context.checkVersion(router: Router) {
|
private suspend fun Context.checkVersion(dialogState: DialogHostState) {
|
||||||
val updateChecker = AppUpdateChecker()
|
val updateChecker = AppUpdateChecker()
|
||||||
|
|
||||||
withUIContext { toast(MR.strings.searching_for_updates) }
|
withUIContext { toast(MR.strings.searching_for_updates) }
|
||||||
|
@ -208,14 +207,16 @@ class AboutScreen : Screen() {
|
||||||
}
|
}
|
||||||
when (result) {
|
when (result) {
|
||||||
is AppUpdateResult.NewUpdate -> {
|
is AppUpdateResult.NewUpdate -> {
|
||||||
val body = result.release.info
|
val data = NewUpdateData(
|
||||||
val url = result.release.downloadLink
|
result.release.info,
|
||||||
val isBeta = result.release.preRelease == true
|
result.release.downloadLink,
|
||||||
|
result.release.preRelease == true
|
||||||
|
)
|
||||||
|
|
||||||
// Create confirmation window
|
// Create confirmation window
|
||||||
withUIContext {
|
withUIContext {
|
||||||
AppUpdateNotifier.releasePageUrl = result.release.releaseLink
|
AppUpdateNotifier.releasePageUrl = result.release.releaseLink
|
||||||
NewUpdateDialogController(body, url, isBeta).showDialog(router)
|
dialogState.awaitNewUpdateDialog(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is AppUpdateResult.NoNewUpdate -> {
|
is AppUpdateResult.NoNewUpdate -> {
|
||||||
|
|
|
@ -8,10 +8,8 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
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 com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
|
@ -22,17 +20,16 @@ import eu.kanade.tachiyomi.data.backup.create.BackupOptions
|
||||||
import eu.kanade.tachiyomi.data.backup.models.Backup
|
import eu.kanade.tachiyomi.data.backup.models.Backup
|
||||||
import eu.kanade.tachiyomi.data.backup.restore.BackupRestoreJob
|
import eu.kanade.tachiyomi.data.backup.restore.BackupRestoreJob
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import yokai.domain.DialogHostState
|
||||||
import yokai.i18n.MR
|
import yokai.i18n.MR
|
||||||
import yokai.presentation.component.LabeledCheckbox
|
import yokai.presentation.component.LabeledCheckbox
|
||||||
import android.R as AR
|
import android.R as AR
|
||||||
|
|
||||||
@Composable
|
suspend fun DialogHostState.awaitRestoreBackup(
|
||||||
fun RestoreBackup(
|
|
||||||
context: Context,
|
context: Context,
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
pair: Pair<Results?, Exception?>,
|
pair: Pair<Results?, Exception?>,
|
||||||
onDismissRequest: () -> Unit,
|
): Unit = dialog { cont ->
|
||||||
) {
|
|
||||||
val (results, e) = pair
|
val (results, e) = pair
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
var message = stringResource(MR.strings.restore_content_full)
|
var message = stringResource(MR.strings.restore_content_full)
|
||||||
|
@ -52,20 +49,20 @@ fun RestoreBackup(
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = { cont.cancel() },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
context.toast(MR.strings.restoring_backup)
|
context.toast(MR.strings.restoring_backup)
|
||||||
BackupRestoreJob.start(context, uri)
|
BackupRestoreJob.start(context, uri)
|
||||||
onDismissRequest()
|
cont.cancel()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(MR.strings.restore))
|
Text(text = stringResource(MR.strings.restore))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(onClick = onDismissRequest) {
|
TextButton(onClick = { cont.cancel() }) {
|
||||||
Text(text = stringResource(AR.string.cancel))
|
Text(text = stringResource(AR.string.cancel))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -74,9 +71,9 @@ fun RestoreBackup(
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = { cont.cancel() },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = onDismissRequest) {
|
TextButton(onClick = { cont.cancel() }) {
|
||||||
Text(text = stringResource(AR.string.cancel))
|
Text(text = stringResource(AR.string.cancel))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -86,29 +83,27 @@ fun RestoreBackup(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
suspend fun DialogHostState.awaitCreateBackup(
|
||||||
fun CreateBackup(
|
|
||||||
context: Context,
|
context: Context,
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
onDismissRequest: () -> Unit,
|
): Unit = dialog { cont ->
|
||||||
) {
|
var options by mutableStateOf(BackupOptions())
|
||||||
var options by remember { mutableStateOf(BackupOptions()) }
|
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = { cont.cancel() },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(onClick = {
|
TextButton(onClick = {
|
||||||
val actualUri =
|
val actualUri =
|
||||||
UniFile.fromUri(context, uri)?.createFile(Backup.getBackupFilename())?.uri ?: return@TextButton
|
UniFile.fromUri(context, uri)?.createFile(Backup.getBackupFilename())?.uri ?: return@TextButton
|
||||||
context.toast(MR.strings.creating_backup)
|
context.toast(MR.strings.creating_backup)
|
||||||
BackupCreatorJob.startNow(context, actualUri, options)
|
BackupCreatorJob.startNow(context, actualUri, options)
|
||||||
onDismissRequest()
|
cont.cancel()
|
||||||
}) {
|
}) {
|
||||||
Text(stringResource(MR.strings.create))
|
Text(stringResource(MR.strings.create))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(onClick = { onDismissRequest() }) {
|
TextButton(onClick = { cont.cancel() }) {
|
||||||
Text(stringResource(MR.strings.cancel))
|
Text(stringResource(MR.strings.cancel))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue