I have two flows: activityState and activityUiState. I need the activityUiState to be of type MutableStateFlow, so I'm using the activityState as a Flow to update the value of the activityUiState. The activityState and subsequently activityUiState should be updated when selectedActivityId's value changes, however, that is often not the case. Could you tell me how to correct this code so that both activityState and activityUiState stay up to date?
val selectedActivityId = MutableStateFlow(savedStateHandle.get(ACTIVITY_ID_SAVED_STATE_KEY))
val activityUiState = MutableStateFlow(ActivityUiState())
selectedActivityId.flatMapLatest { activityId ->
@OptIn(ExperimentalCoroutinesApi::class)
val activityState = selectedActivityId.flatMapLatest { activityId ->
if (activityId == null) return@flatMapLatest flowOf(ActivityUiState())
val flowOfActivity = activitiesRepository.getActivityStream(activityId)
val flowOfSubActivities = activitiesRepository.getSubActivitiesPerMainActivity(activityId).flatMapLatest { subActivities ->
val subActivitiesUiStates = subActivities.map { subActivity ->
voiceNotesRepository.getAllVoiceNotesPerActivity(subActivity.id).map { voiceNotes ->
ActivityUiState(
date = subActivity.date,
id = subActivity.id,
title = subActivity.title,
note = subActivity.note,
startTime = subActivity.startTime,
endTime = subActivity.endTime,
voiceNotesUiState = voiceNotes.map { voiceNote ->
VoiceNoteUiState(
id = voiceNote.id,
uri = voiceNote.uri,
duration = voiceNote.duration,
timestamp = voiceNote.timestamp,
activityId = subActivity.id
)
},
mainActivityId = subActivity.mainActivityId
)
}
}
combine(subActivitiesUiStates) { it -> it.toList() }
}
combine(
flowOfActivity,
flowOfSubActivities,
voiceNotesRepository.getAllVoiceNotesPerActivity(activityId)
) { activity, subActivitiesUiStates, voiceNotes ->
activity?.let {
activityUiState.update {
it.copy(
date = activity.date,
id = activity.id,
title = activity.title,
note = activity.note,
startTime = activity.startTime,
endTime = activity.endTime,
voiceNotesUiState = voiceNotes.map{ voiceNote ->
VoiceNoteUiState(
id = voiceNote.id,
uri = voiceNote.uri,
duration = voiceNote.duration,
timestamp = voiceNote.timestamp,
activityId = activity.id
)
},
subActivitiesUiState = subActivitiesUiStates
)
}
ActivityUiState(
date = activity.date,
id = activity.id,
title = activity.title,
note = activity.note,
startTime = activity.startTime,
endTime = activity.endTime,
voiceNotesUiState = voiceNotes.map{ voiceNote ->
VoiceNoteUiState(
id = voiceNote.id,
uri = voiceNote.uri,
duration = voiceNote.duration,
timestamp = voiceNote.timestamp,
activityId = activity.id
)
},
subActivitiesUiState = subActivitiesUiStates
)
} ?:run {
activityUiState.update {
ActivityUiState()
}
ActivityUiState()
}
}
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000L),
initialValue = ActivityUiState()
)
fun selectActivity(id: UUID?) {
selectedActivityId.value = id
}