Created
June 7, 2025 18:44
-
-
Save euri16/0de7a3b1b470473e88324f046bf6461e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed interface UserProfileEvent { | |
data object DeleteAccount : UserProfileEvent | |
data object ConsumeEffect : UserProfileEvent | |
} | |
sealed interface UserProfileEffect { | |
data class ShowError(val message: String) : UserProfileEffect | |
data object NavigateToLogin : UserProfileEffect | |
} | |
data class UserProfileUiState( | |
val isLoading: Boolean = false, | |
val user: User? = null, | |
val effect: UserProfileEffect? = null, | |
) | |
class UserProfileViewModel( | |
private val userRepository: UserRepository | |
) : ViewModel() { | |
private val _uiState = MutableStateFlow(UserProfileUiState()) | |
val uiState = _uiState.asStateFlow() | |
val effect = uiState.map { it.effect } | |
fun processEvent(event: UserProfileEvent) { | |
when (event) { | |
UserProfileEvent.DeleteAccount -> deleteAccount() | |
UserProfileEvent.ConsumeEffect -> consumeEffect() | |
} | |
} | |
private fun deleteAccount() { | |
viewModelScope.launch { | |
_uiState.update { it.copy(isLoading = true) } | |
try { | |
userRepository.deleteAccount() | |
_uiState.update { | |
it.copy( | |
isLoading = false, | |
effect = UserProfileEffect.NavigateToLogin | |
) | |
} | |
} catch (exception: Exception) { | |
_uiState.update { | |
it.copy( | |
isLoading = false, | |
effect = UserProfileEffect.ShowError(message = "An error occurred") | |
) | |
} | |
} | |
} | |
} | |
private fun consumeEffect() { | |
_uiState.update { it.copy(effect = null) } | |
} | |
} | |
// UI STARTS HERE | |
@Composable | |
fun UserProfileScreen( | |
viewModel: UserProfileViewModel = hiltViewModel() | |
) { | |
val uiState by viewModel.uiState.collectAsStateWithLifecycle() | |
Column { | |
Button( | |
onClick = { viewModel.processEvent(UserProfileEvent.DeleteAccount) }, | |
enabled = uiState.isLoading.not() | |
) { | |
Text("Delete Account") | |
} | |
} | |
EffectHandler(viewModel.effect, onEvent = viewModel::processEvent) | |
} | |
@Composable | |
private fun EffectHandler( | |
effectFlow: Flow<UserProfileEffect?>, | |
navController: NavHostController = LocalNavHostController.current, | |
onEvent: (UserProfileEvent) -> Unit, | |
) { | |
LaunchedUiEffectHandler( | |
effectFlow, | |
onConsumeEffect = { onEvent(UserProfileEvent.ConsumeEffect) }, | |
onEffect = { effect -> | |
when (effect) { | |
UserProfileEffect.NavigateToLogin -> { | |
navController.navigate(LoginRoute) | |
} | |
is UserProfileEffect.ShowError -> { | |
// Show error dialog or snackbar | |
showErrorDialog(effect.message) | |
} | |
} | |
} | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment