From ce59bcd3c3e9848cdf2475aed096d5d2c3a19302 Mon Sep 17 00:00:00 2001 From: Artem Chepurnyi Date: Tue, 22 Oct 2024 20:13:08 +0300 Subject: [PATCH] improvement: Move more text phrases to translatable resources #626 --- .../keyguard/android/BaseActivity.kt | 43 ++++++++++----- .../composeResources/values/strings.xml | 4 ++ .../ChangePasswordStateProducer.kt | 4 +- .../list/DuplicatesListStateProducer.kt | 12 ----- .../home/vault/util/changePasswordAction.kt | 54 ------------------- .../feature/keyguard/setup/SetupScreen.kt | 2 +- .../keyguard/feature/loading/LoadingTask.kt | 6 ++- 7 files changed, 42 insertions(+), 83 deletions(-) diff --git a/common/src/androidMain/kotlin/com/artemchep/keyguard/android/BaseActivity.kt b/common/src/androidMain/kotlin/com/artemchep/keyguard/android/BaseActivity.kt index 4b44e71..ece4672 100644 --- a/common/src/androidMain/kotlin/com/artemchep/keyguard/android/BaseActivity.kt +++ b/common/src/androidMain/kotlin/com/artemchep/keyguard/android/BaseActivity.kt @@ -41,20 +41,26 @@ import com.artemchep.keyguard.common.usecase.GetVaultSession import com.artemchep.keyguard.common.usecase.ShowMessage import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.copy.PermissionServiceAndroid +import com.artemchep.keyguard.feature.loading.ReadableExceptionMessage +import com.artemchep.keyguard.feature.loading.getErrorReadableMessage import com.artemchep.keyguard.feature.navigation.LocalNavigationBackHandler import com.artemchep.keyguard.feature.navigation.N import com.artemchep.keyguard.feature.navigation.NavigationController import com.artemchep.keyguard.feature.navigation.NavigationIntent import com.artemchep.keyguard.feature.navigation.NavigationRouterBackHandler +import com.artemchep.keyguard.feature.navigation.state.TranslatorScope +import com.artemchep.keyguard.platform.LeContext +import com.artemchep.keyguard.platform.recordException +import com.artemchep.keyguard.res.Res +import com.artemchep.keyguard.res.* import com.artemchep.keyguard.ui.surface.LocalBackgroundManager import com.artemchep.keyguard.ui.surface.LocalSurfaceColor import com.artemchep.keyguard.ui.theme.KeyguardTheme -import com.google.firebase.crashlytics.ktx.crashlytics -import com.google.firebase.ktx.Firebase import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import org.kodein.di.DIAware import org.kodein.di.android.closestDI import org.kodein.di.compose.rememberInstance @@ -75,6 +81,11 @@ abstract class BaseActivity : AppCompatActivity(), DIAware { */ private var lastUseExternalBrowser: Boolean = false + protected val translatorScope by lazy { + val context = LeContext(this) + TranslatorScope.of(context) + } + @OptIn(ExperimentalComposeUiApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -472,18 +483,26 @@ abstract class BaseActivity : AppCompatActivity(), DIAware { } private fun ShowMessage.internalShowNavigationErrorMessage(e: Throwable) { - Firebase.crashlytics.recordException(e) + recordException(e) - e.printStackTrace() + // Show an error message + lifecycleScope.launch { + val msg = when (e) { + is ActivityNotFoundException -> { + val title = translatorScope.translate(Res.string.error_failed_open_app_for) + ReadableExceptionMessage(title = title) + } - val model = ToastMessage( - type = ToastMessage.Type.ERROR, - title = when (e) { - is ActivityNotFoundException -> "No installed app can handle this request." - else -> "Something went wrong" - }, - ) - copy(model) + else -> getErrorReadableMessage(e, translatorScope) + } + + val model = ToastMessage( + type = ToastMessage.Type.ERROR, + title = msg.title, + text = msg.text, + ) + copy(model) + } } @Composable diff --git a/common/src/commonMain/composeResources/values/strings.xml b/common/src/commonMain/composeResources/values/strings.xml index 60fb801..d9961dd 100644 --- a/common/src/commonMain/composeResources/values/strings.xml +++ b/common/src/commonMain/composeResources/values/strings.xml @@ -495,6 +495,8 @@ Failed to authorize a request Failed to open a URI Failed to format the placeholder + No installed app can handle this request + Something went wrong Scan QR code Load and parse a QR code from an image file. @@ -611,6 +613,7 @@ No URL overrides Create an encrypted vault where the local data will be stored. + By continuing you confirm that you have purchased the Keyguard or have had an active license. App password Biometric authentication Create a vault @@ -927,6 +930,7 @@ Change app password App password never gets stored on the device nor sent over the network. It is used to generate a secret key that is used to encrypt the local data. Unless you suspect unauthorized access or discover a malware on the device, there is no need to change the password if it is a strong, unique password. + Password changed successfully Export items Archive password diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/changepassword/ChangePasswordStateProducer.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/changepassword/ChangePasswordStateProducer.kt index d0ea75c..b6d502b 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/changepassword/ChangePasswordStateProducer.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/changepassword/ChangePasswordStateProducer.kt @@ -173,7 +173,7 @@ private fun RememberStateFlowScope.ah( .getCreateIo(currentPassword, newPassword) .effectTap { val msg = ToastMessage( - title = "Changed the password", + title = translate(Res.string.changepassword_password_changed_successfully), type = ToastMessage.Type.SUCCESS, ) message(msg) @@ -207,7 +207,7 @@ private fun RememberStateFlowScope.ah( .getCreateIo(currentPassword, newPassword) .effectTap { val msg = ToastMessage( - title = "Changed the password", + title = translate(Res.string.changepassword_password_changed_successfully), type = ToastMessage.Type.SUCCESS, ) message(msg) diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/duplicates/list/DuplicatesListStateProducer.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/duplicates/list/DuplicatesListStateProducer.kt index 43f285a..af4f6a1 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/duplicates/list/DuplicatesListStateProducer.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/duplicates/list/DuplicatesListStateProducer.kt @@ -451,12 +451,6 @@ fun RememberStateFlowScope.createCipherSelectionFlow( filteredCipherIds, true, ) - .effectMap { - val message = ToastMessage( - title = "Add to favourites", - ) - message(message) - } .launchIn(appScope) }, ) @@ -478,12 +472,6 @@ fun RememberStateFlowScope.createCipherSelectionFlow( filteredCipherIds, false, ) - .effectMap { - val message = ToastMessage( - title = "Removed from favourites", - ) - message(message) - } .launchIn(appScope) }, ) diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/vault/util/changePasswordAction.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/vault/util/changePasswordAction.kt index 301016c..df10e43 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/vault/util/changePasswordAction.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/home/vault/util/changePasswordAction.kt @@ -90,12 +90,6 @@ fun RememberStateFlowScope.cipherEnableConfirmAccessAction( filteredCipherIds, true, ) - .effectMap { - val message = ToastMessage( - title = "Auth re-prompt enabled", - ) - message(message) - } .launchIn(appScope) }, ) @@ -122,12 +116,6 @@ fun RememberStateFlowScope.cipherDisableConfirmAccessAction( filteredCipherIds, false, ) - .effectMap { - val message = ToastMessage( - title = "Auth re-prompt disabled", - ) - message(message) - } .biFlatTap( ifException = { ioEffect { after?.invoke(false) } @@ -299,12 +287,6 @@ fun RememberStateFlowScope.cipherCopyToAction( cipher.id to ownership } copyCipherById(cipherIdsToOwnership) - .effectMap { - val message = ToastMessage( - title = "Copied ciphers!", - ) - message(message) - } .launchIn(appScope) } @@ -383,12 +365,6 @@ fun RememberStateFlowScope.cipherMoveToFolderAction( cipherIds, destination, ) - .effectMap { - val message = ToastMessage( - title = "Moved to the folder", - ) - message(message) - } .launchIn(appScope) } @@ -444,12 +420,6 @@ fun RememberStateFlowScope.cipherChangeNameAction( .data .mapValues { it.value as String } changeCipherNameById(cipherIdsToNames) - .effectMap { - val message = ToastMessage( - title = "Changed names", - ) - message(message) - } .launchIn(appScope) } @@ -518,12 +488,6 @@ fun RememberStateFlowScope.cipherChangePasswordAction( .data .mapValues { it.value as String } changeCipherPasswordById(cipherIdsToPasswords) - .effectMap { - val message = ToastMessage( - title = "Changed passwords", - ) - message(message) - } .launchIn(appScope) } @@ -601,12 +565,6 @@ fun RememberStateFlowScope.cipherTrashAction( .map { it.id } .toSet() trashCipherById(cipherIds) - .effectMap { - val message = ToastMessage( - title = "Trashed", - ) - message(message) - } .launchIn(appScope) } @@ -646,12 +604,6 @@ fun RememberStateFlowScope.cipherRestoreAction( .map { it.id } .toSet() restoreCipherById(cipherIds) - .effectMap { - val message = ToastMessage( - title = "Restored", - ) - message(message) - } .launchIn(appScope) } @@ -691,12 +643,6 @@ fun RememberStateFlowScope.cipherDeleteAction( .map { it.id } .toSet() removeCipherById(cipherIds) - .effectMap { - val message = ToastMessage( - title = "Deleted", - ) - message(message) - } .launchIn(appScope) } diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/keyguard/setup/SetupScreen.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/keyguard/setup/SetupScreen.kt index 907cf6b..b45ee5c 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/keyguard/setup/SetupScreen.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/keyguard/setup/SetupScreen.kt @@ -304,7 +304,7 @@ private fun ColumnScope.SetupScreenCreateVaultTitle() { if (isStandalone) { Spacer(Modifier.height(8.dp)) Text( - text = "By continuing you confirm that you have purchased the Keyguard or have had an active license.", + text = stringResource(Res.string.setup_free_text), style = MaterialTheme.typography.bodyMedium, color = LocalContentColor.current .combineAlpha(DisabledEmphasisAlpha), diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/loading/LoadingTask.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/loading/LoadingTask.kt index e6de0b5..98ee49a 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/loading/LoadingTask.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/feature/loading/LoadingTask.kt @@ -8,11 +8,12 @@ import com.artemchep.keyguard.common.io.bind import com.artemchep.keyguard.common.util.flow.EventFlow import com.artemchep.keyguard.feature.navigation.state.TranslatorScope import com.artemchep.keyguard.feature.navigation.state.translate +import com.artemchep.keyguard.res.Res +import com.artemchep.keyguard.res.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch class LoadingTask( @@ -94,7 +95,8 @@ suspend fun getErrorReadableMessage(e: Throwable, translator: TranslatorScope) = } else -> { - val title = e.message.orEmpty() + val title = e.message + ?: translator.translate(Res.string.error_failed_unknown) ReadableExceptionMessage( title = title, )