Fix chat folders flickering during drag and drop.

Fixes the UI flickering that occurs when reordering chat folders. The issue was caused by the ViewModel updating the database each time a list item position changes when we were already updating list order in the UI state manually at the same time.
This commit is contained in:
Jeffrey Starke
2025-04-24 11:21:09 -04:00
committed by Cody Henthorne
parent 62ed823e42
commit 9d593bcaff
2 changed files with 25 additions and 17 deletions

View File

@@ -101,7 +101,13 @@ class ChatFoldersFragment : ComposeFragment() {
onDeleteDismissed = {
viewModel.showDeleteDialog(false)
},
onPositionUpdated = { fromIndex, toIndex -> viewModel.updatePosition(fromIndex, toIndex) }
onDragAndDropEvent = { event ->
when (event) {
is DragAndDropEvent.OnItemMove -> viewModel.updateItemPosition(event.fromIndex, event.toIndex)
is DragAndDropEvent.OnItemDrop -> viewModel.saveItemPositions()
is DragAndDropEvent.OnDragCancel -> {}
}
}
)
}
}
@@ -117,16 +123,12 @@ fun FoldersScreen(
onDeleteClicked: (ChatFolderRecord) -> Unit = {},
onDeleteConfirmed: () -> Unit = {},
onDeleteDismissed: () -> Unit = {},
onPositionUpdated: (Int, Int) -> Unit = { _, _ -> }
onDragAndDropEvent: (DragAndDropEvent) -> Unit = {}
) {
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val isRtl = ViewUtil.isRtl(LocalContext.current)
val listState = rememberLazyListState()
val dragDropState = rememberDragDropState(listState, includeHeader = true, includeFooter = true) { event ->
if (event is DragAndDropEvent.OnItemMove) {
onPositionUpdated(event.fromIndex, event.toIndex)
}
}
val dragDropState = rememberDragDropState(listState, includeHeader = true, includeFooter = true, onEvent = onDragAndDropEvent)
LaunchedEffect(Unit) {
if (!SignalStore.uiHints.hasSeenChatFoldersEducationSheet) {

View File

@@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.signal.core.util.swap
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.contacts.paged.ChatType
import org.thoughtcrime.securesms.database.SignalDatabase
@@ -177,17 +178,22 @@ class ChatFoldersViewModel : ViewModel() {
}
}
fun updatePosition(fromIndex: Int, toIndex: Int) {
viewModelScope.launch(Dispatchers.IO) {
val folders = state.value.folders.toMutableList().apply { add(toIndex, removeAt(fromIndex)) }
val updatedFolders = folders.mapIndexed { index, chatFolderRecord ->
chatFolderRecord.copy(position = index)
}
ChatFoldersRepository.updatePositions(updatedFolders)
fun updateItemPosition(fromIndex: Int, toIndex: Int) {
val folders = state.value.folders.swap(fromIndex, toIndex)
val updatedFolders = folders.mapIndexed { index, chatFolderRecord ->
chatFolderRecord.copy(position = index)
}
internalState.update {
it.copy(folders = updatedFolders)
}
}
internalState.update {
it.copy(folders = updatedFolders)
}
fun saveItemPositions() {
val updatedFolders = state.value.folders.mapIndexed { index, chatFolderRecord ->
chatFolderRecord.copy(position = index)
}
viewModelScope.launch(Dispatchers.IO) {
ChatFoldersRepository.updatePositions(updatedFolders)
}
}