@@ -8,10 +8,10 @@ import android.net.Uri
88import androidx.activity.compose.rememberLauncherForActivityResult
99import androidx.activity.result.contract.ActivityResultContracts
1010import androidx.compose.animation.AnimatedVisibility
11+ import androidx.compose.animation.core.animateDpAsState
1112import androidx.compose.animation.fadeIn
1213import androidx.compose.animation.fadeOut
1314import androidx.compose.foundation.ExperimentalFoundationApi
14- import androidx.compose.foundation.gestures.detectTapGestures
1515import androidx.compose.foundation.horizontalScroll
1616import androidx.compose.foundation.layout.Arrangement
1717import androidx.compose.foundation.layout.Box
@@ -25,9 +25,9 @@ import androidx.compose.foundation.layout.padding
2525import androidx.compose.foundation.layout.statusBarsPadding
2626import androidx.compose.foundation.layout.systemBarsPadding
2727import androidx.compose.foundation.lazy.LazyColumn
28- import androidx.compose.foundation.lazy.LazyListItemInfo
2928import androidx.compose.foundation.lazy.LazyListScope
3029import androidx.compose.foundation.lazy.items
30+ import androidx.compose.foundation.lazy.rememberLazyListState
3131import androidx.compose.foundation.rememberScrollState
3232import androidx.compose.material.icons.Icons
3333import androidx.compose.material.icons.filled.Clear
@@ -40,6 +40,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
4040import androidx.compose.material3.Icon
4141import androidx.compose.material3.MaterialTheme
4242import androidx.compose.material3.Scaffold
43+ import androidx.compose.material3.Surface
4344import androidx.compose.material3.Text
4445import androidx.compose.material3.TextButton
4546import androidx.compose.runtime.Composable
@@ -51,19 +52,16 @@ import androidx.compose.runtime.toMutableStateList
5152import androidx.compose.ui.Alignment
5253import androidx.compose.ui.Modifier
5354import androidx.compose.ui.hapticfeedback.HapticFeedbackType
54- import androidx.compose.ui.input.pointer.pointerInput
5555import androidx.compose.ui.platform.LocalContext
5656import androidx.compose.ui.platform.LocalHapticFeedback
5757import androidx.compose.ui.res.stringResource
5858import androidx.compose.ui.text.style.TextAlign
5959import androidx.compose.ui.unit.Dp
6060import androidx.compose.ui.unit.dp
6161import androidx.hilt.navigation.compose.hiltViewModel
62- import org.burnoutcrew.reorderable.ReorderableItem
63- import org.burnoutcrew.reorderable.ReorderableState
64- import org.burnoutcrew.reorderable.detectReorder
65- import org.burnoutcrew.reorderable.rememberReorderableLazyListState
66- import org.burnoutcrew.reorderable.reorderable
62+ import sh.calvin.reorderable.ReorderableItem
63+ import sh.calvin.reorderable.ReorderableLazyListState
64+ import sh.calvin.reorderable.rememberReorderableLazyListState
6765import tm.alashow.base.util.extensions.swap
6866import tm.alashow.common.compose.LocalIsPreviewMode
6967import tm.alashow.common.compose.previews.CombinedPreview
@@ -148,17 +146,16 @@ private fun EditPlaylist(
148146 ) { paddings ->
149147 ProvideScaffoldPadding (paddings) {
150148 val itemsBeforeContent = 3
151- val reorderableState = rememberReorderableLazyListState(
152- onMove = { from, to -> onMovePlaylistItem(from.index - itemsBeforeContent, to.index - itemsBeforeContent) },
153- canDragOver = { it.key is DraggableItemKey },
154- )
149+ val listState = rememberLazyListState()
150+ val reorderableState = rememberReorderableLazyListState(listState) { from, to ->
151+ onMovePlaylistItem(from.index - itemsBeforeContent, to.index - itemsBeforeContent)
152+ }
155153
156154 Box (modifier) {
157155 LazyColumn (
158- state = reorderableState. listState,
156+ state = listState,
159157 modifier = Modifier
160158 .fillMaxSize()
161- .reorderable(reorderableState)
162159 ) {
163160 item {
164161 Spacer (Modifier .statusBarsPadding())
@@ -334,55 +331,50 @@ private fun LazyListScope.editPlaylistExtraActions(
334331
335332@OptIn(ExperimentalFoundationApi ::class )
336333private fun LazyListScope.editablePlaylistAudioList (
337- reorderableState : ReorderableState < LazyListItemInfo > ,
334+ reorderableState : ReorderableLazyListState ,
338335 onRemove : (PlaylistAudioId ) -> Unit ,
339336 audios : PlaylistItems ,
340337) {
341338 items(audios, key = { DraggableItemKey (it.playlistAudio.id) }) { playlistItem ->
342339 val haptic = LocalHapticFeedback .current
343340 val itemKey = DraggableItemKey (playlistItem.playlistAudio.id)
344- val isDragging = reorderableState.draggingItemKey == itemKey
345- ReorderableItem (
346- reorderableState, key = itemKey,
347- if (isDragging) Modifier else Modifier .animateItem()
348- ) {
349- Row (
350- verticalAlignment = Alignment .CenterVertically ,
351- horizontalArrangement = Arrangement .spacedBy(AppTheme .specs.paddingSmall),
352- modifier = Modifier
353- .padding(vertical = Theme .specs.paddingSmall)
354- .padding(start = Theme .specs.paddingSmall)
355- .padding(end = Theme .specs.padding),
356- ) {
357- IconButton (onClick = { onRemove(playlistItem.playlistAudio.id) }) {
341+ ReorderableItem (reorderableState, itemKey) { isDragging ->
342+ val elevation by animateDpAsState(if (isDragging) 2 .dp else 0 .dp)
343+ Surface (shadowElevation = elevation) {
344+ Row (
345+ verticalAlignment = Alignment .CenterVertically ,
346+ horizontalArrangement = Arrangement .spacedBy(AppTheme .specs.paddingSmall),
347+ modifier = Modifier
348+ .padding(vertical = Theme .specs.paddingSmall)
349+ .padding(start = Theme .specs.paddingSmall)
350+ .padding(end = Theme .specs.padding)
351+ .apply { if (isDragging) animateItem() else this }
352+ ) {
353+ IconButton (onClick = { onRemove(playlistItem.playlistAudio.id) }) {
354+ Icon (
355+ Icons .Default .RemoveCircleOutline ,
356+ contentDescription = null ,
357+ modifier = Modifier .weight(2f )
358+ )
359+ }
360+
361+ AudioRowItem (
362+ audio = playlistItem.audio,
363+ modifier = Modifier .weight(19f ),
364+ includeCover = false ,
365+ observeNowPlayingAudio = false ,
366+ maxLines = 1 ,
367+ )
368+
358369 Icon (
359- Icons .Default .RemoveCircleOutline ,
370+ Icons .Default .DragHandle ,
360371 contentDescription = null ,
361- modifier = Modifier .weight(2f )
372+ modifier = Modifier .draggableHandle(
373+ onDragStarted = { haptic.performHapticFeedback(HapticFeedbackType .GestureThresholdActivate ) },
374+ onDragStopped = { haptic.performHapticFeedback(HapticFeedbackType .GestureEnd ) },
375+ )
362376 )
363377 }
364-
365- AudioRowItem (
366- audio = playlistItem.audio,
367- modifier = Modifier .weight(19f ),
368- includeCover = false ,
369- observeNowPlayingAudio = false ,
370- maxLines = 1 ,
371- )
372-
373- Icon (
374- Icons .Default .DragHandle ,
375- contentDescription = null ,
376- modifier = Modifier
377- .pointerInput(Unit ) {
378- detectTapGestures(
379- onPress = {
380- haptic.performHapticFeedback(HapticFeedbackType .LongPress )
381- }
382- )
383- }
384- .detectReorder(reorderableState)
385- )
386378 }
387379 }
388380 }
0 commit comments