@@ -4,14 +4,19 @@ import androidx.compose.animation.core.LinearEasing
44import androidx.compose.animation.core.animateFloatAsState
55import androidx.compose.animation.core.tween
66import androidx.compose.foundation.BorderStroke
7+ import androidx.compose.foundation.ExperimentalFoundationApi
78import androidx.compose.foundation.clickable
89import androidx.compose.foundation.layout.*
10+ import androidx.compose.foundation.lazy.LazyColumn
11+ import androidx.compose.foundation.lazy.items
12+ import androidx.compose.foundation.lazy.rememberLazyListState
913import androidx.compose.foundation.rememberScrollState
1014import androidx.compose.foundation.shape.RoundedCornerShape
1115import androidx.compose.foundation.verticalScroll
1216import androidx.compose.material.icons.Icons
1317import androidx.compose.material.icons.filled.Add
1418import androidx.compose.material.icons.filled.Delete
19+ import androidx.compose.material.icons.filled.DragHandle
1520import androidx.compose.material.icons.filled.Refresh
1621import androidx.compose.material3.*
1722import androidx.compose.runtime.*
@@ -28,8 +33,10 @@ import com.droidspaces.app.R
2833import com.droidspaces.app.util.ContainerManager
2934import kotlinx.coroutines.delay
3035import kotlinx.coroutines.launch
36+ import sh.calvin.reorderable.ReorderableItem
37+ import sh.calvin.reorderable.rememberReorderableLazyListState
3138
32- @OptIn(ExperimentalLayoutApi ::class )
39+ @OptIn(ExperimentalLayoutApi ::class , ExperimentalFoundationApi :: class )
3340@Composable
3441fun UpstreamInterfaceList (
3542 upstreamInterfaces : List <String >,
@@ -45,21 +52,40 @@ fun UpstreamInterfaceList(
4552 }
4653
4754 Column (modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement .spacedBy(12 .dp)) {
48- // Selected interfaces
49- upstreamInterfaces.forEach { iface ->
50- Surface (
51- modifier = Modifier .fillMaxWidth(),
52- color = MaterialTheme .colorScheme.surfaceContainerHigh,
53- shape = RoundedCornerShape (20 .dp),
54- border = BorderStroke (1 .dp, MaterialTheme .colorScheme.outlineVariant.copy(alpha = 0.5f ))
55- ) {
56- Row (
57- modifier = Modifier .padding(horizontal = 16 .dp, vertical = 12 .dp),
58- verticalAlignment = Alignment .CenterVertically
59- ) {
60- Text (text = iface, modifier = Modifier .weight(1f ), style = MaterialTheme .typography.bodyLarge)
61- IconButton (onClick = { onInterfacesChange(upstreamInterfaces - iface) }) {
62- Icon (Icons .Default .Delete , contentDescription = null , tint = MaterialTheme .colorScheme.error)
55+ // Selected interfaces (drag the handle to reorder; height is bounded since
56+ // this LazyColumn sits inside the form's own scrolling Column)
57+ val lazyListState = rememberLazyListState()
58+ val reorderableState = rememberReorderableLazyListState(lazyListState) { from, to ->
59+ onInterfacesChange(upstreamInterfaces.toMutableList().apply { add(to.index, removeAt(from.index)) })
60+ }
61+ LazyColumn (
62+ state = lazyListState,
63+ modifier = Modifier .fillMaxWidth().heightIn(max = 480 .dp),
64+ verticalArrangement = Arrangement .spacedBy(12 .dp)
65+ ) {
66+ items(upstreamInterfaces, key = { it }) { iface ->
67+ ReorderableItem (reorderableState, key = iface) {
68+ Surface (
69+ modifier = Modifier .fillMaxWidth(),
70+ color = MaterialTheme .colorScheme.surfaceContainerHigh,
71+ shape = RoundedCornerShape (20 .dp),
72+ border = BorderStroke (1 .dp, MaterialTheme .colorScheme.outlineVariant.copy(alpha = 0.5f ))
73+ ) {
74+ Row (
75+ modifier = Modifier .padding(horizontal = 16 .dp, vertical = 12 .dp),
76+ verticalAlignment = Alignment .CenterVertically
77+ ) {
78+ Icon (
79+ Icons .Default .DragHandle ,
80+ contentDescription = null ,
81+ modifier = Modifier .draggableHandle().padding(end = 12 .dp),
82+ tint = MaterialTheme .colorScheme.onSurfaceVariant
83+ )
84+ Text (text = iface, modifier = Modifier .weight(1f ), style = MaterialTheme .typography.bodyLarge)
85+ IconButton (onClick = { onInterfacesChange(upstreamInterfaces - iface) }) {
86+ Icon (Icons .Default .Delete , contentDescription = null , tint = MaterialTheme .colorScheme.error)
87+ }
88+ }
6389 }
6490 }
6591 }
0 commit comments