From 826f3ca5fde00bcea3d454b77dbfca3a619ac429 Mon Sep 17 00:00:00 2001 From: alexander Date: Tue, 4 Jun 2024 16:21:39 +0200 Subject: [PATCH] :construction: Bottom Sheet webview is now in used for Android --- iosApp/iosApp/ContentView.swift | 2 +- shared/src/androidMain/kotlin/main.android.kt | 5 +- shared/src/commonMain/kotlin/App.kt | 49 +++++++++------ .../mcc/shared/screens/app/AppScreen.kt | 8 +-- .../mcc/shared/screens/login/LoginScreen.kt | 61 +++++++++++-------- .../screens/login/LoginScreenViewModel.kt | 45 -------------- 6 files changed, 72 insertions(+), 98 deletions(-) delete mode 100644 shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreenViewModel.kt diff --git a/iosApp/iosApp/ContentView.swift b/iosApp/iosApp/ContentView.swift index 6371228..4ae9d82 100644 --- a/iosApp/iosApp/ContentView.swift +++ b/iosApp/iosApp/ContentView.swift @@ -17,7 +17,7 @@ struct ContentView: View { .onOpenURL(perform: { url in if(loginBridge.isCallbackUrl(url: url.absoluteString)){ showingSheet = false - loginBridge.onLoginSuccessful(callbackUrl: url.absoluteString) + loginBridge.handleCallbackUrl(callbackUrl: url.absoluteString) } }) .edgesIgnoringSafeArea(.all) diff --git a/shared/src/androidMain/kotlin/main.android.kt b/shared/src/androidMain/kotlin/main.android.kt index de55344..9058df7 100644 --- a/shared/src/androidMain/kotlin/main.android.kt +++ b/shared/src/androidMain/kotlin/main.android.kt @@ -7,7 +7,6 @@ import org.koin.android.ext.koin.androidContext @Composable fun MainView() { val context = LocalContext.current - App(DatabaseDao(DatabaseDriverFactory(LocalContext.current)), {}) { - androidContext(context) - } + App(databaseDao = DatabaseDao(DatabaseDriverFactory(LocalContext.current)), + onKoinStart = { androidContext(context) }) } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/App.kt b/shared/src/commonMain/kotlin/App.kt index e1c5130..1812db1 100644 --- a/shared/src/commonMain/kotlin/App.kt +++ b/shared/src/commonMain/kotlin/App.kt @@ -14,7 +14,6 @@ import net.schacher.mcc.shared.repositories.DeckRepository import net.schacher.mcc.shared.repositories.PackRepository import net.schacher.mcc.shared.screens.app.AppScreen import net.schacher.mcc.shared.screens.app.AppViewModel -import net.schacher.mcc.shared.screens.login.LoginScreenViewModel import net.schacher.mcc.shared.screens.main.MainViewModel import net.schacher.mcc.shared.screens.mydecks.MyDecksViewModel import net.schacher.mcc.shared.screens.newdeck.NewDeckViewModel @@ -40,7 +39,6 @@ val repositories = module { val viewModels = module { singleOf(::AppViewModel) - singleOf(::LoginScreenViewModel) singleOf(::MainViewModel) singleOf(::MyDecksViewModel) singleOf(::NewDeckViewModel) @@ -53,31 +51,44 @@ val viewModels = module { @Composable fun App( databaseDao: DatabaseDao, - onLoginClicked: (LoginBridge) -> Unit = {}, + onLoginClicked: ((LoginBridge) -> Unit)? = null, onKoinStart: KoinApplication.() -> Unit = {} ) { val authHandler = AuthRepository(databaseDao as SettingsDao) KoinApplication(application = { onKoinStart() - modules(platformModule, module { - single { databaseDao } - single { databaseDao } - single { databaseDao } - single { databaseDao } - }, module { - single { authHandler } - }, network, repositories, viewModels + modules( + platformModule, + module { + single { databaseDao } + single { databaseDao } + single { databaseDao } + single { databaseDao } + }, + module { + single { authHandler } + }, + network, + repositories, + viewModels ) }) { MccTheme { - AppScreen(onLogInClicked = { - onLoginClicked(object : LoginBridge { - override val url: String = BuildConfig.OAUTH_URL - override fun onLoginSuccessful(callbackUrl: String) { - authHandler.handleCallbackUrl(callbackUrl) + AppScreen( + onLogInClicked = if (onLoginClicked != null) { + { + onLoginClicked.invoke( + object : LoginBridge { + override val url: String = BuildConfig.OAUTH_URL + override fun handleCallbackUrl(callbackUrl: String) { + authHandler.handleCallbackUrl(callbackUrl) + } + }) } - }) - }) + } else { + null + } + ) } } } @@ -90,7 +101,7 @@ interface LoginBridge { val url: String - fun onLoginSuccessful(callbackUrl: String) + fun handleCallbackUrl(callbackUrl: String) fun isCallbackUrl(url: String): Boolean = url.startsWith("mccapp://callback") } diff --git a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/app/AppScreen.kt b/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/app/AppScreen.kt index 008bf82..f2054c9 100644 --- a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/app/AppScreen.kt +++ b/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/app/AppScreen.kt @@ -18,7 +18,7 @@ private const val LOG_OUT_MILLIS = 450 @Composable fun AppScreen( appViewModel: AppViewModel = koinInject(), - onLogInClicked: () -> Unit = {} + onLogInClicked: (() -> Unit)? = null ) { val loggedIn = appViewModel.state.collectAsState() @@ -42,9 +42,9 @@ fun AppScreen( if (it) { MainScreen() } else { - LoginScreen(onLogInClicked = onLogInClicked) { - appViewModel.onGuestLoginClicked() - } + LoginScreen( + onLogInClicked = onLogInClicked, + onGuestLogin = { appViewModel.onGuestLoginClicked() }) } } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreen.kt b/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreen.kt index 78e5c53..d3cc1d1 100644 --- a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreen.kt +++ b/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreen.kt @@ -31,7 +31,6 @@ import androidx.compose.material.icons.filled.Close import androidx.compose.material.rememberModalBottomSheetState 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 @@ -61,22 +60,21 @@ import net.schacher.mcc.shared.design.compose.BackHandler import net.schacher.mcc.shared.design.compose.ConfirmationDialog import net.schacher.mcc.shared.design.theme.DefaultShape import net.schacher.mcc.shared.repositories.AuthRepository -import net.schacher.mcc.shared.screens.login.LoginScreenViewModel.UiState.CONFIRMATION -import net.schacher.mcc.shared.screens.login.LoginScreenViewModel.UiState.ENTER_CREDENTIALS import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.koin.compose.koinInject import pro.schacher.mcc.BuildConfig -@OptIn(ExperimentalResourceApi::class) +internal var confirmationSeen = false + @Composable fun LoginScreen( - viewModel: LoginScreenViewModel = koinInject(), - onLogInClicked: () -> Unit, + onLogInClicked: (() -> Unit)? = null, onGuestLogin: () -> Unit, ) { - val state = viewModel.state.collectAsState().value + var showingConfirmation by remember { mutableStateOf(false) } + var showingLoginView by remember { mutableStateOf(false) } Box(modifier = Modifier.fillMaxSize()) { Image( @@ -107,8 +105,15 @@ fun LoginScreen( TextButton( modifier = Modifier.fillMaxWidth(), onClick = { - onLogInClicked.invoke() -// viewModel.onLoginClicked() + if (confirmationSeen) { + if (onLogInClicked != null) { + onLogInClicked() + } else { + showingLoginView = true + } + } else { + showingConfirmation = true + } }, shape = DefaultShape, colors = ButtonDefaults.textButtonColors( @@ -141,25 +146,29 @@ fun LoginScreen( } } - when (state) { - CONFIRMATION -> { - ConfirmationDialog( - title = stringResource(Res.string.login_info_title), - message = stringResource(Res.string.login_info_message), - onConfirm = { - viewModel.onDismissInfoClicked() - }, - ) - } + if (showingConfirmation) { + confirmationSeen = true + ConfirmationDialog( + title = stringResource(Res.string.login_info_title), + message = stringResource(Res.string.login_info_message), + onConfirm = { + showingConfirmation = false - ENTER_CREDENTIALS -> { - ModalBottomLoginSheet( - onDismiss = { - viewModel.onDismissLoginClicked() - }) - } + if (onLogInClicked != null) { + onLogInClicked.invoke() + } else { + showingLoginView = true + } + }, + ) + } - else -> {} + if (showingLoginView) { + ModalBottomLoginSheet( + onDismiss = { + showingLoginView = false + } + ) } } diff --git a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreenViewModel.kt b/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreenViewModel.kt deleted file mode 100644 index 33f5119..0000000 --- a/shared/src/commonMain/kotlin/net/schacher/mcc/shared/screens/login/LoginScreenViewModel.kt +++ /dev/null @@ -1,45 +0,0 @@ -package net.schacher.mcc.shared.screens.login - -import dev.icerock.moko.mvvm.viewmodel.ViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import net.schacher.mcc.shared.repositories.AuthRepository - -class LoginScreenViewModel(private val authRepository: AuthRepository) : ViewModel() { - - private val _state = MutableStateFlow(UiState.LOGIN_SELECTION) - - val state = _state.asStateFlow() - - private var infoSeen = false - - fun onLoginClicked() { - _state.update { - if (it == UiState.LOGIN_SELECTION && !infoSeen) { - UiState.CONFIRMATION - } else { - UiState.ENTER_CREDENTIALS - } - } - } - - fun onDismissInfoClicked() { - this.infoSeen = true - _state.update { - UiState.ENTER_CREDENTIALS - } - } - - fun onDismissLoginClicked() { - _state.update { - UiState.LOGIN_SELECTION - } - } - - enum class UiState { - LOGIN_SELECTION, - CONFIRMATION, - ENTER_CREDENTIALS, - } -} \ No newline at end of file