mirror of
https://github.com/yogeshpaliyal/KeyPass.git
synced 2026-01-06 09:09:44 -06:00
Password change screen implementation (#534)
* kmp migration started: shared module added * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * Drop files from .gitignore * add password change screen * add password change screen * add password change screen * Drop files from .gitignore * merged
This commit is contained in:
committed by
GitHub
parent
bde4f09e84
commit
5381938454
@@ -76,11 +76,11 @@ fun AuthScreen(state: AuthState) {
|
||||
Text(text = stringResource(id = state.title))
|
||||
|
||||
PasswordInputField(
|
||||
password,
|
||||
setPassword,
|
||||
passwordVisible,
|
||||
setPasswordVisible,
|
||||
passwordError
|
||||
password = password,
|
||||
setPassword = setPassword,
|
||||
passwordVisible = passwordVisible,
|
||||
setPasswordVisible = setPasswordVisible,
|
||||
passwordError = passwordError
|
||||
)
|
||||
|
||||
ButtonBar(state, password, setPasswordError) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.yogeshpaliyal.keypass.R
|
||||
|
||||
@Composable
|
||||
fun PasswordInputField(
|
||||
label: Int = R.string.enter_password,
|
||||
password: String,
|
||||
setPassword: (String) -> Unit,
|
||||
passwordVisible: Boolean,
|
||||
@@ -31,7 +32,7 @@ fun PasswordInputField(
|
||||
value = password,
|
||||
singleLine = true,
|
||||
placeholder = {
|
||||
Text(text = stringResource(id = R.string.enter_password))
|
||||
Text(text = stringResource(id = label))
|
||||
},
|
||||
visualTransformation = if (passwordVisible) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
package com.yogeshpaliyal.keypass.ui.changePassword
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.ArrowBackIosNew
|
||||
import androidx.compose.material3.BottomAppBar
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.yogeshpaliyal.common.utils.getKeyPassPassword
|
||||
import com.yogeshpaliyal.common.utils.setKeyPassPassword
|
||||
import com.yogeshpaliyal.keypass.R
|
||||
import com.yogeshpaliyal.keypass.ui.auth.components.PasswordInputField
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.StateUpdateAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.ChangeAppPasswordState
|
||||
import kotlinx.coroutines.launch
|
||||
import org.reduxkotlin.TypedDispatcher
|
||||
import org.reduxkotlin.compose.rememberTypedDispatcher
|
||||
|
||||
fun TypedDispatcher<Action>.updateState(state: ChangeAppPasswordState) {
|
||||
this(StateUpdateAction(state = state))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChangePassword(state: ChangeAppPasswordState) {
|
||||
val dispatchAction = rememberTypedDispatcher<Action>()
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
|
||||
Scaffold(bottomBar = {
|
||||
BottomAppBar {
|
||||
IconButton(onClick = {
|
||||
dispatchAction(GoBackAction)
|
||||
}) {
|
||||
Icon(
|
||||
painter = rememberVectorPainter(image = Icons.Rounded.ArrowBackIosNew),
|
||||
contentDescription = "Go Back",
|
||||
tint = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
}
|
||||
}
|
||||
}) { contentPadding ->
|
||||
Surface(modifier = Modifier.padding(contentPadding)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(32.dp)
|
||||
.fillMaxSize(1f)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
Arrangement.SpaceEvenly,
|
||||
Alignment.CenterHorizontally
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_undraw_unlock_24mb),
|
||||
contentDescription = ""
|
||||
)
|
||||
|
||||
Text(text = stringResource(id = R.string.change_app_password))
|
||||
|
||||
PasswordInputField(
|
||||
R.string.old_password,
|
||||
state.oldPassword.password,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
oldPassword = state.oldPassword.copy(
|
||||
password = it,
|
||||
passwordError = null
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.oldPassword.passwordVisible,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
oldPassword = state.oldPassword.copy(
|
||||
passwordVisible = it
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.oldPassword.passwordError
|
||||
)
|
||||
|
||||
PasswordInputField(
|
||||
R.string.new_password,
|
||||
state.newPassword.password,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
newPassword = state.newPassword.copy(
|
||||
password = it,
|
||||
passwordError = null
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.newPassword.passwordVisible,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
newPassword = state.newPassword.copy(
|
||||
passwordVisible = it
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.newPassword.passwordError
|
||||
)
|
||||
|
||||
PasswordInputField(
|
||||
R.string.confirm_password,
|
||||
state.confirmPassword.password,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
confirmPassword = state.confirmPassword.copy(
|
||||
password = it,
|
||||
passwordError = null
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.confirmPassword.passwordVisible,
|
||||
{
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
confirmPassword = state.confirmPassword.copy(
|
||||
passwordVisible = it
|
||||
)
|
||||
)
|
||||
)
|
||||
},
|
||||
state.confirmPassword.passwordError
|
||||
)
|
||||
|
||||
Row(modifier = Modifier.fillMaxWidth(1f), Arrangement.SpaceEvenly) {
|
||||
Button(onClick = {
|
||||
// Validate password and change
|
||||
val oldPassword = state.oldPassword
|
||||
if (oldPassword.password.isBlank()) {
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
oldPassword = oldPassword.copy(
|
||||
passwordError = R.string.blank_old_password
|
||||
)
|
||||
)
|
||||
)
|
||||
return@Button
|
||||
}
|
||||
|
||||
val newPassword = state.newPassword
|
||||
if (newPassword.password.isBlank()) {
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
newPassword = newPassword.copy(
|
||||
passwordError = R.string.blank_new_password
|
||||
)
|
||||
)
|
||||
)
|
||||
return@Button
|
||||
}
|
||||
|
||||
val confirmPassword = state.confirmPassword
|
||||
if (confirmPassword.password.isBlank()) {
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
confirmPassword = confirmPassword.copy(
|
||||
passwordError = R.string.blank_confirm_password
|
||||
)
|
||||
)
|
||||
)
|
||||
return@Button
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
val oldPasswordFromStore = context.getKeyPassPassword()
|
||||
if (oldPassword.password != oldPasswordFromStore) {
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
oldPassword = oldPassword.copy(
|
||||
passwordError = R.string.incorrect_old_password
|
||||
)
|
||||
)
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (newPassword.password != confirmPassword.password) {
|
||||
dispatchAction.updateState(
|
||||
state.copy(
|
||||
confirmPassword = confirmPassword.copy(
|
||||
passwordError = R.string.password_no_match
|
||||
)
|
||||
)
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
||||
context.setKeyPassPassword(newPassword.password)
|
||||
dispatchAction(ToastAction(R.string.password_change_success))
|
||||
}
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.change_app_password))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,7 @@ import androidx.compose.ui.unit.dp
|
||||
import com.yogeshpaliyal.keypass.BuildConfig
|
||||
import com.yogeshpaliyal.keypass.ui.auth.AuthScreen
|
||||
import com.yogeshpaliyal.keypass.ui.backup.BackupScreen
|
||||
import com.yogeshpaliyal.keypass.ui.changePassword.ChangePassword
|
||||
import com.yogeshpaliyal.keypass.ui.detail.AccountDetailPage
|
||||
import com.yogeshpaliyal.keypass.ui.home.Homepage
|
||||
import com.yogeshpaliyal.keypass.ui.redux.KeyPassRedux
|
||||
@@ -61,6 +62,7 @@ import com.yogeshpaliyal.keypass.ui.redux.states.AccountDetailState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.AuthState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.BackupScreenState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.BottomSheetState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.ChangeAppPasswordState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.HomeState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.KeyPassState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.ScreenState
|
||||
@@ -157,6 +159,9 @@ fun CurrentPage() {
|
||||
BackupScreen(state = it)
|
||||
}
|
||||
|
||||
is ChangeAppPasswordState -> {
|
||||
ChangePassword(it)
|
||||
}
|
||||
is TotpDetailState -> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.yogeshpaliyal.keypass.ui.redux.states
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
data class ChangeAppPasswordState(
|
||||
val oldPassword: PasswordFieldState = PasswordFieldState(),
|
||||
val newPassword: PasswordFieldState = PasswordFieldState(),
|
||||
val confirmPassword: PasswordFieldState = PasswordFieldState()
|
||||
) : ScreenState(false)
|
||||
|
||||
data class PasswordFieldState(
|
||||
val password: String = "",
|
||||
val passwordVisible: Boolean = false,
|
||||
@StringRes val passwordError: Int? = null
|
||||
)
|
||||
@@ -46,6 +46,7 @@ import com.yogeshpaliyal.keypass.ui.redux.actions.IntentNavigation
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.NavigationAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.actions.ToastAction
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.BackupScreenState
|
||||
import com.yogeshpaliyal.keypass.ui.redux.states.ChangeAppPasswordState
|
||||
import kotlinx.coroutines.launch
|
||||
import org.reduxkotlin.compose.rememberTypedDispatcher
|
||||
|
||||
@@ -155,6 +156,12 @@ fun MySettingCompose() {
|
||||
) {
|
||||
launcher.launch(arrayOf())
|
||||
}
|
||||
PreferenceItem(
|
||||
title = R.string.change_app_password,
|
||||
summary = R.string.change_app_password
|
||||
) {
|
||||
dispatchAction(NavigationAction(ChangeAppPasswordState()))
|
||||
}
|
||||
Divider(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(1f)
|
||||
|
||||
@@ -92,5 +92,13 @@
|
||||
<string name="incorrect_password">गलत पासवर्ड</string>
|
||||
<string name="password_no_match">पासवर्ड मेल नहीं खाता</string>
|
||||
<string name="auto_backup_desc">जब भी खाता जोड़ा या संशोधित किया जाएगा, आपके खाते का बैकअप ले लिया जाएगा</string>
|
||||
<string name="change_app_password">ऐप पासवर्ड बदलें</string>
|
||||
<string name="old_password">पुराना पासवर्ड</string>
|
||||
<string name="new_password">नया पासवर्ड</string>
|
||||
<string name="blank_old_password">कृपया अपना पुराना पासवर्ड दर्ज करें</string>
|
||||
<string name="incorrect_old_password">कृपया अपना सही पुराना पासवर्ड दर्ज करें</string>
|
||||
<string name="blank_new_password">कृपया अपना नया पासवर्ड दर्ज करें</string>
|
||||
<string name="blank_confirm_password">कृपया पुष्टि पासवर्ड दर्ज करें</string>
|
||||
<string name="password_change_success">पासवर्ड सफलतापूर्वक बदला गया</string>
|
||||
|
||||
</resources>
|
||||
@@ -90,5 +90,13 @@
|
||||
<string name="incorrect_password">Senha incorreta</string>
|
||||
<string name="password_no_match">A senha não corresponde</string>
|
||||
<string name="auto_backup_desc">Será feito backup de suas contas sempre que uma conta for adicionada ou modificada</string>
|
||||
<string name="change_app_password">Alterar senha do aplicativo</string>
|
||||
<string name="old_password">Senha Antiga</string>
|
||||
<string name="new_password">Nova Senha</string>
|
||||
<string name="blank_old_password">Por favor, digite sua senha antiga</string>
|
||||
<string name="incorrect_old_password">Digite sua senha antiga correta</string>
|
||||
<string name="blank_new_password">Por favor, digite sua nova senha</string>
|
||||
<string name="blank_confirm_password">Por favor, digite a senha de confirmação</string>
|
||||
<string name="password_change_success">Senha alterada com sucesso</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -91,5 +91,13 @@
|
||||
<string name="incorrect_password">密码错误</string>
|
||||
<string name="password_no_match">密码不匹配</string>
|
||||
<string name="auto_backup_desc">每当添加或修改帐户时,都会备份您的帐户</string>
|
||||
<string name="change_app_password">更改应用密码</string>
|
||||
<string name="old_password">旧密码</string>
|
||||
<string name="new_password">新密码</string>
|
||||
<string name="blank_old_password">请输入您的旧密码</string>
|
||||
<string name="incorrect_old_password">请输入正确的旧密码</string>
|
||||
<string name="blank_new_password">请输入您的新密码</string>
|
||||
<string name="blank_confirm_password">请输入确认密码</string>
|
||||
<string name="password_change_success">密码修改成功</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -90,5 +90,13 @@
|
||||
<string name="incorrect_password">Incorrect Password</string>
|
||||
<string name="password_no_match">The password did not match</string>
|
||||
<string name="auto_backup_desc">Your accounts will be backed up whenever account is added or modified</string>
|
||||
<string name="change_app_password">Change App Password</string>
|
||||
<string name="old_password">Old Password</string>
|
||||
<string name="new_password">New Password</string>
|
||||
<string name="blank_old_password">Please enter your old password</string>
|
||||
<string name="incorrect_old_password">Please enter your correct old password</string>
|
||||
<string name="blank_new_password">Please enter your new password</string>
|
||||
<string name="blank_confirm_password">Please enter confirm password</string>
|
||||
<string name="password_change_success">Password changed successfully</string>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user