Skip to content

Instantly share code, notes, and snippets.

View euri16's full-sized avatar

Eury Perez euri16

View GitHub Profile
val viewEffect = uiState.map { it.effect }
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,
)
@Composable
fun UserProfileScreen(
viewModel: UserProfileViewModel = hiltViewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
// Handle effects
LaunchedEffect(uiState.errorToShow) {
uiState.errorToShow?.let { errorToShow ->
showErrorDialog(errorToShow)
data class UserProfileUiState(
val isLoading: Boolean = false,
val user: User? = null,
val errorToShow: String? = null
)
class UserProfileViewModel(
private val userRepository: UserRepository
) : ViewModel() {
// SharedFlow without replay - loses events immediately
private val _sharedFlowEvents = MutableSharedFlow<UIEvent>()
viewModelScope.launch { // Already uses Dispatchers.Main.immediate
delay(3000) // User goes to background
_sharedFlowEvents.emit(UIEvent.Navigate) // LOST - no active collectors
}
// Channel - buffers events even without collectors
private val _channelEvents = Channel<UIEvent>()
@Composable
fun UserProfileScreen(
viewModel: UserProfileViewModel = hiltViewModel()
) {
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(viewModel.events, lifecycleOwner) {
viewModel.events.flowWithLifecycle(lifecycleOwner.lifecycle)
.onEach {
when (event) {
sealed class UIEvent {
object NavigateToLogin : UIEvent()
data class ShowError(val error: String) : UIEvent()
}
class UserProfileViewModel(
private val userRepository: UserRepository
) : ViewModel() {
private val _events = Channel<UIEvent>()
class NoConsumptionTrackingViewModel : ViewModel() {
private val _events = MutableSharedFlow<UIEvent>(replay = 1)
val events = _events.asSharedFlow()
fun showImportantDialog() {
viewModelScope.launch {
_events.emit(UIEvent.ShowCriticalDialog)
}
}
}
@Composable
fun UserProfileScreen(
viewModel: UserProfileViewModel = hiltViewModel()
) {
val navController = LocalNavController.current
val events by viewModel.events.collectAsStateWithLifecycle(initialValue = null)
// Handle events when they change
LaunchedEffect(events) {
events?.let { event ->
sealed class UIEvent {
object NavigateToLogin : UIEvent()
data class ShowError(val error: String) : UIEvent()
}
class UserProfileViewModel(
private val userRepository: UserRepository
) : ViewModel() {
// UI state management (normal StateFlow usage)