From fa08a60299fac80c39178fbc9c60228c1dd97a81 Mon Sep 17 00:00:00 2001 From: Vadik Sirekanyan Date: Sun, 11 Feb 2024 21:50:33 +0400 Subject: [PATCH] Added update error toast --- .../org/sirekanyan/outline/MainActivity.kt | 10 ++++++++++ .../java/org/sirekanyan/outline/MainState.kt | 14 +++++++++++++- .../sirekanyan/outline/ext/LocalizedString.kt | 19 +++++++++++++++++++ .../java/org/sirekanyan/outline/ext/Toast.kt | 4 ++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/sirekanyan/outline/ext/LocalizedString.kt diff --git a/app/src/main/java/org/sirekanyan/outline/MainActivity.kt b/app/src/main/java/org/sirekanyan/outline/MainActivity.kt index bf1f911..fe47146 100644 --- a/app/src/main/java/org/sirekanyan/outline/MainActivity.kt +++ b/app/src/main/java/org/sirekanyan/outline/MainActivity.kt @@ -7,8 +7,12 @@ import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.core.view.WindowCompat +import kotlinx.coroutines.launch +import org.sirekanyan.outline.ext.showToast import org.sirekanyan.outline.ui.AboutDialogContent import org.sirekanyan.outline.ui.AddServerContent import org.sirekanyan.outline.ui.DeleteKeyContent @@ -25,6 +29,12 @@ class MainActivity : ComponentActivity() { val router = rememberRouter() val state = rememberMainState(router) OutlineTheme { + val context = LocalContext.current + LaunchedEffect(Unit) { + launch { + state.observeToasts().collect(context::showToast) + } + } Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { BackHandler(state.drawer.isOpen) { state.closeDrawer() diff --git a/app/src/main/java/org/sirekanyan/outline/MainState.kt b/app/src/main/java/org/sirekanyan/outline/MainState.kt index 7c9629f..e0133de 100644 --- a/app/src/main/java/org/sirekanyan/outline/MainState.kt +++ b/app/src/main/java/org/sirekanyan/outline/MainState.kt @@ -10,6 +10,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -19,6 +21,8 @@ import kotlinx.parcelize.Parcelize import org.sirekanyan.outline.api.model.Key import org.sirekanyan.outline.api.model.Server import org.sirekanyan.outline.db.KeyValueDao +import org.sirekanyan.outline.ext.LocalizedString +import org.sirekanyan.outline.ext.PluralsResource import org.sirekanyan.outline.ext.asyncAll import org.sirekanyan.outline.ext.rememberStateScope import org.sirekanyan.outline.feature.keys.KeysErrorState @@ -52,6 +56,8 @@ class MainState( private val prefs: KeyValueDao, ) : CoroutineScope by scope { + private val toasts = MutableSharedFlow() + fun observeToasts(): Flow = toasts val drawer = router.drawer val drawerDisabled by derivedStateOf { search.isOpened && drawer.isClosed } var page by router.pageState @@ -99,7 +105,7 @@ class MainState( withContext(Dispatchers.IO) { page.keys = KeysLoadingState page.keys = try { - servers.getServers() + val errors = servers.getServers() .asyncAll { server -> runCatching { withTimeout(5.seconds) { @@ -107,6 +113,12 @@ class MainState( } } } + .mapNotNull { result -> + result.exceptionOrNull() + } + if (errors.isNotEmpty()) { + toasts.emit(PluralsResource(R.plurals.outln_update_error, errors.size)) + } KeysIdleState } catch (exception: Exception) { exception.printStackTrace() diff --git a/app/src/main/java/org/sirekanyan/outline/ext/LocalizedString.kt b/app/src/main/java/org/sirekanyan/outline/ext/LocalizedString.kt new file mode 100644 index 0000000..adb4c56 --- /dev/null +++ b/app/src/main/java/org/sirekanyan/outline/ext/LocalizedString.kt @@ -0,0 +1,19 @@ +package org.sirekanyan.outline.ext + +import android.content.Context +import androidx.annotation.PluralsRes +import androidx.annotation.StringRes + +fun Context.getString(resource: LocalizedString): String = + when (resource) { + is StringResource -> + resources.getString(resource.id) + is PluralsResource -> + resources.getQuantityString(resource.id, resource.quantity, resource.quantity) + } + +sealed class LocalizedString + +class StringResource(@StringRes val id: Int) : LocalizedString() + +class PluralsResource(@PluralsRes val id: Int, val quantity: Int) : LocalizedString() diff --git a/app/src/main/java/org/sirekanyan/outline/ext/Toast.kt b/app/src/main/java/org/sirekanyan/outline/ext/Toast.kt index 756b5b9..d5f4a0b 100644 --- a/app/src/main/java/org/sirekanyan/outline/ext/Toast.kt +++ b/app/src/main/java/org/sirekanyan/outline/ext/Toast.kt @@ -7,3 +7,7 @@ import androidx.annotation.StringRes fun Context.showToast(@StringRes text: Int) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show() } + +fun Context.showToast(text: LocalizedString) { + Toast.makeText(this, getString(text), Toast.LENGTH_SHORT).show() +}