From 42ad4ee821c5d7d5be0db3d4620b431cbab805e1 Mon Sep 17 00:00:00 2001 From: Syer10 Date: Sun, 6 Mar 2022 22:19:34 -0500 Subject: [PATCH] Add main Backhandlers --- .../resources/MR/values/base/strings.xml | 1 + .../kotlin/ca/gosyer/ui/main/MainMenu.kt | 25 +++++++++++++++++++ .../kotlin/ca/gosyer/ui/main/MainViewModel.kt | 7 ++++++ .../kotlin/ca/gosyer/ui/main/Routes.kt | 7 ++++++ .../ca/gosyer/uicore/vm/ContextWrapper.kt | 12 +++++++++ .../ca/gosyer/uicore/vm/ContextWrapper.kt | 2 ++ .../ca/gosyer/uicore/vm/ContextWrapper.kt | 5 ++++ .../kotlin/ca/gosyer/uicore/vm/ViewModel.kt | 6 +++++ 8 files changed, 65 insertions(+) diff --git a/i18n/src/commonMain/resources/MR/values/base/strings.xml b/i18n/src/commonMain/resources/MR/values/base/strings.xml index db45b219..af6de20e 100644 --- a/i18n/src/commonMain/resources/MR/values/base/strings.xml +++ b/i18n/src/commonMain/resources/MR/values/base/strings.xml @@ -12,6 +12,7 @@ Cannot start server Confirm exit Are you sure you want to exit? + Press back again to exit Tachidesk-JUI update available %1$s is now available! diff --git a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainMenu.kt b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainMenu.kt index d7c6562b..ab304856 100644 --- a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainMenu.kt +++ b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainMenu.kt @@ -19,10 +19,15 @@ import androidx.compose.foundation.layout.width import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.Modifier import androidx.compose.ui.unit.dp +import ca.gosyer.ui.base.navigation.BackHandler import ca.gosyer.ui.base.navigation.DisplayController import ca.gosyer.ui.base.navigation.withDisplayController import ca.gosyer.ui.main.components.BottomNav @@ -30,6 +35,8 @@ import ca.gosyer.ui.main.components.SideMenu import ca.gosyer.uicore.vm.LocalViewModelFactory import cafe.adriel.voyager.navigator.Navigator import cafe.adriel.voyager.transitions.FadeTransition +import kotlinx.coroutines.delay +import kotlin.time.Duration.Companion.seconds const val SIDE_MENU_EXPAND_DURATION = 500 @@ -37,6 +44,7 @@ const val SIDE_MENU_EXPAND_DURATION = 500 fun MainMenu() { val vmFactory = LocalViewModelFactory.current val vm = remember { vmFactory.instantiate() } + val confirmExit by vm.confirmExit.collectAsState() Surface { Navigator(vm.startScreen.toScreen()) { navigator -> val controller = remember { DisplayController() } @@ -47,6 +55,23 @@ fun MainMenu() { SkinnyMainMenu(navigator) } } + BackHandler(navigator.size == 1 && navigator.lastItem::class != vm.startScreen.toScreenClazz()) { + navigator replaceAll vm.startScreen.toScreen() + } + var exitConfirmed by remember { mutableStateOf(false) } + LaunchedEffect(exitConfirmed) { + delay(2.seconds) + exitConfirmed = false + } + BackHandler( + confirmExit && + navigator.size == 1 && + navigator.lastItem::class == vm.startScreen.toScreenClazz() && + !exitConfirmed + ) { + exitConfirmed = true + vm.confirmExitToast() + } } } } diff --git a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainViewModel.kt b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainViewModel.kt index cc550848..cdb40cfb 100644 --- a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainViewModel.kt +++ b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/MainViewModel.kt @@ -7,7 +7,9 @@ package ca.gosyer.ui.main import ca.gosyer.data.ui.UiPreferences +import ca.gosyer.i18n.MR import ca.gosyer.uicore.vm.ContextWrapper +import ca.gosyer.uicore.vm.Length import ca.gosyer.uicore.vm.ViewModel import kotlinx.coroutines.MainScope import kotlinx.coroutines.cancel @@ -20,9 +22,14 @@ class MainViewModel @Inject constructor( override val scope = MainScope() val startScreen = uiPreferences.startScreen().get() + val confirmExit = uiPreferences.confirmExit().stateIn(scope) override fun onDispose() { super.onDispose() scope.cancel() } + + fun confirmExitToast() { + toast(MR.strings.confirm_exit_toast.toPlatformString(), Length.SHORT) + } } diff --git a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/Routes.kt b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/Routes.kt index b22096f1..ec81dcac 100644 --- a/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/Routes.kt +++ b/presentation/src/jvmMain/kotlin/ca/gosyer/ui/main/Routes.kt @@ -18,3 +18,10 @@ fun StartScreen.toScreen() = when (this) { StartScreen.Sources -> SourcesScreen() StartScreen.Extensions -> ExtensionsScreen() } + +fun StartScreen.toScreenClazz() = when (this) { + StartScreen.Library -> LibraryScreen::class + StartScreen.Updates -> UpdatesScreen::class + StartScreen.Sources -> SourcesScreen::class + StartScreen.Extensions -> ExtensionsScreen::class +} \ No newline at end of file diff --git a/ui-core/src/androidMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt b/ui-core/src/androidMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt index fccab748..5f1799a5 100644 --- a/ui-core/src/androidMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt +++ b/ui-core/src/androidMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt @@ -7,6 +7,7 @@ package ca.gosyer.uicore.vm import android.content.Context +import android.widget.Toast import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.desc.desc import dev.icerock.moko.resources.format @@ -20,4 +21,15 @@ actual class ContextWrapper @Inject constructor(val context: Context) { actual fun toPlatformString(stringResource: StringResource, vararg args: Any): String { return stringResource.format(*args).toString(context) } + + actual fun toast(string: String, length: Length) { + Toast.makeText( + context, + string, + when (length) { + Length.SHORT -> Toast.LENGTH_SHORT + Length.LONG -> Toast.LENGTH_LONG + } + ).show() + } } diff --git a/ui-core/src/desktopMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt b/ui-core/src/desktopMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt index 8b11171b..389ba555 100644 --- a/ui-core/src/desktopMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt +++ b/ui-core/src/desktopMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt @@ -17,4 +17,6 @@ actual class ContextWrapper @Inject constructor() { actual fun toPlatformString(stringResource: StringResource, vararg args: Any): String { return stringResource.format(*args).localized() } + actual fun toast(string: String, length: Length) { + } } diff --git a/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt b/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt index d193ecca..8d6899ae 100644 --- a/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt +++ b/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ContextWrapper.kt @@ -11,4 +11,9 @@ import dev.icerock.moko.resources.StringResource expect class ContextWrapper { fun toPlatformString(stringResource: StringResource): String fun toPlatformString(stringResource: StringResource, vararg args: Any): String + fun toast(string: String, length: Length) } +enum class Length { + SHORT, + LONG +} \ No newline at end of file diff --git a/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ViewModel.kt b/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ViewModel.kt index 4f384fdc..37b05e09 100644 --- a/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ViewModel.kt +++ b/ui-core/src/jvmMain/kotlin/ca/gosyer/uicore/vm/ViewModel.kt @@ -6,6 +6,7 @@ package ca.gosyer.uicore.vm +import ca.gosyer.core.lang.launchUI import ca.gosyer.core.prefs.Preference import ca.gosyer.uicore.prefs.PreferenceMutableStateFlow import cafe.adriel.voyager.core.model.ScreenModel @@ -37,4 +38,9 @@ abstract class ViewModel(private val contextWrapper: ContextWrapper) : ScreenMod fun StringResource.toPlatformString(vararg args: Any): String { return contextWrapper.toPlatformString(this, *args) } + fun toast(string: String, length: Length) { + scope.launchUI { + contextWrapper.toast(string, length) + } + } }