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,
)