refactor: streamline drag-and-drop reordering logic in ManageColumnsDialog and ListsScreen for consistency
This commit is contained in:
+33
-61
@@ -6,7 +6,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.gestures.detectDragGestures
|
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -40,8 +39,6 @@ import androidx.compose.material.icons.filled.DateRange
|
|||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.DragHandle
|
import androidx.compose.material.icons.filled.DragHandle
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
|
||||||
import androidx.compose.material.icons.filled.List
|
import androidx.compose.material.icons.filled.List
|
||||||
import androidx.compose.material.icons.filled.Menu
|
import androidx.compose.material.icons.filled.Menu
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
@@ -2499,28 +2496,31 @@ fun ManageColumnsDialog(
|
|||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
// Column list with drag-and-drop reordering
|
// Column list with drag-and-drop reordering
|
||||||
|
// Local extension mirroring the working behavior used in ListsScreen
|
||||||
|
fun <T> MutableList<T>.move(
|
||||||
|
from: Int,
|
||||||
|
to: Int,
|
||||||
|
) {
|
||||||
|
if (from == to) return
|
||||||
|
if (isEmpty()) return
|
||||||
|
if (from !in indices) return
|
||||||
|
val item = removeAt(from)
|
||||||
|
val insertIndex =
|
||||||
|
when {
|
||||||
|
to > size -> size
|
||||||
|
to < 0 -> 0
|
||||||
|
else -> to
|
||||||
|
}
|
||||||
|
add(insertIndex, item)
|
||||||
|
}
|
||||||
|
|
||||||
val reorderState =
|
val reorderState =
|
||||||
rememberReorderableLazyListState(onMove = { from, to ->
|
rememberReorderableLazyListState(
|
||||||
if (reorderedFields.isEmpty()) return@rememberReorderableLazyListState
|
onMove = { from, to ->
|
||||||
val lastIndex = reorderedFields.lastIndex
|
// Use the same semantics as on the Lists screen for consistency
|
||||||
if (lastIndex < 0) return@rememberReorderableLazyListState
|
reorderedFields.move(from.index, to.index)
|
||||||
|
},
|
||||||
val fromIndex = from.index.coerceIn(0, lastIndex)
|
)
|
||||||
// Clamp target index into valid range; drop-at-end maps to lastIndex
|
|
||||||
val toIndex = to.index.coerceIn(0, lastIndex)
|
|
||||||
|
|
||||||
if (fromIndex in 0..lastIndex && toIndex in 0..lastIndex) {
|
|
||||||
if (fromIndex != toIndex && reorderedFields.isNotEmpty()) {
|
|
||||||
val item = reorderedFields.removeAt(fromIndex)
|
|
||||||
val newLastIndex = reorderedFields.lastIndex
|
|
||||||
var insertIndex = toIndex
|
|
||||||
// Adjust target when moving forward due to index shift after removal
|
|
||||||
if (fromIndex < toIndex) insertIndex = (toIndex - 1).coerceIn(0, newLastIndex + 1)
|
|
||||||
insertIndex = insertIndex.coerceIn(0, newLastIndex + 1)
|
|
||||||
reorderedFields.add(insertIndex, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier =
|
modifier =
|
||||||
@@ -2536,8 +2536,13 @@ fun ManageColumnsDialog(
|
|||||||
items = reorderedFields,
|
items = reorderedFields,
|
||||||
key = { _, field -> field.id },
|
key = { _, field -> field.id },
|
||||||
) { index, field ->
|
) { index, field ->
|
||||||
ReorderableItem(reorderState, key = field.id) { _ ->
|
ReorderableItem(
|
||||||
Box(modifier = Modifier.animateItemPlacement()) {
|
reorderState,
|
||||||
|
key = field.id,
|
||||||
|
) { _ ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.animateItemPlacement(),
|
||||||
|
) {
|
||||||
ColumnItem(
|
ColumnItem(
|
||||||
field = field,
|
field = field,
|
||||||
onEdit = { fieldToEdit = field },
|
onEdit = { fieldToEdit = field },
|
||||||
@@ -2661,7 +2666,8 @@ fun ColumnItem(
|
|||||||
dragHandle: (@Composable () -> Unit)? = null,
|
dragHandle: (@Composable () -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier =
|
||||||
|
Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
colors =
|
colors =
|
||||||
CardDefaults.cardColors(
|
CardDefaults.cardColors(
|
||||||
@@ -2682,40 +2688,6 @@ fun ColumnItem(
|
|||||||
if (dragHandle != null) {
|
if (dragHandle != null) {
|
||||||
dragHandle()
|
dragHandle()
|
||||||
}
|
}
|
||||||
Row {
|
|
||||||
IconButton(
|
|
||||||
onClick = onMoveUp,
|
|
||||||
enabled = canMoveUp,
|
|
||||||
modifier = Modifier.size(32.dp),
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.KeyboardArrowUp,
|
|
||||||
contentDescription = "Move up",
|
|
||||||
tint =
|
|
||||||
if (canMoveUp) {
|
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
IconButton(
|
|
||||||
onClick = onMoveDown,
|
|
||||||
enabled = canMoveDown,
|
|
||||||
modifier = Modifier.size(32.dp),
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.KeyboardArrowDown,
|
|
||||||
contentDescription = "Move down",
|
|
||||||
tint =
|
|
||||||
if (canMoveDown) {
|
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.3f)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
package com.collabtable.app.ui.screens
|
package com.collabtable.app.ui.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|||||||
Reference in New Issue
Block a user