gracefully handling errors within the profile screen
This commit is contained in:
parent
347074b10f
commit
21be4a4b1d
|
@ -161,7 +161,7 @@ internal class FeatureModules internal constructor(
|
||||||
coroutineDispatchers
|
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 {
|
val notificationsModule by unsafeLazy {
|
||||||
NotificationsModule(
|
NotificationsModule(
|
||||||
matrixModules.push,
|
matrixModules.push,
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package app.dapk.st.profile
|
package app.dapk.st.profile
|
||||||
|
|
||||||
import app.dapk.st.core.ProvidableModule
|
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.ProfileService
|
||||||
import app.dapk.st.matrix.room.RoomService
|
import app.dapk.st.matrix.room.RoomService
|
||||||
import app.dapk.st.matrix.sync.SyncService
|
import app.dapk.st.matrix.sync.SyncService
|
||||||
|
@ -9,10 +10,11 @@ class ProfileModule(
|
||||||
private val profileService: ProfileService,
|
private val profileService: ProfileService,
|
||||||
private val syncService: SyncService,
|
private val syncService: SyncService,
|
||||||
private val roomService: RoomService,
|
private val roomService: RoomService,
|
||||||
|
private val errorTracker: ErrorTracker,
|
||||||
) : ProvidableModule {
|
) : ProvidableModule {
|
||||||
|
|
||||||
fun profileViewModel(): ProfileViewModel {
|
fun profileViewModel(): ProfileViewModel {
|
||||||
return ProfileViewModel(profileService, syncService, roomService)
|
return ProfileViewModel(profileService, syncService, roomService, errorTracker)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -67,6 +67,7 @@ private fun ProfilePage(context: Context, viewModel: ProfileViewModel, profile:
|
||||||
|
|
||||||
when (val state = profile.content) {
|
when (val state = profile.content) {
|
||||||
is Lce.Loading -> CenteredLoading()
|
is Lce.Loading -> CenteredLoading()
|
||||||
|
is Lce.Error -> GenericError { viewModel.start() }
|
||||||
is Lce.Content -> {
|
is Lce.Content -> {
|
||||||
val configuration = LocalConfiguration.current
|
val configuration = LocalConfiguration.current
|
||||||
val content = state.value
|
val content = state.value
|
||||||
|
|
|
@ -2,6 +2,7 @@ package app.dapk.st.profile
|
||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import app.dapk.st.core.Lce
|
import app.dapk.st.core.Lce
|
||||||
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.design.components.SpiderPage
|
import app.dapk.st.design.components.SpiderPage
|
||||||
import app.dapk.st.matrix.common.RoomId
|
import app.dapk.st.matrix.common.RoomId
|
||||||
import app.dapk.st.matrix.room.ProfileService
|
import app.dapk.st.matrix.room.ProfileService
|
||||||
|
@ -16,6 +17,7 @@ class ProfileViewModel(
|
||||||
private val profileService: ProfileService,
|
private val profileService: ProfileService,
|
||||||
private val syncService: SyncService,
|
private val syncService: SyncService,
|
||||||
private val roomService: RoomService,
|
private val roomService: RoomService,
|
||||||
|
private val errorTracker: ErrorTracker,
|
||||||
) : DapkViewModel<ProfileScreenState, ProfileEvent>(
|
) : DapkViewModel<ProfileScreenState, ProfileEvent>(
|
||||||
ProfileScreenState(SpiderPage(Page.Routes.profile, "Profile", null, Page.Profile(Lce.Loading()), hasToolbar = false))
|
ProfileScreenState(SpiderPage(Page.Routes.profile, "Profile", null, Page.Profile(Lce.Loading()), hasToolbar = false))
|
||||||
) {
|
) {
|
||||||
|
@ -31,13 +33,20 @@ class ProfileViewModel(
|
||||||
syncingJob = syncService.startSyncing().launchIn(viewModelScope)
|
syncingJob = syncService.startSyncing().launchIn(viewModelScope)
|
||||||
|
|
||||||
combine(
|
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(),
|
syncService.invites(),
|
||||||
transform = { me, invites -> me to invites }
|
transform = { me, invites -> me to invites }
|
||||||
)
|
)
|
||||||
.onEach { (me, invites) ->
|
.onEach { (me, invites) ->
|
||||||
updatePageState<Page.Profile> {
|
updatePageState<Page.Profile> {
|
||||||
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()
|
.launchPageJob()
|
||||||
|
|
Loading…
Reference in New Issue