diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LoadError.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LoadError.kt new file mode 100644 index 00000000..e5ac470a --- /dev/null +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LoadError.kt @@ -0,0 +1,63 @@ +package dev.msfjarvis.claw.android.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.unit.dp +import androidx.paging.LoadState + +@Composable +fun LoadError( + data: LoadState.Error, + modifier: Modifier = Modifier, +) { + var showDialog by remember { mutableStateOf(false) } + Column(verticalArrangement = Arrangement.spacedBy(4.dp), modifier = modifier) { + Text( + text = "Failed to load posts", + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.align(Alignment.CenterHorizontally), + ) + Button( + onClick = { showDialog = true }, + modifier = Modifier.align(Alignment.CenterHorizontally), + ) { + Text(text = "Show error") + } + } + if (showDialog) { + val clipboard = LocalClipboardManager.current + AlertDialog( + onDismissRequest = { showDialog = false }, + confirmButton = { + Text( + text = "Copy stacktrace", + modifier = + Modifier.clickable { + clipboard.setText(AnnotatedString(data.error.stackTraceToString())) + showDialog = false + } + ) + }, + text = { + Text( + text = "${data.error.message}", + style = MaterialTheme.typography.bodyLarge, + ) + } + ) + } +} diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt index 7379a039..f1c7be89 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/lists/NetworkPosts.kt @@ -8,6 +8,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems @@ -15,6 +16,7 @@ import androidx.paging.compose.items import com.google.accompanist.swiperefresh.SwipeRefresh import com.google.accompanist.swiperefresh.SwipeRefreshIndicator import com.google.accompanist.swiperefresh.rememberSwipeRefreshState +import dev.msfjarvis.claw.android.ui.LoadError import dev.msfjarvis.claw.common.posts.PostActions import dev.msfjarvis.claw.common.posts.toDbModel import dev.msfjarvis.claw.database.local.SavedPost @@ -29,7 +31,8 @@ fun NetworkPosts( postActions: PostActions, modifier: Modifier = Modifier, ) { - val isRefreshing = items.loadState.refresh == LoadState.Loading + val loadState = items.loadState.refresh + val isRefreshing = loadState == LoadState.Loading SwipeRefresh( state = rememberSwipeRefreshState(isRefreshing), onRefresh = reloadPosts, @@ -44,7 +47,11 @@ fun NetworkPosts( } ) { if (items.itemCount == 0) { - Box(modifier = Modifier.fillMaxSize()) + Box(modifier = Modifier.fillMaxSize()) { + if (loadState is LoadState.Error) { + LoadError(data = loadState, modifier = Modifier.align(Alignment.Center)) + } + } } else { LazyColumn( state = listState,