diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/LoginScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/LoginScreen.kt index ac9cb9a..bce07ae 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/LoginScreen.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/LoginScreen.kt @@ -20,13 +20,15 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp +import ru.daemonlord.messenger.R @Composable fun LoginScreen( state: AuthUiState, - headerTitle: String = "Messenger Login", + headerTitle: String = "", onEmailChanged: (String) -> Unit, onNameChanged: (String) -> Unit, onUsernameChanged: (String) -> Unit, @@ -42,6 +44,7 @@ fun LoginScreen( ) { val isTabletLayout = LocalConfiguration.current.screenWidthDp >= 840 val isBusy = state.isLoading + val resolvedHeaderTitle = headerTitle.ifBlank { stringResource(id = R.string.auth_header_login) } Box( modifier = Modifier @@ -58,16 +61,16 @@ fun LoginScreen( horizontalAlignment = Alignment.CenterHorizontally, ) { Text( - text = headerTitle, + text = resolvedHeaderTitle, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 14.dp), ) val subtitle = when (state.step) { - AuthStep.EMAIL -> "Enter your email to continue" - AuthStep.PASSWORD -> "Enter password for ${state.email}" - AuthStep.REGISTER -> "Create account for ${state.email}" - AuthStep.OTP -> "Two-factor authentication is enabled" + AuthStep.EMAIL -> stringResource(id = R.string.auth_subtitle_enter_email) + AuthStep.PASSWORD -> stringResource(id = R.string.auth_subtitle_enter_password, state.email) + AuthStep.REGISTER -> stringResource(id = R.string.auth_subtitle_create_account, state.email) + AuthStep.OTP -> stringResource(id = R.string.auth_subtitle_2fa_enabled) } Text( text = subtitle, @@ -81,7 +84,7 @@ fun LoginScreen( OutlinedTextField( value = state.email, onValueChange = onEmailChanged, - label = { Text(text = "Email") }, + label = { Text(text = stringResource(id = R.string.auth_label_email)) }, singleLine = true, enabled = !isBusy, modifier = Modifier @@ -96,7 +99,7 @@ fun LoginScreen( if (isBusy) { CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.padding(2.dp)) } else { - Text("Continue") + Text(stringResource(id = R.string.auth_continue)) } } } @@ -106,7 +109,7 @@ fun LoginScreen( value = state.email, onValueChange = {}, readOnly = true, - label = { Text(text = "Email") }, + label = { Text(text = stringResource(id = R.string.auth_label_email)) }, singleLine = true, modifier = Modifier .fillMaxWidth() @@ -119,14 +122,14 @@ fun LoginScreen( .align(Alignment.Start) .padding(bottom = 6.dp), ) { - Text("Change email") + Text(stringResource(id = R.string.auth_change_email)) } if (state.step == AuthStep.REGISTER) { OutlinedTextField( value = state.name, onValueChange = onNameChanged, - label = { Text(text = "Name") }, + label = { Text(text = stringResource(id = R.string.auth_label_name)) }, singleLine = true, enabled = !isBusy, modifier = Modifier @@ -136,7 +139,7 @@ fun LoginScreen( OutlinedTextField( value = state.username, onValueChange = onUsernameChanged, - label = { Text(text = "Username") }, + label = { Text(text = stringResource(id = R.string.auth_label_username)) }, singleLine = true, enabled = !isBusy, modifier = Modifier @@ -149,7 +152,7 @@ fun LoginScreen( OutlinedTextField( value = state.password, onValueChange = onPasswordChanged, - label = { Text(text = "Password") }, + label = { Text(text = stringResource(id = R.string.auth_label_password)) }, visualTransformation = PasswordVisualTransformation(), singleLine = true, enabled = !isBusy, @@ -167,13 +170,19 @@ fun LoginScreen( .align(Alignment.Start) .padding(bottom = 4.dp), ) { - Text(if (state.useRecoveryCode) "Use OTP code" else "Use recovery code") + Text( + if (state.useRecoveryCode) { + stringResource(id = R.string.auth_use_otp_code) + } else { + stringResource(id = R.string.auth_use_recovery_code) + }, + ) } if (state.useRecoveryCode) { OutlinedTextField( value = state.recoveryCode, onValueChange = onRecoveryCodeChanged, - label = { Text(text = "Recovery code") }, + label = { Text(text = stringResource(id = R.string.auth_label_recovery_code)) }, singleLine = true, enabled = !isBusy, modifier = Modifier @@ -184,7 +193,7 @@ fun LoginScreen( OutlinedTextField( value = state.otpCode, onValueChange = onOtpCodeChanged, - label = { Text(text = "2FA code") }, + label = { Text(text = stringResource(id = R.string.auth_label_2fa_code)) }, singleLine = true, enabled = !isBusy, modifier = Modifier @@ -204,10 +213,10 @@ fun LoginScreen( } else { Text( when (state.step) { - AuthStep.PASSWORD -> "Sign in" - AuthStep.REGISTER -> "Create account" - AuthStep.OTP -> "Confirm 2FA" - AuthStep.EMAIL -> "Continue" + AuthStep.PASSWORD -> stringResource(id = R.string.auth_sign_in) + AuthStep.REGISTER -> stringResource(id = R.string.auth_create_account) + AuthStep.OTP -> stringResource(id = R.string.auth_confirm_2fa) + AuthStep.EMAIL -> stringResource(id = R.string.auth_continue) } ) } @@ -237,13 +246,13 @@ fun LoginScreen( enabled = !isBusy, modifier = Modifier.padding(top = 8.dp), ) { - Text(text = "Verify email by token") + Text(text = stringResource(id = R.string.auth_verify_email_by_token)) } TextButton( onClick = onOpenResetPassword, enabled = !isBusy, ) { - Text(text = "Forgot password") + Text(text = stringResource(id = R.string.auth_forgot_password)) } } } diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/reset/ResetPasswordScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/reset/ResetPasswordScreen.kt index 4ebfad9..dc3c23c 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/reset/ResetPasswordScreen.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/reset/ResetPasswordScreen.kt @@ -23,9 +23,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import ru.daemonlord.messenger.R import ru.daemonlord.messenger.ui.account.AccountViewModel @Composable @@ -51,11 +53,11 @@ fun ResetPasswordRoute( .then(if (isTabletLayout) Modifier.widthIn(max = 620.dp) else Modifier), verticalArrangement = Arrangement.spacedBy(10.dp), ) { - Text("Password reset", style = MaterialTheme.typography.headlineSmall) + Text(stringResource(id = R.string.auth_password_reset_title), style = MaterialTheme.typography.headlineSmall) OutlinedTextField( value = email, onValueChange = { email = it }, - label = { Text("Email") }, + label = { Text(stringResource(id = R.string.auth_label_email)) }, modifier = Modifier.fillMaxWidth(), ) Button( @@ -63,12 +65,12 @@ fun ResetPasswordRoute( modifier = Modifier.fillMaxWidth(), enabled = !state.isSaving && email.isNotBlank(), ) { - Text("Send reset link") + Text(stringResource(id = R.string.auth_send_reset_link)) } OutlinedTextField( value = password, onValueChange = { password = it }, - label = { Text("New password") }, + label = { Text(stringResource(id = R.string.auth_new_password)) }, modifier = Modifier.fillMaxWidth(), ) Button( @@ -80,7 +82,7 @@ fun ResetPasswordRoute( modifier = Modifier.fillMaxWidth(), enabled = !state.isSaving && !token.isNullOrBlank() && password.length >= 8, ) { - Text("Reset with token") + Text(stringResource(id = R.string.auth_reset_with_token)) } if (state.isSaving) { CircularProgressIndicator() @@ -92,7 +94,7 @@ fun ResetPasswordRoute( Text(state.errorMessage!!, color = MaterialTheme.colorScheme.error) } Button(onClick = onBackToLogin, modifier = Modifier.fillMaxWidth()) { - Text("Back to login") + Text(stringResource(id = R.string.auth_back_to_login)) } } } diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/verify/VerifyEmailScreen.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/verify/VerifyEmailScreen.kt index 49edfc8..47c168f 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/verify/VerifyEmailScreen.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/auth/verify/VerifyEmailScreen.kt @@ -24,9 +24,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import ru.daemonlord.messenger.R import ru.daemonlord.messenger.ui.account.AccountViewModel @Composable @@ -59,11 +61,11 @@ fun VerifyEmailRoute( .then(if (isTabletLayout) Modifier.widthIn(max = 620.dp) else Modifier), verticalArrangement = Arrangement.spacedBy(10.dp), ) { - Text("Verify email", style = MaterialTheme.typography.headlineSmall) + Text(stringResource(id = R.string.auth_verify_email_title), style = MaterialTheme.typography.headlineSmall) OutlinedTextField( value = editableToken, onValueChange = { editableToken = it }, - label = { Text("Verification token") }, + label = { Text(stringResource(id = R.string.auth_verification_token)) }, modifier = Modifier.fillMaxWidth(), ) Button( @@ -71,12 +73,12 @@ fun VerifyEmailRoute( enabled = !state.isSaving && editableToken.isNotBlank(), modifier = Modifier.fillMaxWidth(), ) { - Text("Verify") + Text(stringResource(id = R.string.auth_verify)) } OutlinedTextField( value = resendEmail, onValueChange = { resendEmail = it }, - label = { Text("Email for resend") }, + label = { Text(stringResource(id = R.string.auth_email_for_resend)) }, modifier = Modifier.fillMaxWidth(), singleLine = true, ) @@ -85,7 +87,7 @@ fun VerifyEmailRoute( enabled = !state.isSaving && resendEmail.isNotBlank(), modifier = Modifier.fillMaxWidth(), ) { - Text("Resend verification link") + Text(stringResource(id = R.string.auth_resend_verification_link)) } if (state.isSaving) { CircularProgressIndicator() @@ -97,7 +99,7 @@ fun VerifyEmailRoute( Text(state.errorMessage!!, color = MaterialTheme.colorScheme.error) } Button(onClick = onBackToLogin, modifier = Modifier.fillMaxWidth()) { - Text("Back to login") + Text(stringResource(id = R.string.auth_back_to_login)) } } } diff --git a/android/app/src/main/res/values-ru/strings.xml b/android/app/src/main/res/values-ru/strings.xml index e21d91a..883b8ed 100644 --- a/android/app/src/main/res/values-ru/strings.xml +++ b/android/app/src/main/res/values-ru/strings.xml @@ -177,4 +177,35 @@ все контакты никто + + Вход в Messenger + Введите email для продолжения + Введите пароль для %1$s + Создайте аккаунт для %1$s + Включена двухфакторная аутентификация + Email + Имя + Имя пользователя + Пароль + Код восстановления + Код 2FA + Продолжить + Изменить email + Использовать OTP-код + Использовать код восстановления + Войти + Создать аккаунт + Подтвердить 2FA + Подтвердить email по токену + Забыли пароль + Подтверждение email + Токен подтверждения + Подтвердить + Email для повторной отправки + Отправить ссылку повторно + Назад ко входу + Сброс пароля + Отправить ссылку сброса + Новый пароль + Сбросить по токену diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index c391879..67224a5 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -177,4 +177,35 @@ everyone contacts nobody + + Messenger Login + Enter your email to continue + Enter password for %1$s + Create account for %1$s + Two-factor authentication is enabled + Email + Name + Username + Password + Recovery code + 2FA code + Continue + Change email + Use OTP code + Use recovery code + Sign in + Create account + Confirm 2FA + Verify email by token + Forgot password + Verify email + Verification token + Verify + Email for resend + Resend verification link + Back to login + Password reset + Send reset link + New password + Reset with token