diff --git a/appcompose/src/main/java/com/readrops/app/compose/account/credentials/AccountCredentialsScreen.kt b/appcompose/src/main/java/com/readrops/app/compose/account/credentials/AccountCredentialsScreen.kt
index 18a6c15a..4089c468 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/account/credentials/AccountCredentialsScreen.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/account/credentials/AccountCredentialsScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
@@ -178,7 +179,7 @@ class AccountCredentialsScreen(
ShortSpacer()
Text(
- text = ErrorMessage.get(exception = state.loginException!!),
+ text = ErrorMessage.get(state.loginException!!, LocalContext.current),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.error
)
diff --git a/appcompose/src/main/java/com/readrops/app/compose/timelime/ErrorListDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/timelime/ErrorListDialog.kt
index d3763452..f7606a91 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/timelime/ErrorListDialog.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/timelime/ErrorListDialog.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
@@ -44,7 +45,7 @@ fun ErrorListDialog(
modifier = Modifier.verticalScroll(scrollableState)
) {
for (error in errorResult.entries) {
- Text(text = "${error.key.name}: ${ErrorMessage.get(error.value)}")
+ Text(text = "${error.key.name}: ${ErrorMessage.get(error.value, LocalContext.current)}")
ShortSpacer()
}
diff --git a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineScreenModel.kt b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineScreenModel.kt
index 3fd89f21..36ecba6e 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineScreenModel.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineScreenModel.kt
@@ -2,7 +2,6 @@ package com.readrops.app.compose.timelime
import android.content.Context
import android.content.Intent
-import android.util.Log
import androidx.compose.runtime.Stable
import androidx.paging.Pager
import androidx.paging.PagingConfig
@@ -32,6 +31,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapConcat
+import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
@@ -68,6 +68,11 @@ class TimelineScreenModel(
database.newItemDao().selectAll(query)
},
).flow
+ .transformLatest { value ->
+ if (!timelineState.value.isRefreshing) {
+ emit(value)
+ }
+ }
.cachedIn(screenModelScope),
isAccountLocal = account.isLocal
)
@@ -102,11 +107,11 @@ class TimelineScreenModel(
} else {
_timelineState.update { it.copy(isRefreshing = true) }
- repository?.synchronize()
try {
+ repository?.synchronize()
} catch (e: Exception) {
- // handle sync exceptions
- Log.d("TimelineScreenModel", "refreshTimeline: ${e.message}")
+ _timelineState.update { it.copy(syncError = e, isRefreshing = false) }
+ return@launch
}
_timelineState.update {
@@ -160,7 +165,7 @@ class TimelineScreenModel(
it.copy(
isRefreshing = false,
endSynchronizing = true,
- synchronizationErrors = if (results!!.second.isNotEmpty()) results.second else null
+ localSyncErrors = if (results!!.second.isNotEmpty()) results.second else null
)
}
}
@@ -287,7 +292,7 @@ class TimelineScreenModel(
fun closeDialog(dialog: DialogState? = null) {
if (dialog is DialogState.ErrorList) {
- _timelineState.update { it.copy(synchronizationErrors = null) }
+ _timelineState.update { it.copy(localSyncErrors = null) }
}
_timelineState.update { it.copy(dialog = null) }
@@ -329,7 +334,8 @@ data class TimelineState(
val feedCount: Int = 0,
val feedMax: Int = 0,
val endSynchronizing: Boolean = false,
- val synchronizationErrors: ErrorResult? = null,
+ val localSyncErrors: ErrorResult? = null,
+ val syncError: Exception? = null,
val filters: QueryFilters = QueryFilters(),
val filterFeedName: String = "",
val filterFolderName: String = "",
diff --git a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineTab.kt b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineTab.kt
index c04e9f45..1c4b2efc 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineTab.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/timelime/TimelineTab.kt
@@ -52,6 +52,7 @@ import cafe.adriel.voyager.navigator.tab.TabOptions
import com.readrops.app.compose.R
import com.readrops.app.compose.item.ItemScreen
import com.readrops.app.compose.timelime.drawer.TimelineDrawer
+import com.readrops.app.compose.util.ErrorMessage
import com.readrops.app.compose.util.components.CenteredProgressIndicator
import com.readrops.app.compose.util.components.Placeholder
import com.readrops.app.compose.util.components.RefreshScreen
@@ -127,25 +128,31 @@ object TimelineTab : Tab {
}
}
- LaunchedEffect(state.synchronizationErrors) {
- if (state.synchronizationErrors != null) {
+ LaunchedEffect(state.localSyncErrors) {
+ if (state.localSyncErrors != null) {
val action = snackbarHostState.showSnackbar(
message = context.resources.getQuantityString(
R.plurals.error_occurred,
- state.synchronizationErrors!!.size
+ state.localSyncErrors!!.size
),
actionLabel = context.getString(R.string.details),
duration = SnackbarDuration.Short
)
if (action == SnackbarResult.ActionPerformed) {
- viewModel.openDialog(DialogState.ErrorList(state.synchronizationErrors!!))
+ viewModel.openDialog(DialogState.ErrorList(state.localSyncErrors!!))
} else {
// remove errors from state
- viewModel.closeDialog(DialogState.ErrorList(state.synchronizationErrors!!))
+ viewModel.closeDialog(DialogState.ErrorList(state.localSyncErrors!!))
}
}
}
+
+ LaunchedEffect(state.syncError) {
+ if (state.syncError != null) {
+ snackbarHostState.showSnackbar(ErrorMessage.get(state.syncError!!, context))
+ }
+ }
when (val dialog = state.dialog) {
is DialogState.ConfirmDialog -> {
diff --git a/appcompose/src/main/java/com/readrops/app/compose/util/ErrorMessage.kt b/appcompose/src/main/java/com/readrops/app/compose/util/ErrorMessage.kt
index f7ce9503..cee30fd9 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/util/ErrorMessage.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/util/ErrorMessage.kt
@@ -1,7 +1,6 @@
package com.readrops.app.compose.util
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.res.stringResource
+import android.content.Context
import com.readrops.api.utils.exceptions.HttpException
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.exceptions.UnknownFormatException
@@ -11,33 +10,31 @@ import java.net.UnknownHostException
object ErrorMessage {
- @Composable
- fun get(exception: Exception) = when (exception) {
- is HttpException -> getHttpMessage(exception)
- is UnknownHostException -> stringResource(R.string.unreachable_url)
- is NoSuchFileException -> stringResource(R.string.unable_open_file)
- is IOException -> stringResource(R.string.network_failure, exception.message.orEmpty())
- is ParseException, is UnknownFormatException -> stringResource(R.string.processing_feed_error)
+ fun get(exception: Exception, context: Context) = when (exception) {
+ is HttpException -> getHttpMessage(exception, context)
+ is UnknownHostException -> context.resources.getString(R.string.unreachable_url)
+ is NoSuchFileException -> context.resources.getString(R.string.unable_open_file)
+ is IOException -> context.resources.getString(R.string.network_failure, exception.message.orEmpty())
+ is ParseException, is UnknownFormatException -> context.resources.getString(R.string.processing_feed_error)
else -> "${exception.javaClass.simpleName}: ${exception.message}"
}
- @Composable
- private fun getHttpMessage(exception: HttpException): String {
+ private fun getHttpMessage(exception: HttpException, context: Context): String {
return when (exception.code) {
in 400..499 -> {
when (exception.code) {
- 400 -> stringResource(id = R.string.http_error_400)
- 401 -> stringResource(id = R.string.http_error_401)
- 403 -> stringResource(id = R.string.http_error_403)
- 404 -> stringResource(id = R.string.http_error_404)
- else -> stringResource(id = R.string.http_error_4XX, exception.code)
+ 400 -> context.resources.getString(R.string.http_error_400)
+ 401 -> context.resources.getString(R.string.http_error_401)
+ 403 -> context.resources.getString(R.string.http_error_403)
+ 404 -> context.resources.getString(R.string.http_error_404)
+ else -> context.resources.getString(R.string.http_error_4XX, exception.code)
}
}
in 500..599 -> {
- stringResource(id = R.string.http_error_5XX, exception.code)
+ context.resources.getString(R.string.http_error_5XX, exception.code)
}
- else -> stringResource(id = R.string.http_error, exception.code)
+ else -> context.resources.getString(R.string.http_error, exception.code)
}
}
}
\ No newline at end of file
diff --git a/appcompose/src/main/java/com/readrops/app/compose/util/components/ErrorDialog.kt b/appcompose/src/main/java/com/readrops/app/compose/util/components/ErrorDialog.kt
index 53737e75..7bd3e770 100644
--- a/appcompose/src/main/java/com/readrops/app/compose/util/components/ErrorDialog.kt
+++ b/appcompose/src/main/java/com/readrops/app/compose/util/components/ErrorDialog.kt
@@ -2,6 +2,7 @@ package com.readrops.app.compose.util.components
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.readrops.app.compose.R
@@ -17,7 +18,7 @@ fun ErrorDialog(
icon = painterResource(id = R.drawable.ic_error),
onDismiss = onDismiss
) {
- Text(text = ErrorMessage.get(exception = exception))
+ Text(text = ErrorMessage.get(exception, LocalContext.current))
}
}
diff --git a/appcompose/src/main/res/values-fr/strings.xml b/appcompose/src/main/res/values-fr/strings.xml
index c5e6eea8..31f51614 100644
--- a/appcompose/src/main/res/values-fr/strings.xml
+++ b/appcompose/src/main/res/values-fr/strings.xml
@@ -161,7 +161,7 @@
Erreur HTTP 401, veuillez vérifier vos identifiants
Erreur HTTP 403, accès interdit
Erreur HTTP 404, l\'URL n\'existe pas
- Erreur HTTP %1$s, veuillez vérifier vos champs
- Erreur HTTP %1$s, erreur serveur
- Erreur HTTP %1$s
+ Erreur HTTP %1$d, veuillez vérifier vos champs
+ Erreur HTTP %1$d, erreur serveur
+ Erreur HTTP %1$d
\ No newline at end of file
diff --git a/appcompose/src/main/res/values/strings.xml b/appcompose/src/main/res/values/strings.xml
index 03a6eff1..cf90ecb2 100644
--- a/appcompose/src/main/res/values/strings.xml
+++ b/appcompose/src/main/res/values/strings.xml
@@ -167,7 +167,7 @@
HTTP error 401, please check your credentials
HTTP error 403, access forbidden
HTTP error 404, URL not found
- HTTP error %1$s, please check your fields
- HTTP error %1$s, server error
- HTTP error %1$s
+ HTTP error %1$d, please check your fields
+ HTTP error %1$d, server error
+ HTTP error %1$d
\ No newline at end of file