From c752a18ac99ed619a990d53b813a57d44fcf63c0 Mon Sep 17 00:00:00 2001 From: aritra Date: Sat, 4 Jan 2025 14:18:51 +0530 Subject: [PATCH 1/3] Converted Login Screen from Activity -> Composable Screen --- app/src/main/AndroidManifest.xml | 54 ++-- .../com/aritradas/uncrack/MainActivity.kt | 4 +- .../uncrack/navigation/Navigation.kt | 32 ++- .../aritradas/uncrack/navigation/Screen.kt | 7 + .../presentation/auth/login/LoginScreen.kt | 220 +++++++++++++++ .../presentation/auth/login/LoginScreens.kt | 267 ------------------ .../presentation/auth/signup/SignupScreen.kt | 5 +- .../presentation/intro/OnboardingScreen.kt | 47 +-- .../presentation/intro/SplashScreen.kt | 41 +-- .../presentation/settings/SettingsScreen.kt | 5 +- 10 files changed, 296 insertions(+), 386 deletions(-) create mode 100644 app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt delete mode 100644 app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreens.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e92bf2..cd3722d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,19 +5,20 @@ - - - + + - - @@ -40,37 +37,24 @@ - - - - - - - + android:theme="@style/Theme.UnCrack"> - - + android:theme="@style/Theme.UnCrack"> - - + android:theme="@style/Theme.UnCrack"> - - - - + android:theme="@style/Theme.UnCrack"> - + @@ -87,7 +71,7 @@ android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:enabled="true" android:exported="true" - android:permission="com.google.android.c2dm.permission.SEND" > + android:permission="com.google.android.c2dm.permission.SEND"> diff --git a/app/src/main/java/com/aritradas/uncrack/MainActivity.kt b/app/src/main/java/com/aritradas/uncrack/MainActivity.kt index 8eee43a..c32f732 100644 --- a/app/src/main/java/com/aritradas/uncrack/MainActivity.kt +++ b/app/src/main/java/com/aritradas/uncrack/MainActivity.kt @@ -17,6 +17,7 @@ import androidx.core.view.WindowCompat import com.aritradas.uncrack.navigation.Navigation import com.aritradas.uncrack.presentation.settings.SettingsViewModel import com.aritradas.uncrack.ui.theme.UnCrackTheme +import com.aritradas.uncrack.util.NetworkConnectivityObserver import com.google.android.gms.tasks.Task import com.google.android.play.core.appupdate.AppUpdateManagerFactory import com.google.android.play.core.appupdate.AppUpdateInfo @@ -70,7 +71,8 @@ class MainActivity : ComponentActivity() { setContent { UnCrackTheme { - Navigation(this) + val connectivityObserver = NetworkConnectivityObserver(applicationContext) + Navigation(this, connectivityObserver) } } } diff --git a/app/src/main/java/com/aritradas/uncrack/navigation/Navigation.kt b/app/src/main/java/com/aritradas/uncrack/navigation/Navigation.kt index e92c7f5..6d3bdfe 100644 --- a/app/src/main/java/com/aritradas/uncrack/navigation/Navigation.kt +++ b/app/src/main/java/com/aritradas/uncrack/navigation/Navigation.kt @@ -32,8 +32,12 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import com.aritradas.uncrack.R +import com.aritradas.uncrack.presentation.auth.AuthViewModel +import com.aritradas.uncrack.presentation.auth.login.LoginScreen import com.aritradas.uncrack.presentation.browse.BrowseScreen import com.aritradas.uncrack.presentation.browse.category.CategoryScreen +import com.aritradas.uncrack.presentation.intro.OnboardingScreen +import com.aritradas.uncrack.presentation.intro.SplashScreen import com.aritradas.uncrack.presentation.masterKey.KeyViewModel import com.aritradas.uncrack.presentation.masterKey.updateMasterKey.UpdateMasterKey import com.aritradas.uncrack.presentation.profile.HelpScreen @@ -63,6 +67,7 @@ import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight import com.aritradas.uncrack.ui.theme.OnSurfaceVariantLight import com.aritradas.uncrack.ui.theme.PrimaryDark import com.aritradas.uncrack.util.BackPressHandler +import com.aritradas.uncrack.util.ConnectivityObserver import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -71,7 +76,9 @@ import kotlinx.collections.immutable.persistentListOf @Composable fun Navigation( activity: Activity, + connectivityObserver: ConnectivityObserver, modifier: Modifier = Modifier, + authViewModel: AuthViewModel = hiltViewModel(), masterKeyViewModel: KeyViewModel = hiltViewModel(), passwordGeneratorViewModel: PasswordGeneratorViewModel = hiltViewModel(), userViewModel: UserViewModel = hiltViewModel(), @@ -87,6 +94,9 @@ fun Navigation( val backStackEntry = navController.currentBackStackEntryAsState() val screensWithoutNavigationBar = persistentListOf( + Screen.OnboardingScreen.name, + Screen.LoginScreen.name, + Screen.SignUpScreen.name, Screen.AccountSelectionScreen.name, "${Screen.AddPasswordScreen.name}?accountIcon={accountIcon}&accountName={accountName}&accountCategory={accountCategory}", "${Screen.EditPasswordScreen.name}/{accountID}", @@ -102,7 +112,9 @@ fun Navigation( BackPressHandler() Scaffold( - modifier = Modifier.fillMaxSize().then(modifier), + modifier = Modifier + .fillMaxSize() + .then(modifier), bottomBar = { ShowBottomNavigation( backStackEntry, @@ -113,13 +125,29 @@ fun Navigation( ) { NavHost( navController = navController, - startDestination = "vault_screen", + startDestination = "splash_screen", enterTransition = { FadeIn }, exitTransition = { FadeOut }, popEnterTransition = { FadeIn }, popExitTransition = { FadeOut } ) { + composable(route = Screen.SplashScreen.name) { + SplashScreen(navController) + } + composable(route = Screen.OnboardingScreen.name) { + OnboardingScreen(navController) + } + + composable(route = Screen.LoginScreen.name) { + LoginScreen( + navController, + viewModel = authViewModel, + connectivityObserver + ) + } + + composable(route = Screen.BrowseScreen.name) { BrowseScreen( navController diff --git a/app/src/main/java/com/aritradas/uncrack/navigation/Screen.kt b/app/src/main/java/com/aritradas/uncrack/navigation/Screen.kt index c6de55e..cb52137 100644 --- a/app/src/main/java/com/aritradas/uncrack/navigation/Screen.kt +++ b/app/src/main/java/com/aritradas/uncrack/navigation/Screen.kt @@ -2,6 +2,13 @@ package com.aritradas.uncrack.navigation sealed class Screen(val name: String) { + data object SplashScreen: Screen("splash_screen") + data object OnboardingScreen: Screen("onboarding_screen") + data object LoginScreen: Screen("login_screen") + data object SignUpScreen: Screen("signup_screen") + data object ForgetPasswordScreen: Screen("forgot_password_screen") + data object CreateMasterKeyScreen: Screen("create_master_key_scree") + data object ConfirmMasterKeyScreen: Screen("confirm_master_key_scree") data object BrowseScreen : Screen("home_screen") data object VaultScreen : Screen("vault_screen") data object ToolsScreen : Screen("tools_screen") diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt new file mode 100644 index 0000000..3135124 --- /dev/null +++ b/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt @@ -0,0 +1,220 @@ +package com.aritradas.uncrack.presentation.auth.login + +import android.app.Activity +import android.content.Intent +import android.widget.Toast +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import com.aritradas.uncrack.R +import com.aritradas.uncrack.components.NoInternetScreen +import com.aritradas.uncrack.components.ProgressDialog +import com.aritradas.uncrack.components.UCButton +import com.aritradas.uncrack.components.UCTextField +import com.aritradas.uncrack.navigation.Screen +import com.aritradas.uncrack.presentation.auth.AuthViewModel +import com.aritradas.uncrack.presentation.auth.forgotPassword.ForgotPasswordScreen +import com.aritradas.uncrack.presentation.auth.signup.SignupScreen +import com.aritradas.uncrack.presentation.masterKey.createMasterKey.CreateMasterKeyScreen +import com.aritradas.uncrack.ui.theme.DMSansFontFamily +import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight +import com.aritradas.uncrack.ui.theme.PrimaryLight +import com.aritradas.uncrack.ui.theme.medium16 +import com.aritradas.uncrack.util.ConnectivityObserver +import com.aritradas.uncrack.util.UtilsKt.findActivity +import com.aritradas.uncrack.util.Validator.Companion.isValidEmail +import kotlinx.coroutines.flow.collectLatest + + +@Composable +fun LoginScreen( + navController: NavController, + viewModel: AuthViewModel, + connectivityObserver: ConnectivityObserver, + modifier: Modifier = Modifier +) { + val context = LocalContext.current + var email by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + var passwordVisibility by remember { mutableStateOf(false) } + val isSignInButtonEnable by remember { derivedStateOf { email.isValidEmail() } } + + val errorLiveData by viewModel.errorLiveData.observeAsState() + val loginSuccess by viewModel.loginSuccess.observeAsState() + var isLoading by remember { mutableStateOf(false) } + var networkStatus by remember { mutableStateOf(ConnectivityObserver.Status.Unavailable) } + + LaunchedEffect(key1 = true) { + connectivityObserver.observe().collectLatest { status -> + networkStatus = status + } + } + + LaunchedEffect(errorLiveData) { + errorLiveData?.let { error -> + isLoading = false + Toast.makeText(context, error, Toast.LENGTH_SHORT).show() + } + } + + LaunchedEffect(loginSuccess) { + loginSuccess?.let { success -> + isLoading = false + if (success) { + navController.navigate(Screen.CreateMasterKeyScreen.name) + } + } + } + + when (networkStatus) { + ConnectivityObserver.Status.Available -> { + Scaffold( + modifier = modifier.fillMaxSize() + ) { paddingValues -> + + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .padding(16.dp) + ) { + Text( + text = stringResource(R.string.log_in), + fontSize = 40.sp, + fontWeight = FontWeight.Bold, + fontFamily = DMSansFontFamily, + color = Color.Black + ) + + Spacer(modifier = Modifier.height(60.dp)) + + UCTextField( + modifier = Modifier.fillMaxWidth(), + headerText = stringResource(R.string.email_header), + hintText = stringResource(R.string.email_hint), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next), + value = email, + onValueChange = { email = it } + ) + + Spacer(modifier = Modifier.height(30.dp)) + + UCTextField( + modifier = Modifier.fillMaxWidth(), + headerText = stringResource(R.string.password_header), + hintText = stringResource(R.string.password_hint), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), + value = password, + onValueChange = { password = it }, + visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + val image = if (passwordVisibility) + painterResource(id = R.drawable.visibility_off) + else painterResource(id = R.drawable.visibility_on) + + val imageDescription = + if (passwordVisibility) stringResource(R.string.show_password) else stringResource(R.string.hide_password) + + IconButton(onClick = { passwordVisibility = !passwordVisibility }) { + Icon( + modifier = Modifier.size(24.dp), + painter = image, + contentDescription = imageDescription + ) + } + } + ) + + Spacer(modifier = Modifier.height(12.dp)) + + Text( + text = stringResource(R.string.forgot_password), + modifier = Modifier + .align(Alignment.End) + .clickable { navController.navigate(Screen.ForgetPasswordScreen.name) }, + color = MaterialTheme.colorScheme.primary + ) + + Spacer(modifier = Modifier.weight(1f)) + + UCButton( + modifier = Modifier.fillMaxWidth(), + text = stringResource(R.string.login), + isLoading = isLoading, + loadingText = "Logging you in..", + onClick = { + isLoading = true + viewModel.logIn(email, password) + }, + enabled = isSignInButtonEnable + ) + + Spacer(modifier = Modifier.height(15.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Center + ) { + Text( + text = stringResource(R.string.don_t_have_an_account), + style = medium16.copy(color = OnPrimaryContainerLight) + ) + + Spacer(modifier = Modifier.width(8.dp)) + + Text( + modifier = Modifier.clickable { navController.navigate(Screen.SignUpScreen.name) }, + text = stringResource(R.string.create), + style = medium16.copy(color = PrimaryLight) + ) + } + } + } + + if (isLoading) { + ProgressDialog {} + } + } + else -> { + NoInternetScreen() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreens.kt b/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreens.kt deleted file mode 100644 index ece83e6..0000000 --- a/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreens.kt +++ /dev/null @@ -1,267 +0,0 @@ -package com.aritradas.uncrack.presentation.auth.login - -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import android.widget.Toast -import androidx.activity.ComponentActivity -import androidx.activity.SystemBarStyle -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.ImeAction -import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation -import androidx.compose.ui.text.input.VisualTransformation -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.core.view.WindowCompat -import androidx.hilt.navigation.compose.hiltViewModel -import com.aritradas.uncrack.R -import com.aritradas.uncrack.components.NoInternetScreen -import com.aritradas.uncrack.components.ProgressDialog -import com.aritradas.uncrack.components.UCButton -import com.aritradas.uncrack.components.UCTextField -import com.aritradas.uncrack.presentation.auth.AuthViewModel -import com.aritradas.uncrack.presentation.auth.forgotPassword.ForgotPasswordScreen -import com.aritradas.uncrack.presentation.auth.signup.SignupScreen -import com.aritradas.uncrack.presentation.masterKey.createMasterKey.CreateMasterKeyScreen -import com.aritradas.uncrack.ui.theme.DMSansFontFamily -import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight -import com.aritradas.uncrack.ui.theme.PrimaryLight -import com.aritradas.uncrack.ui.theme.UnCrackTheme -import com.aritradas.uncrack.ui.theme.medium16 -import com.aritradas.uncrack.util.ConnectivityObserver -import com.aritradas.uncrack.util.NetworkConnectivityObserver -import com.aritradas.uncrack.util.UtilsKt.findActivity -import com.aritradas.uncrack.util.Validator.Companion.isValidEmail -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.collectLatest - -@AndroidEntryPoint -class LoginScreens : ComponentActivity() { - - private lateinit var userAuthViewModel: AuthViewModel - private lateinit var connectivityObserver: ConnectivityObserver - - override fun onCreate(savedInstanceState: Bundle?) { - - enableEdgeToEdge( - statusBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ), - navigationBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ) - ) - super.onCreate(savedInstanceState) - WindowCompat.setDecorFitsSystemWindows(window, false) - - connectivityObserver = NetworkConnectivityObserver(applicationContext) - setContent { - UnCrackTheme { - var networkStatus by remember { mutableStateOf(ConnectivityObserver.Status.Unavailable) } - - LaunchedEffect(key1 = true) { - connectivityObserver.observe().collectLatest { status -> - networkStatus = status - } - } - userAuthViewModel = hiltViewModel() - - when (networkStatus) { - ConnectivityObserver.Status.Available -> { - LoginContent(this@LoginScreens, userAuthViewModel) - } - else -> { - NoInternetScreen() - } - } - } - } - } -} - -@Composable -fun LoginContent( - activity: Activity, - viewModel: AuthViewModel, - modifier: Modifier = Modifier -) { - val context = LocalContext.current - var email by remember { mutableStateOf("") } - var password by remember { mutableStateOf("") } - var passwordVisibility by remember { mutableStateOf(false) } - val isSignInButtonEnable by remember { derivedStateOf { email.isValidEmail() } } - - val errorLiveData by viewModel.errorLiveData.observeAsState() - val loginSuccess by viewModel.loginSuccess.observeAsState() - var isLoading by remember { mutableStateOf(false) } - - LaunchedEffect(errorLiveData) { - errorLiveData?.let { error -> - isLoading = false - Toast.makeText(context, error, Toast.LENGTH_SHORT).show() - } - } - - LaunchedEffect(loginSuccess) { - loginSuccess?.let { success -> - isLoading = false - if (success) { - context.findActivity()?.apply { - startActivity(Intent(activity, CreateMasterKeyScreen::class.java)) - finish() // Optional: close the login activity - } - } - } - } - - Scaffold( - modifier = modifier.fillMaxSize() - ) { paddingValues -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - .padding(16.dp) - ) { - Text( - text = stringResource(R.string.log_in), - fontSize = 40.sp, - fontWeight = FontWeight.Bold, - fontFamily = DMSansFontFamily, - color = Color.Black - ) - - Spacer(modifier = Modifier.height(60.dp)) - - UCTextField( - modifier = Modifier.fillMaxWidth(), - headerText = stringResource(R.string.email_header), - hintText = stringResource(R.string.email_hint), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next), - value = email, - onValueChange = { email = it } - ) - - Spacer(modifier = Modifier.height(30.dp)) - - UCTextField( - modifier = Modifier.fillMaxWidth(), - headerText = stringResource(R.string.password_header), - hintText = stringResource(R.string.password_hint), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), - value = password, - onValueChange = { password = it }, - visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(), - trailingIcon = { - val image = if (passwordVisibility) - painterResource(id = R.drawable.visibility_off) - else painterResource(id = R.drawable.visibility_on) - - val imageDescription = - if (passwordVisibility) stringResource(R.string.show_password) else stringResource(R.string.hide_password) - - IconButton(onClick = { passwordVisibility = !passwordVisibility }) { - Icon( - modifier = Modifier.size(24.dp), - painter = image, - contentDescription = imageDescription - ) - } - } - ) - - Spacer(modifier = Modifier.height(12.dp)) - - Text( - text = stringResource(R.string.forgot_password), - modifier = Modifier - .align(Alignment.End) - .clickable { - context.findActivity()?.let { - it.startActivity(Intent(it, ForgotPasswordScreen::class.java)) - } - }, - color = MaterialTheme.colorScheme.primary - ) - - Spacer(modifier = Modifier.weight(1f)) - - UCButton( - modifier = Modifier.fillMaxWidth(), - text = stringResource(R.string.login), - isLoading = isLoading, - loadingText = "Logging you in..", - onClick = { - isLoading = true - viewModel.logIn(email, password) - }, - enabled = isSignInButtonEnable - ) - - Spacer(modifier = Modifier.height(15.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center - ) { - Text( - text = stringResource(R.string.don_t_have_an_account), - style = medium16.copy(color = OnPrimaryContainerLight) - ) - - Spacer(modifier = Modifier.width(8.dp)) - - Text( - modifier = Modifier.clickable { - context.findActivity()?.apply { - startActivity(Intent(activity, SignupScreen::class.java)) - } - }, - text = stringResource(R.string.create), - style = medium16.copy(color = PrimaryLight) - ) - } - } - } - - if (isLoading) { - ProgressDialog {} - } -} \ No newline at end of file diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/auth/signup/SignupScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/auth/signup/SignupScreen.kt index 9d54b82..bb3e26b 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/auth/signup/SignupScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/auth/signup/SignupScreen.kt @@ -53,7 +53,6 @@ import com.aritradas.uncrack.components.ProgressDialog import com.aritradas.uncrack.components.UCButton import com.aritradas.uncrack.components.UCTextField import com.aritradas.uncrack.presentation.auth.AuthViewModel -import com.aritradas.uncrack.presentation.auth.login.LoginScreens import com.aritradas.uncrack.presentation.masterKey.createMasterKey.CreateMasterKeyScreen import com.aritradas.uncrack.ui.theme.DMSansFontFamily import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight @@ -290,9 +289,7 @@ fun SignupContent( Text( modifier = Modifier.clickable { - context.findActivity()?.apply { - startActivity(Intent(activity, LoginScreens::class.java)) - } + }, text = stringResource(id = R.string.login), style = medium16.copy(color = PrimaryLight) diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/intro/OnboardingScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/intro/OnboardingScreen.kt index 63ad979..029e821 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/intro/OnboardingScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/intro/OnboardingScreen.kt @@ -1,11 +1,6 @@ package com.aritradas.uncrack.presentation.intro import android.app.Activity -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -33,41 +28,25 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import com.aritradas.uncrack.R import com.aritradas.uncrack.components.OnboardingComponent import com.aritradas.uncrack.components.UCButton import com.aritradas.uncrack.components.UCStrokeButton -import com.aritradas.uncrack.presentation.auth.login.LoginScreens -import com.aritradas.uncrack.presentation.auth.signup.SignupScreen +import com.aritradas.uncrack.navigation.Screen import com.aritradas.uncrack.presentation.intro.model.OnBoardingItem import com.aritradas.uncrack.ui.theme.OnSurfaceLight import com.aritradas.uncrack.ui.theme.OnSurfaceVariantLight import com.aritradas.uncrack.ui.theme.PrimaryDark -import com.aritradas.uncrack.ui.theme.UnCrackTheme import com.aritradas.uncrack.ui.theme.medium18 -import com.aritradas.uncrack.util.UtilsKt.findActivity -import dagger.hilt.android.AndroidEntryPoint -@AndroidEntryPoint -class OnboardingScreen : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - - enableEdgeToEdge() - super.onCreate(savedInstanceState) - - setContent { - UnCrackTheme { - OnboardingContent(this@OnboardingScreen) - } - } - } -} @Composable -fun OnboardingContent(activity: Activity, modifier: Modifier = Modifier) { +fun OnboardingScreen( + navController: NavController, + modifier: Modifier = Modifier +) { - val context = LocalContext.current val pages = OnBoardingItem.onboardingScreenItems() val pagerState = rememberPagerState(pageCount = { pages.size }) val bottomPadding = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() @@ -89,11 +68,7 @@ fun OnboardingContent(activity: Activity, modifier: Modifier = Modifier) { modifier = Modifier .align(Alignment.End) .clickable { - context.findActivity()?.apply { - val loginIntent = Intent(activity, LoginScreens::class.java) - startActivity(loginIntent) - finish() - } + navController.navigate(Screen.LoginScreen.name) }, text = stringResource(R.string.skip), style = medium18.copy(OnSurfaceLight) @@ -123,9 +98,7 @@ fun OnboardingContent(activity: Activity, modifier: Modifier = Modifier) { modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.get_started), onClick = { - context.findActivity()?.apply { - startActivity(Intent(activity, LoginScreens::class.java)) - } + navController.navigate(Screen.LoginScreen.name) } ) @@ -135,9 +108,7 @@ fun OnboardingContent(activity: Activity, modifier: Modifier = Modifier) { modifier = Modifier.fillMaxWidth(), text = stringResource(R.string.create_an_account), onClick = { - context.findActivity()?.apply { - startActivity(Intent(activity, SignupScreen::class.java)) - } + navController.navigate(Screen.SignUpScreen.name) } ) } diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt index d125d2a..9375128 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt @@ -30,7 +30,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import com.aritradas.uncrack.R +import com.aritradas.uncrack.navigation.Screen import com.aritradas.uncrack.presentation.masterKey.confirmMasterKey.ConfirmMasterKeyScreen import com.aritradas.uncrack.ui.theme.BackgroundLight import com.aritradas.uncrack.ui.theme.UnCrackTheme @@ -38,33 +40,10 @@ import com.google.firebase.auth.FirebaseAuth import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay -@AndroidEntryPoint -@SuppressLint("CustomSplashScreen") -class SplashScreen : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - - enableEdgeToEdge( - statusBarStyle = SystemBarStyle.light( - Color.White.toArgb(), Color.White.toArgb() - ), - navigationBarStyle = SystemBarStyle.light( - Color.White.toArgb(), Color.White.toArgb() - ) - ) - super.onCreate(savedInstanceState) - - setContent { - UnCrackTheme { - SplashContent(this@SplashScreen) - } - } - } -} @Composable -fun SplashContent( - activity: Activity, +fun SplashScreen( + navController: NavController, modifier: Modifier = Modifier ) { @@ -84,17 +63,9 @@ fun SplashContent( animation = true if (currentUser == null) { - activity.run { - delay(2000L) - startActivity(Intent(this, OnboardingScreen::class.java)) - finish() - } + navController.navigate(Screen.OnboardingScreen.name) } else { - activity.run { - delay(2000L) - startActivity(Intent(this, ConfirmMasterKeyScreen::class.java)) - finish() - } + navController.navigate(Screen.ConfirmMasterKeyScreen.name) } } diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/settings/SettingsScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/settings/SettingsScreen.kt index dfc1b2f..f43b93c 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/settings/SettingsScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/settings/SettingsScreen.kt @@ -1,7 +1,6 @@ package com.aritradas.uncrack.presentation.settings import android.app.Activity -import android.content.Intent import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -38,7 +37,6 @@ import com.aritradas.uncrack.components.UCSettingsCard import com.aritradas.uncrack.components.UCSwitchCard import com.aritradas.uncrack.components.UCTopAppBar import com.aritradas.uncrack.navigation.Screen -import com.aritradas.uncrack.presentation.auth.login.LoginScreens import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight import com.aritradas.uncrack.ui.theme.OnSurfaceVariantLight import com.aritradas.uncrack.ui.theme.SurfaceVariantLight @@ -63,8 +61,7 @@ fun SettingsScreen( var openDeleteAccountDialog by remember { mutableStateOf(false) } if (onLogOutComplete || onDeleteAccountComplete) { - activity.startActivity(Intent(activity, LoginScreens::class.java)) - activity.finish() + navController.navigate(Screen.LoginScreen.name) } when { From be625f271d67c323005d8d78e8f5c59809aa95b7 Mon Sep 17 00:00:00 2001 From: aritra Date: Sat, 11 Jan 2025 19:44:08 +0530 Subject: [PATCH 2/3] Converted Signup Screen from Activity -> Composable Screen --- app/src/main/AndroidManifest.xml | 5 - .../uncrack/navigation/Navigation.kt | 11 +- .../presentation/auth/login/LoginScreen.kt | 6 - .../presentation/auth/signup/SignupScreen.kt | 312 ++++++++---------- 4 files changed, 139 insertions(+), 195 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cd3722d..9fb5fe1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,11 +36,6 @@ - - - networkState = status - } - } - authViewModel = hiltViewModel() - - when(networkState) { - ConnectivityObserver.Status.Available -> { - SignupContent( - this@SignupScreen, - authViewModel, - onSignUp = { signUpUser -> - newUser = signUpUser - } - ) - } - else -> { - NoInternetScreen() - } - } - } - } - } -} - @Composable -fun SignupContent( - activity: Activity, +fun SignupScreen( authViewModel: AuthViewModel, + connectivityObserver: ConnectivityObserver, modifier: Modifier = Modifier, onSignUp: (FirebaseUser) -> Unit ) { @@ -139,6 +71,8 @@ fun SignupContent( var userEmail by remember { mutableStateOf("") } var userPassword by remember { mutableStateOf("") } var passwordVisibility by remember { mutableStateOf(false) } + val auth: FirebaseAuth = Firebase.auth + var newUser by remember { mutableStateOf(auth.currentUser) } val isRegisterButtonEnable by remember { derivedStateOf { userName.isValidName() && userEmail.isValidEmail() @@ -147,6 +81,13 @@ fun SignupContent( val errorLiveData by authViewModel.errorLiveData.observeAsState() val registerStatus by authViewModel.registerStatus.observeAsState(false) var isLoading by remember { mutableStateOf(false) } + var networkStatus by remember { mutableStateOf(ConnectivityObserver.Status.Unavailable) } + + LaunchedEffect(true) { + connectivityObserver.observe().collectLatest { status -> + networkStatus = status + } + } LaunchedEffect(registerStatus) { if (registerStatus) { @@ -169,132 +110,137 @@ fun SignupContent( ProgressDialog {} } - Scaffold( - modifier = modifier.fillMaxSize() - ) { paddingValues -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - .padding(16.dp) - ) { - - Text( - text = stringResource(R.string.sign_up), - fontSize = 40.sp, - fontWeight = FontWeight.Bold, - fontFamily = DMSansFontFamily, - color = Color.Black - ) - - Spacer(modifier = Modifier.height(60.dp)) + when(networkStatus) { + ConnectivityObserver.Status.Available -> { + Scaffold( + modifier = modifier.fillMaxSize() + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .padding(16.dp) + ) { + + Text( + text = stringResource(R.string.sign_up), + fontSize = 40.sp, + fontWeight = FontWeight.Bold, + fontFamily = DMSansFontFamily, + color = Color.Black + ) - UCTextField( - modifier = Modifier - .fillMaxWidth(), - headerText = stringResource(R.string.name_header), - hintText = stringResource(R.string.name_hint), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next), - value = userName, - onValueChange = { userName = it } - ) + Spacer(modifier = Modifier.height(60.dp)) + + UCTextField( + modifier = Modifier + .fillMaxWidth(), + headerText = stringResource(R.string.name_header), + hintText = stringResource(R.string.name_hint), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Next), + value = userName, + onValueChange = { userName = it } + ) - Spacer(modifier = Modifier.height(30.dp)) + Spacer(modifier = Modifier.height(30.dp)) - UCTextField( - modifier = Modifier - .fillMaxWidth(), - headerText = stringResource(R.string.email_header), - hintText = stringResource(R.string.email_hint), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next), - value = userEmail, - onValueChange = { userEmail = it } - ) + UCTextField( + modifier = Modifier + .fillMaxWidth(), + headerText = stringResource(R.string.email_header), + hintText = stringResource(R.string.email_hint), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Next), + value = userEmail, + onValueChange = { userEmail = it } + ) - Spacer(modifier = Modifier.height(30.dp)) + Spacer(modifier = Modifier.height(30.dp)) + + UCTextField( + modifier = Modifier + .fillMaxWidth(), + headerText = stringResource(R.string.password_header), + hintText = stringResource(R.string.password_hint), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), + value = userPassword, + onValueChange = { userPassword = it }, + visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(), + trailingIcon = { + val image = if (passwordVisibility) + painterResource(id = R.drawable.visibility_off) + else painterResource(id = R.drawable.visibility_on) + + val imageDescription = + if (passwordVisibility) stringResource(R.string.show_password) else stringResource( + R.string.hide_password + ) + + IconButton(onClick = + { passwordVisibility = passwordVisibility.not() } + ) { + Icon( + modifier = Modifier.size(24.dp), + painter = image, + contentDescription = imageDescription + ) + } + } + ) - UCTextField( - modifier = Modifier - .fillMaxWidth(), - headerText = stringResource(R.string.password_header), - hintText = stringResource(R.string.password_hint), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done), - value = userPassword, - onValueChange = { userPassword = it }, - visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(), - trailingIcon = { - val image = if (passwordVisibility) - painterResource(id = R.drawable.visibility_off) - else painterResource(id = R.drawable.visibility_on) + Spacer(modifier = Modifier.weight(1f)) + + UCButton( + modifier = Modifier + .fillMaxWidth(), + text = stringResource(id = R.string.register), + isLoading = isLoading, + loadingText = "Creating your account", + onClick = { + isLoading = true + authViewModel.signUp( + userName, + userEmail, + userPassword, + onSignedUp = { signUpUser -> + newUser = signUpUser + onSignUp(signUpUser) + } + ) + }, + enabled = isRegisterButtonEnable + ) - val imageDescription = - if (passwordVisibility) stringResource(R.string.show_password) else stringResource( - R.string.hide_password - ) + Spacer(modifier = Modifier.height(15.dp)) - IconButton(onClick = - { passwordVisibility = passwordVisibility.not() } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Center ) { - Icon( - modifier = Modifier.size(24.dp), - painter = image, - contentDescription = imageDescription + Text( + text = stringResource(id = R.string.already_have_an_account), + style = medium16.copy(color = OnPrimaryContainerLight) ) - } - } - ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.width(8.dp)) - UCButton( - modifier = Modifier - .fillMaxWidth(), - text = stringResource(id = R.string.register), - isLoading = isLoading, - loadingText = "Creating your account", - onClick = { - isLoading = true - authViewModel.signUp( - userName, - userEmail, - userPassword, - onSignedUp = { signUpUser -> - onSignUp(signUpUser) - } - ) + Text( + modifier = Modifier.clickable { - context.findActivity()?.apply { - startActivity(Intent(activity, CreateMasterKeyScreen::class.java)) + }, + text = stringResource(id = R.string.login), + style = medium16.copy(color = PrimaryLight) + ) } - }, - enabled = isRegisterButtonEnable - ) - - Spacer(modifier = Modifier.height(15.dp)) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center - ) { - Text( - text = stringResource(id = R.string.already_have_an_account), - style = medium16.copy(color = OnPrimaryContainerLight) - ) - - Spacer(modifier = Modifier.width(8.dp)) - - Text( - modifier = Modifier.clickable { - - }, - text = stringResource(id = R.string.login), - style = medium16.copy(color = PrimaryLight) - ) + } } } + else -> { + NoInternetScreen() + } } + } \ No newline at end of file From e026a030e370de0b6a6584a07d2e95fcfa97e110 Mon Sep 17 00:00:00 2001 From: aritra Date: Sat, 11 Jan 2025 20:25:11 +0530 Subject: [PATCH 3/3] Converted all the ActivityCompoenet screen to Composable Screen --- app/src/main/AndroidManifest.xml | 16 -- .../uncrack/navigation/Navigation.kt | 22 +++ .../aritradas/uncrack/navigation/Screen.kt | 2 +- .../forgotPassword/ForgotPasswordScreen.kt | 152 +++++++----------- .../presentation/auth/login/LoginScreen.kt | 2 +- .../presentation/intro/SplashScreen.kt | 14 -- .../ConfirmMasterKeyScreen.kt | 48 +----- .../createMasterKey/CreateMasterKeyScreen.kt | 78 ++++----- 8 files changed, 115 insertions(+), 219 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9fb5fe1..a1ebd5b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,22 +36,6 @@ - - - - - - - - networkStatus = status - } - } - - when(networkStatus) { - ConnectivityObserver.Status.Available -> { - ForgotPasswordContent() - } - else -> { - NoInternetScreen() - } - } - } - } - } -} - @Composable -fun ForgotPasswordContent( +fun ForgotPasswordScreen( + connectivityObserver: ConnectivityObserver, modifier: Modifier = Modifier, viewModel: AuthViewModel = hiltViewModel() ) { @@ -104,6 +53,13 @@ fun ForgotPasswordContent( val resetPasswordRequestLiveData by viewModel.resetPassword.observeAsState() val errorLiveData by viewModel.errorLiveData.observeAsState() var isLoading by remember { mutableStateOf(false) } + var networkStatus by remember { mutableStateOf(ConnectivityObserver.Status.Unavailable) } + + LaunchedEffect(key1 = true) { + connectivityObserver.observe().collectLatest { status -> + networkStatus = status + } + } LaunchedEffect(resetPasswordRequestLiveData) { if (resetPasswordRequestLiveData == true) { @@ -126,47 +82,55 @@ fun ForgotPasswordContent( ProgressDialog {} } - Scaffold( - modifier = modifier.fillMaxSize() - ) { paddingValues -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - .padding(16.dp) - ) { - - Text( - text = stringResource(R.string.forgot_password), - fontSize = 40.sp, - fontWeight = FontWeight.Bold, - fontFamily = DMSansFontFamily, - color = Color.Black - ) - - Spacer(modifier = Modifier.height(60.dp)) - - UCTextField( - modifier = Modifier - .fillMaxWidth(), - headerText = stringResource(R.string.enter_your_registered_mail), - maxLines = 1, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Done), - value = email, - onValueChange = { email = it } - ) - - Spacer(modifier = Modifier.weight(1f)) - - UCButton( - modifier = Modifier - .fillMaxWidth(), - text = stringResource(R.string.send_reset_link), - onClick = { - viewModel.resetPassword(email) - }, - enabled = enableSendBtn - ) + when(networkStatus) { + ConnectivityObserver.Status.Available -> { + Scaffold( + modifier = modifier.fillMaxSize() + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .padding(16.dp) + ) { + + Text( + text = stringResource(R.string.forgot_password), + fontSize = 40.sp, + fontWeight = FontWeight.Bold, + fontFamily = DMSansFontFamily, + color = Color.Black + ) + + Spacer(modifier = Modifier.height(60.dp)) + + UCTextField( + modifier = Modifier + .fillMaxWidth(), + headerText = stringResource(R.string.enter_your_registered_mail), + maxLines = 1, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email, imeAction = ImeAction.Done), + value = email, + onValueChange = { email = it } + ) + + Spacer(modifier = Modifier.weight(1f)) + + UCButton( + modifier = Modifier + .fillMaxWidth(), + text = stringResource(R.string.send_reset_link), + onClick = { + viewModel.resetPassword(email) + }, + enabled = enableSendBtn + ) + } + } + } + else -> { + NoInternetScreen() } } + } diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt index a0c1b0b..711bcb9 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/auth/login/LoginScreen.kt @@ -163,7 +163,7 @@ fun LoginScreen( text = stringResource(R.string.forgot_password), modifier = Modifier .align(Alignment.End) - .clickable { navController.navigate(Screen.ForgetPasswordScreen.name) }, + .clickable { navController.navigate(Screen.ForgotPasswordScreen.name) }, color = MaterialTheme.colorScheme.primary ) diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt index 9375128..0ea28ba 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/intro/SplashScreen.kt @@ -1,13 +1,5 @@ package com.aritradas.uncrack.presentation.intro -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.SystemBarStyle -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.foundation.Image @@ -26,19 +18,13 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.aritradas.uncrack.R import com.aritradas.uncrack.navigation.Screen -import com.aritradas.uncrack.presentation.masterKey.confirmMasterKey.ConfirmMasterKeyScreen import com.aritradas.uncrack.ui.theme.BackgroundLight -import com.aritradas.uncrack.ui.theme.UnCrackTheme import com.google.firebase.auth.FirebaseAuth -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.delay @Composable diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/confirmMasterKey/ConfirmMasterKeyScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/confirmMasterKey/ConfirmMasterKeyScreen.kt index d44f4fb..80233b1 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/confirmMasterKey/ConfirmMasterKeyScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/confirmMasterKey/ConfirmMasterKeyScreen.kt @@ -1,12 +1,5 @@ package com.aritradas.uncrack.presentation.masterKey.confirmMasterKey -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.SystemBarStyle -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -28,7 +21,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -37,47 +29,19 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp -import androidx.core.view.WindowCompat import androidx.hilt.navigation.compose.hiltViewModel -import com.aritradas.uncrack.MainActivity +import androidx.navigation.NavController import com.aritradas.uncrack.R import com.aritradas.uncrack.components.UCButton import com.aritradas.uncrack.components.UCTextField +import com.aritradas.uncrack.navigation.Screen import com.aritradas.uncrack.presentation.masterKey.KeyViewModel import com.aritradas.uncrack.ui.theme.SurfaceVariantLight -import com.aritradas.uncrack.ui.theme.UnCrackTheme import com.aritradas.uncrack.ui.theme.bold30 -import com.aritradas.uncrack.util.UtilsKt.findActivity -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class ConfirmMasterKeyScreen : ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - - enableEdgeToEdge( - statusBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ), - navigationBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ) - ) - - super.onCreate(savedInstanceState) - WindowCompat.setDecorFitsSystemWindows(window, false) - - setContent { - UnCrackTheme { - ConfirmMasterKeyContent(this@ConfirmMasterKeyScreen) - } - } - } -} @Composable -fun ConfirmMasterKeyContent( - activity: Activity, +fun ConfirmMasterKeyScreen( + navController: NavController, modifier: Modifier = Modifier, masterKeyViewModel: KeyViewModel = hiltViewModel() ) { @@ -154,9 +118,7 @@ fun ConfirmMasterKeyContent( .fillMaxWidth(), text = stringResource(R.string.unlock_uncrack), onClick = { - context.findActivity()?.apply { - startActivity(Intent(activity, MainActivity::class.java)) - } + navController.navigate(Screen.VaultScreen.name) }, enabled = savedMasterKey == confirmMasterKey ) diff --git a/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/createMasterKey/CreateMasterKeyScreen.kt b/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/createMasterKey/CreateMasterKeyScreen.kt index 04fd876..1d889a4 100644 --- a/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/createMasterKey/CreateMasterKeyScreen.kt +++ b/app/src/main/java/com/aritradas/uncrack/presentation/masterKey/createMasterKey/CreateMasterKeyScreen.kt @@ -1,22 +1,26 @@ package com.aritradas.uncrack.presentation.masterKey.createMasterKey -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.SystemBarStyle -import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction @@ -24,52 +28,28 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp -import androidx.core.view.WindowCompat -import androidx.hilt.navigation.compose.hiltViewModel -import com.aritradas.uncrack.MainActivity +import androidx.navigation.NavController import com.aritradas.uncrack.R import com.aritradas.uncrack.components.PasswordStrengthIndicator import com.aritradas.uncrack.components.UCButton import com.aritradas.uncrack.components.UCTextField import com.aritradas.uncrack.domain.model.Key +import com.aritradas.uncrack.navigation.Screen import com.aritradas.uncrack.presentation.masterKey.KeyViewModel -import com.aritradas.uncrack.ui.theme.* -import com.aritradas.uncrack.util.UtilsKt.findActivity -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class CreateMasterKeyScreen : ComponentActivity() { - - private lateinit var masterKeyViewModel: KeyViewModel - override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge( - statusBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ), - navigationBarStyle = SystemBarStyle.light( - Color.Transparent.toArgb(), Color.Transparent.toArgb() - ) - ) - - super.onCreate(savedInstanceState) - WindowCompat.setDecorFitsSystemWindows(window, false) - - setContent { - UnCrackTheme { - masterKeyViewModel = hiltViewModel() - CreateMasterKeyContent(this@CreateMasterKeyScreen, masterKeyViewModel) - } - } - } -} +import com.aritradas.uncrack.ui.theme.OnPrimaryContainerLight +import com.aritradas.uncrack.ui.theme.SurfaceTintLight +import com.aritradas.uncrack.ui.theme.SurfaceVariantLight +import com.aritradas.uncrack.ui.theme.bold30 +import com.aritradas.uncrack.ui.theme.medium14 +import com.aritradas.uncrack.ui.theme.normal16 @Composable -fun CreateMasterKeyContent( - activity: Activity, +fun CreateMasterKeyScreen( + navController: NavController, masterKeyViewModel: KeyViewModel, modifier: Modifier = Modifier ) { - val context = LocalContext.current + val masterKeyObserver by masterKeyViewModel.masterKeyLiveData.observeAsState("") val confirmMasterKeyObserver by masterKeyViewModel.confirmMasterKeyLiveData.observeAsState("") val hasMinLengthObserver by masterKeyViewModel.hasMinLength.observeAsState(false) @@ -186,9 +166,7 @@ fun CreateMasterKeyContent( onClick = { val key = Key(0, masterKeyObserver) masterKeyViewModel.saveMasterKey(key) - context.findActivity()?.apply { - startActivity(Intent(activity, MainActivity::class.java)) - } + navController.navigate(Screen.VaultScreen.name) }, enabled = enableButtonObserver )