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