-
Notifications
You must be signed in to change notification settings - Fork 41
Description
I am working on a list where once a re-order is performed, it goes to the backend and makes a call. If that call fails I expect it to revert back to the original state. I have the code here:
// ListViewModel
data class ListState(
val items: List<ListItemUiState> = emptyList(),
val previousItems: List<ListItemUiState> = emptyList(),
)
class ListViewModel : ViewModel() {
private val _uiStateFlow: MutableStateFlow<ListState> = MutableStateFlow(ListState())
val uiStateFlow: StateFlow<ListState> = _uiStateFlow.asStateFlow()
fun onMove(from: Int, to: Int) {
viewModelScope.launch(Dispatchers.IO) {
_uiStateFlow.update {
val newItems = it.items.move(from = from, to = to)
it.copy(
items = newItems,
previousItems = it.items.toMutableList(),
)
}
val success = false // PerformMoveOnBackend()
_uiStateFlow.update {
val newPlanItems = if (success) it.items else it.previousItems
it.copy(
items = newPlanItems,
previousItems = emptyList(),
)
}
}
}
}Here is my ReorderableColumn Code.
// MyView
val viewModel = ListViewModel()
val state by viewModel.uiStateFlow.collectAsState()
ReorderableColumn(
list = state.items,
onSettle = { fromIndex, toIndex ->
viewModel.onMove(fromIndex, toIndex) }
},
) { _, item, _ ->
key(item.reorderId) { // UUID
when (item) {
is ListItemUiState.Section -> { Section(item.text) }
is ListItemUiState.Item -> {
Card(modifier = Modifier.longPressDraggableHandle(item.draggable)) {
Text(item.title)
}
}
}
}
}
The problem is that if the call fails, then the StateFlow is reverted to its original state, however the Column doesn't update to reflect this. I'm guessing that it's not handling the latest state change, or however it's handling when it refreshes is causing an issue. Maybe an issue with the ReorderableListState? This might be because it's updating the state immediately (i.e. there's not enough time inbetween the two state updates), because if I add a delay after the backend call then it seems to work correctly.
Expectation:
I expect that the column matches the state no matter how often you update it
Actual:
It seems that the column is ignoring subsequent updates if they are performed too often. If you do two updates in a row, the reorder only picks up the first, where a normal list picks up the second.
Here is the visual evidence.