mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 07:21:58 +00:00
feat: adding retry logic to library
This commit is contained in:
parent
5a0b623773
commit
1e75f416e4
2 changed files with 39 additions and 22 deletions
|
|
@ -50,6 +50,12 @@ fun LibraryScreen(
|
|||
var observedOfflineState by remember { mutableStateOf(false) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val isTraktSource = uiState.sourceMode == LibrarySourceMode.TRAKT
|
||||
val retryLibraryLoad: () -> Unit = {
|
||||
NetworkStatusRepository.requestRefresh(force = true)
|
||||
coroutineScope.launch {
|
||||
LibraryRepository.pullFromServer(ProfileRepository.activeProfileId)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(networkStatusUiState.condition, isTraktSource) {
|
||||
when (networkStatusUiState.condition) {
|
||||
|
|
@ -110,14 +116,7 @@ fun LibraryScreen(
|
|||
NuvioNetworkOfflineCard(
|
||||
condition = networkStatusUiState.condition,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
onRetry = {
|
||||
NetworkStatusRepository.requestRefresh(force = true)
|
||||
if (isTraktSource) {
|
||||
coroutineScope.launch {
|
||||
LibraryRepository.pullFromServer(ProfileRepository.activeProfileId)
|
||||
}
|
||||
}
|
||||
},
|
||||
onRetry = retryLibraryLoad,
|
||||
)
|
||||
} else {
|
||||
HomeEmptyStateCard(
|
||||
|
|
@ -128,6 +127,8 @@ fun LibraryScreen(
|
|||
stringResource(Res.string.library_load_failed)
|
||||
},
|
||||
message = uiState.errorMessage.orEmpty(),
|
||||
actionLabel = stringResource(Res.string.action_retry),
|
||||
onActionClick = retryLibraryLoad,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -139,12 +140,7 @@ fun LibraryScreen(
|
|||
NuvioNetworkOfflineCard(
|
||||
condition = networkStatusUiState.condition,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
onRetry = {
|
||||
NetworkStatusRepository.requestRefresh(force = true)
|
||||
coroutineScope.launch {
|
||||
LibraryRepository.pullFromServer(ProfileRepository.activeProfileId)
|
||||
}
|
||||
},
|
||||
onRetry = retryLibraryLoad,
|
||||
)
|
||||
} else {
|
||||
HomeEmptyStateCard(
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ private const val LIST_FETCH_CONCURRENCY = 4
|
|||
private const val SNAPSHOT_CACHE_TTL_MS = 60_000L
|
||||
private const val LIST_TABS_CACHE_TTL_MS = 60_000L
|
||||
private const val FORCE_REFRESH_DEDUP_MS = 10_000L
|
||||
private const val MAX_VISIBLE_ERROR_MESSAGE_LENGTH = 240
|
||||
|
||||
data class TraktLibraryUiState(
|
||||
val listTabs: List<TraktListTab> = emptyList(),
|
||||
|
|
@ -159,21 +160,20 @@ object TraktLibraryRepository {
|
|||
errorMessage = null,
|
||||
)
|
||||
}
|
||||
}.onFailure { error ->
|
||||
}
|
||||
result.exceptionOrNull()?.let { error ->
|
||||
if (error is CancellationException) throw error
|
||||
log.w { "Failed to refresh Trakt library: ${error.message}" }
|
||||
}.getOrNull()
|
||||
|
||||
if (result == null) {
|
||||
_uiState.value = current.copy(
|
||||
log.w(error) { "Failed to refresh Trakt library" }
|
||||
_uiState.value = _uiState.value.copy(
|
||||
isLoading = false,
|
||||
hasLoaded = true,
|
||||
errorMessage = getString(Res.string.trakt_library_load_failed),
|
||||
errorMessage = traktLibraryLoadErrorMessage(error),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
_uiState.value = result.copy(
|
||||
val snapshot = result.getOrThrow()
|
||||
_uiState.value = snapshot.copy(
|
||||
isLoading = false,
|
||||
hasLoaded = true,
|
||||
errorMessage = null,
|
||||
|
|
@ -414,6 +414,27 @@ object TraktLibraryRepository {
|
|||
TraktLibraryStorage.savePayload(json.encodeToString(payload))
|
||||
}
|
||||
|
||||
private suspend fun traktLibraryLoadErrorMessage(error: Throwable): String {
|
||||
val fallback = getString(Res.string.trakt_library_load_failed)
|
||||
val detail = error.userVisibleMessage()
|
||||
return when {
|
||||
detail.isBlank() -> fallback
|
||||
detail.equals(fallback, ignoreCase = true) -> fallback
|
||||
else -> detail
|
||||
}
|
||||
}
|
||||
|
||||
private fun Throwable.userVisibleMessage(): String {
|
||||
val raw = message?.trim()?.takeIf { it.isNotBlank() }
|
||||
?: toString().trim()
|
||||
val firstLine = raw.lines().firstOrNull()?.trim().orEmpty()
|
||||
return if (firstLine.length <= MAX_VISIBLE_ERROR_MESSAGE_LENGTH) {
|
||||
firstLine
|
||||
} else {
|
||||
firstLine.take(MAX_VISIBLE_ERROR_MESSAGE_LENGTH).trimEnd() + "..."
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchListTabs(headers: Map<String, String>): List<TraktListTab> {
|
||||
val watchlistTabs = listOf(
|
||||
TraktListTab(
|
||||
|
|
|
|||
Loading…
Reference in a new issue