diff --git a/design-library/src/main/kotlin/app/dapk/st/design/components/Spider.kt b/design-library/src/main/kotlin/app/dapk/st/design/components/Spider.kt index 826694b..55b8a12 100644 --- a/design-library/src/main/kotlin/app/dapk/st/design/components/Spider.kt +++ b/design-library/src/main/kotlin/app/dapk/st/design/components/Spider.kt @@ -10,22 +10,27 @@ fun Spider(currentPage: SpiderPage, onNavigate: (SpiderPage? val pageCache = remember { mutableMapOf, SpiderPage>() } pageCache[currentPage.route] = currentPage + val navigateAndPopStack = { + pageCache.remove(currentPage.route) + onNavigate(pageCache[currentPage.parent]) + } + val itemScope = object : SpiderItemScope { + override fun goBack() { + navigateAndPopStack() + } + } + val computedWeb = remember(true) { mutableMapOf, @Composable (T) -> Unit>().also { computedWeb -> val scope = object : SpiderScope { - override fun item(route: Route, content: @Composable (T) -> Unit) { - computedWeb[route] = { content(it as T) } + override fun item(route: Route, content: @Composable SpiderItemScope.(T) -> Unit) { + computedWeb[route] = { content(itemScope, it as T) } } } graph.invoke(scope) } } - val navigateAndPopStack = { - pageCache.remove(currentPage.route) - onNavigate(pageCache[currentPage.parent]) - } - Column { if (currentPage.hasToolbar) { Toolbar( @@ -40,7 +45,11 @@ fun Spider(currentPage: SpiderPage, onNavigate: (SpiderPage? interface SpiderScope { - fun item(route: Route, content: @Composable (T) -> Unit) + fun item(route: Route, content: @Composable SpiderItemScope.(T) -> Unit) +} + +interface SpiderItemScope { + fun goBack() } data class SpiderPage( diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt index d130dd3..5d1447e 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/MessengerScreen.kt @@ -43,10 +43,7 @@ import app.dapk.st.core.LifecycleEffect import app.dapk.st.core.StartObserving import app.dapk.st.core.components.CenteredLoading import app.dapk.st.core.extensions.takeIfContent -import app.dapk.st.design.components.MessengerUrlIcon -import app.dapk.st.design.components.MissingAvatarIcon -import app.dapk.st.design.components.SmallTalkTheme -import app.dapk.st.design.components.Toolbar +import app.dapk.st.design.components.* import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.UserId import app.dapk.st.matrix.sync.MessageMeta @@ -95,7 +92,7 @@ internal fun MessengerScreen( }) when (state.composerState) { is ComposerState.Text -> { - Room(state.roomState, replyActions) + Room(state.roomState, replyActions, onRetry = { viewModel.post(MessengerAction.OnMessengerVisible(roomId, attachments)) }) TextComposer( state.composerState, onTextChange = { viewModel.post(MessengerAction.ComposerTextUpdate(it)) }, @@ -132,7 +129,7 @@ private fun MessengerViewModel.ObserveEvents(galleryLauncher: ActivityResultLaun } @Composable -private fun ColumnScope.Room(roomStateLce: Lce, replyActions: ReplyActions) { +private fun ColumnScope.Room(roomStateLce: Lce, replyActions: ReplyActions, onRetry: () -> Unit) { when (val state = roomStateLce) { is Lce.Loading -> CenteredLoading() is Lce.Content -> { @@ -165,16 +162,7 @@ private fun ColumnScope.Room(roomStateLce: Lce, replyActions: Re } } - is Lce.Error -> { - Box(contentAlignment = Alignment.Center) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text("Something went wrong...") - Button(onClick = {}) { - Text("Retry") - } - } - } - } + is Lce.Error -> GenericError(cause = state.cause, action = onRetry) } } diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryActivity.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryActivity.kt index 06faf13..7ccd939 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryActivity.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryActivity.kt @@ -15,6 +15,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.lifecycleScope import app.dapk.st.core.* import app.dapk.st.core.extensions.unsafeLazy +import app.dapk.st.design.components.GenericError import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize @@ -59,7 +60,10 @@ fun Activity.PermissionGuard(state: State>, onGranted: @Co PermissionResult.ShowRational -> finish() } - is Lce.Error -> finish() + is Lce.Error -> GenericError(message = "Store permission required", label = "Close") { + finish() + } + is Lce.Loading -> { // loading should be quick, let's avoid displaying anything } diff --git a/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryScreen.kt b/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryScreen.kt index 8770857..daae82d 100644 --- a/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryScreen.kt +++ b/features/messenger/src/main/kotlin/app/dapk/st/messenger/gallery/ImageGalleryScreen.kt @@ -51,7 +51,6 @@ fun ImageGalleryScreen(viewModel: ImageGalleryViewModel, onTopLevelBack: () -> U } - @Composable fun ImageGalleryFolders(state: ImageGalleryPage.Folders, onClick: (Folder) -> Unit, onRetry: () -> Unit) { val screenWidth = LocalConfiguration.current.screenWidthDp diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt index 6d57470..889ecf4 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt @@ -119,7 +119,7 @@ private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile: } @Composable -private fun Invitations(viewModel: ProfileViewModel, invitations: Page.Invitations) { +private fun SpiderItemScope.Invitations(viewModel: ProfileViewModel, invitations: Page.Invitations) { when (val state = invitations.content) { is Lce.Loading -> CenteredLoading() is Lce.Content -> { @@ -147,7 +147,7 @@ private fun Invitations(viewModel: ProfileViewModel, invitations: Page.Invitatio } } - is Lce.Error -> TODO() + is Lce.Error -> GenericError(label = "Go back", cause = state.cause) { goBack() } } } diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt index 4ffb0a9..edf9bc3 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt @@ -63,7 +63,7 @@ internal fun SettingsScreen(viewModel: SettingsViewModel, onSignOut: () -> Unit, } Spider(currentPage = viewModel.state.page, onNavigate = onNavigate) { item(Page.Routes.root) { - RootSettings(it) { viewModel.onClick(it) } + RootSettings(it, onClick = { viewModel.onClick(it) }, onRetry = { viewModel.start() }) } item(Page.Routes.encryption) { Encryption(viewModel, it) @@ -180,7 +180,7 @@ internal fun SettingsScreen(viewModel: SettingsViewModel, onSignOut: () -> Unit, } @Composable -private fun RootSettings(page: Page.Root, onClick: (SettingItem) -> Unit) { +private fun RootSettings(page: Page.Root, onClick: (SettingItem) -> Unit, onRetry: () -> Unit) { when (val content = page.content) { is Lce.Content -> { LazyColumn( @@ -226,12 +226,10 @@ private fun RootSettings(page: Page.Root, onClick: (SettingItem) -> Unit) { } } - is Lce.Error -> { - // TODO - } + is Lce.Error -> GenericError(cause = content.cause, action = onRetry) is Lce.Loading -> { - // TODO + // Should be quick enough to avoid needing a loading state } } } @@ -264,7 +262,7 @@ private fun PushProviders(viewModel: SettingsViewModel, state: Page.PushProvider } } - is Lce.Error -> TODO() + is Lce.Error -> GenericError(cause = lce.cause) { viewModel.fetchPushProviders() } } } diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/eventlogger/EventLogScreen.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/eventlogger/EventLogScreen.kt index 8a7d76e..50cbfee 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/eventlogger/EventLogScreen.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/eventlogger/EventLogScreen.kt @@ -14,6 +14,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import app.dapk.st.core.AppLogTag import app.dapk.st.core.Lce +import app.dapk.st.core.components.CenteredLoading +import app.dapk.st.design.components.GenericError import app.dapk.st.matrix.common.MatrixLogTag private val filterItems = listOf(null) + (MatrixLogTag.values().map { it.key } + AppLogTag.values().map { it.key }).distinct() @@ -33,11 +35,13 @@ fun EventLogScreen(viewModel: EventLoggerViewModel) { viewModel.selectLog(it, filter = null) } } + else -> { Events( selectedPageContent = state.selectedState, onExit = { viewModel.exitLog() }, - onSelectTag = { viewModel.selectLog(state.selectedState.selectedPage, it) } + onSelectTag = { viewModel.selectLog(state.selectedState.selectedPage, it) }, + onRetry = { viewModel.start() }, ) } } @@ -46,6 +50,7 @@ fun EventLogScreen(viewModel: EventLoggerViewModel) { is Lce.Error -> { // TODO } + is Lce.Loading -> { // TODO } @@ -69,7 +74,7 @@ private fun LogKeysList(keys: List, onSelected: (String) -> Unit) { } @Composable -private fun Events(selectedPageContent: SelectedState, onExit: () -> Unit, onSelectTag: (String?) -> Unit) { +private fun Events(selectedPageContent: SelectedState, onExit: () -> Unit, onSelectTag: (String?) -> Unit, onRetry: () -> Unit) { BackHandler(onBack = onExit) when (val content = selectedPageContent.content) { is Lce.Content -> { @@ -112,9 +117,8 @@ private fun Events(selectedPageContent: SelectedState, onExit: () -> Unit, onSel } } } - is Lce.Error -> TODO() - is Lce.Loading -> { - // TODO - } + + is Lce.Error -> GenericError(cause = content.cause, action = onRetry) + is Lce.Loading -> CenteredLoading() } } \ No newline at end of file