diff --git a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt index 1d6f800..e77cb3e 100644 --- a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt +++ b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt @@ -161,7 +161,7 @@ internal class FeatureModules internal constructor( coroutineDispatchers ) } - val profileModule by unsafeLazy { ProfileModule(matrixModules.profile, matrixModules.sync, matrixModules.room) } + val profileModule by unsafeLazy { ProfileModule(matrixModules.profile, matrixModules.sync, matrixModules.room, trackingModule.errorTracker) } val notificationsModule by unsafeLazy { NotificationsModule( matrixModules.push, diff --git a/design-library/src/main/kotlin/app/dapk/st/design/components/Error.kt b/design-library/src/main/kotlin/app/dapk/st/design/components/Error.kt new file mode 100644 index 0000000..3242945 --- /dev/null +++ b/design-library/src/main/kotlin/app/dapk/st/design/components/Error.kt @@ -0,0 +1,22 @@ +package app.dapk.st.design.components + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +fun GenericError(retryAction: () -> Unit) { + Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Something went wrong...") + Button(onClick = { retryAction() }) { + Text("Retry") + } + } + } +} \ No newline at end of file diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt index 0fb5111..43d7d44 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt @@ -1,6 +1,7 @@ package app.dapk.st.profile import app.dapk.st.core.ProvidableModule +import app.dapk.st.core.extensions.ErrorTracker import app.dapk.st.matrix.room.ProfileService import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.sync.SyncService @@ -9,10 +10,11 @@ class ProfileModule( private val profileService: ProfileService, private val syncService: SyncService, private val roomService: RoomService, + private val errorTracker: ErrorTracker, ) : ProvidableModule { fun profileViewModel(): ProfileViewModel { - return ProfileViewModel(profileService, syncService, roomService) + return ProfileViewModel(profileService, syncService, roomService, errorTracker) } } \ No newline at end of file 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 e3a0f0d..f6371e9 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 @@ -67,6 +67,7 @@ private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile: when (val state = profile.content) { is Lce.Loading -> CenteredLoading() + is Lce.Error -> GenericError { viewModel.start() } is Lce.Content -> { val configuration = LocalConfiguration.current val content = state.value diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt index 484cdcf..ff4a017 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt @@ -2,6 +2,7 @@ package app.dapk.st.profile import androidx.lifecycle.viewModelScope import app.dapk.st.core.Lce +import app.dapk.st.core.extensions.ErrorTracker import app.dapk.st.design.components.SpiderPage import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.room.ProfileService @@ -16,6 +17,7 @@ class ProfileViewModel( private val profileService: ProfileService, private val syncService: SyncService, private val roomService: RoomService, + private val errorTracker: ErrorTracker, ) : DapkViewModel( ProfileScreenState(SpiderPage(Page.Routes.profile, "Profile", null, Page.Profile(Lce.Loading()), hasToolbar = false)) ) { @@ -31,13 +33,20 @@ class ProfileViewModel( syncingJob = syncService.startSyncing().launchIn(viewModelScope) combine( - flow { emit(profileService.me(forceRefresh = true)) }, + flow { + val result = runCatching { profileService.me(forceRefresh = true) } + .onFailure { errorTracker.track(it, "Loading profile") } + emit(result) + }, syncService.invites(), transform = { me, invites -> me to invites } ) .onEach { (me, invites) -> updatePageState { - copy(content = Lce.Content(Page.Profile.Content(me, invites.size))) + when (me.isSuccess) { + true -> copy(content = Lce.Content(Page.Profile.Content(me.getOrThrow(), invites.size))) + false -> copy(content = Lce.Error(me.exceptionOrNull()!!)) + } } } .launchPageJob()