refactor: keep lazy itemsIndexed for relay drag-and-drop
Replace the single-item Column approach with RelayDragState that works within itemsIndexed. Each relay item remains a separate lazy item for better performance with large lists. The drag handle icon on each row captures drag gestures while the item modifier applies visual feedback (elevation, scale, translation). https://claude.ai/code/session_01RVM5kEJGrCaJTaP3GmVHDd
This commit is contained in:
+74
-12
@@ -68,6 +68,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayExporter
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayListCollection
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayZipExporter
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected.ConnectedRelayListViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.connected.renderConnectedItems
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.dm.DMRelayListViewModel
|
||||
@@ -201,6 +202,67 @@ fun MappedAllRelayListView(
|
||||
val indexerCounts by indexerViewModel.countResults.collectAsStateWithLifecycle()
|
||||
val searchCounts by searchViewModel.countResults.collectAsStateWithLifecycle()
|
||||
|
||||
val homeDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> nip65ViewModel.moveHomeRelay(from, to) },
|
||||
itemCount = { homeFeedState.size },
|
||||
)
|
||||
val notifDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> nip65ViewModel.moveNotifRelay(from, to) },
|
||||
itemCount = { notifFeedState.size },
|
||||
)
|
||||
val dmDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> dmViewModel.moveRelay(from, to) },
|
||||
itemCount = { dmFeedState.size },
|
||||
)
|
||||
val privateOutboxDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> privateOutboxViewModel.moveRelay(from, to) },
|
||||
itemCount = { privateOutboxFeedState.size },
|
||||
)
|
||||
val proxyDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> proxyViewModel.moveRelay(from, to) },
|
||||
itemCount = { proxyRelays.size },
|
||||
)
|
||||
val broadcastDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> broadcastViewModel.moveRelay(from, to) },
|
||||
itemCount = { broadcastRelays.size },
|
||||
)
|
||||
val indexerDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> indexerViewModel.moveRelay(from, to) },
|
||||
itemCount = { indexerRelays.size },
|
||||
)
|
||||
val searchDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> searchViewModel.moveRelay(from, to) },
|
||||
itemCount = { searchFeedState.size },
|
||||
)
|
||||
val localDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> localViewModel.moveRelay(from, to) },
|
||||
itemCount = { localFeedState.size },
|
||||
)
|
||||
val trustedDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> trustedViewModel.moveRelay(from, to) },
|
||||
itemCount = { trustedFeedState.size },
|
||||
)
|
||||
val feedsDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> relayFeedsViewModel.moveRelay(from, to) },
|
||||
itemCount = { relayFeedsFeedState.size },
|
||||
)
|
||||
val blockedDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> blockedViewModel.moveRelay(from, to) },
|
||||
itemCount = { blockedFeedState.size },
|
||||
)
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
SavingTopBar(
|
||||
@@ -274,7 +336,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategoryFirstModifier,
|
||||
)
|
||||
}
|
||||
renderNip65HomeItems(homeFeedState, nip65ViewModel, accountViewModel, nav, outboxCounts)
|
||||
renderNip65HomeItems(homeFeedState, nip65ViewModel, accountViewModel, nav, outboxCounts, homeDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -283,7 +345,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderNip65NotifItems(notifFeedState, nip65ViewModel, accountViewModel, nav, inboxCounts)
|
||||
renderNip65NotifItems(notifFeedState, nip65ViewModel, accountViewModel, nav, inboxCounts, notifDragState)
|
||||
|
||||
item {
|
||||
SettingsCategoryWithButton(
|
||||
@@ -295,7 +357,7 @@ fun MappedAllRelayListView(
|
||||
},
|
||||
)
|
||||
}
|
||||
renderDMItems(dmFeedState, dmViewModel, accountViewModel, nav, dmCounts)
|
||||
renderDMItems(dmFeedState, dmViewModel, accountViewModel, nav, dmCounts, dmDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -304,7 +366,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderPrivateOutboxItems(privateOutboxFeedState, privateOutboxViewModel, accountViewModel, nav, privateHomeCounts)
|
||||
renderPrivateOutboxItems(privateOutboxFeedState, privateOutboxViewModel, accountViewModel, nav, privateHomeCounts, privateOutboxDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -313,7 +375,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderProxyItems(proxyRelays, proxyViewModel, accountViewModel, nav, proxyCounts)
|
||||
renderProxyItems(proxyRelays, proxyViewModel, accountViewModel, nav, proxyCounts, proxyDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -322,7 +384,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderBroadcastItems(broadcastRelays, broadcastViewModel, accountViewModel, nav)
|
||||
renderBroadcastItems(broadcastRelays, broadcastViewModel, accountViewModel, nav, broadcastDragState)
|
||||
|
||||
item {
|
||||
SettingsCategoryWithButton(
|
||||
@@ -333,7 +395,7 @@ fun MappedAllRelayListView(
|
||||
ResetIndexerRelays(indexerViewModel)
|
||||
}
|
||||
}
|
||||
renderIndexerItems(indexerRelays, indexerViewModel, accountViewModel, nav, indexerCounts)
|
||||
renderIndexerItems(indexerRelays, indexerViewModel, accountViewModel, nav, indexerCounts, indexerDragState)
|
||||
|
||||
item {
|
||||
SettingsCategoryWithButton(
|
||||
@@ -344,7 +406,7 @@ fun MappedAllRelayListView(
|
||||
ResetSearchRelays(searchViewModel)
|
||||
}
|
||||
}
|
||||
renderSearchItems(searchFeedState, searchViewModel, accountViewModel, nav, searchCounts)
|
||||
renderSearchItems(searchFeedState, searchViewModel, accountViewModel, nav, searchCounts, searchDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -371,7 +433,7 @@ fun MappedAllRelayListView(
|
||||
)
|
||||
}
|
||||
}
|
||||
renderLocalItems(localFeedState, localViewModel, accountViewModel, nav)
|
||||
renderLocalItems(localFeedState, localViewModel, accountViewModel, nav, localDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -380,7 +442,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderTrustedItems(trustedFeedState, trustedViewModel, accountViewModel, nav)
|
||||
renderTrustedItems(trustedFeedState, trustedViewModel, accountViewModel, nav, trustedDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -389,7 +451,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderRelayFeedsItems(relayFeedsFeedState, relayFeedsViewModel, accountViewModel, nav)
|
||||
renderRelayFeedsItems(relayFeedsFeedState, relayFeedsViewModel, accountViewModel, nav, feedsDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
@@ -398,7 +460,7 @@ fun MappedAllRelayListView(
|
||||
SettingsCategorySpacingModifier,
|
||||
)
|
||||
}
|
||||
renderBlockedItems(blockedFeedState, blockedViewModel, accountViewModel, nav)
|
||||
renderBlockedItems(blockedFeedState, blockedViewModel, accountViewModel, nav, blockedDragState)
|
||||
|
||||
item {
|
||||
SettingsCategory(
|
||||
|
||||
+20
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,9 +35,10 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
|
||||
@@ -48,14 +50,18 @@ fun BlockedRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderBlockedItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderBlockedItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,21 +71,18 @@ fun LazyListScope.renderBlockedItems(
|
||||
postViewModel: BlockedRelayListViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Blocked_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Blocked" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+20
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,9 +35,10 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
|
||||
@@ -48,14 +50,18 @@ fun BroadcastRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderBroadcastItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderBroadcastItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,21 +71,18 @@ fun LazyListScope.renderBroadcastItems(
|
||||
postViewModel: BroadcastRelayListViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Broadcast_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Broadcast" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+34
-16
@@ -71,36 +71,54 @@ fun BasicRelaySetupInfoClickableRow(
|
||||
onClick: () -> Unit,
|
||||
nip11CachedRetriever: Nip11CachedRetriever,
|
||||
modifier: Modifier = Modifier,
|
||||
dragModifier: Modifier = Modifier,
|
||||
index: Int = -1,
|
||||
dragState: RelayDragState? = null,
|
||||
countResult: RelayCountResult? = null,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val clipboardManager = LocalClipboard.current
|
||||
val scope = rememberCoroutineScope()
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.combinedClickable(
|
||||
onClick = onClick,
|
||||
onLongClick = {
|
||||
scope.launch {
|
||||
clipboardManager.setText(item.relay.url)
|
||||
}
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
||||
val itemModifier =
|
||||
if (dragState != null && index >= 0) {
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.draggableRelayItem(index, dragState)
|
||||
.combinedClickable(
|
||||
onClick = onClick,
|
||||
onLongClick = {
|
||||
scope.launch {
|
||||
clipboardManager.setText(item.relay.url)
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.combinedClickable(
|
||||
onClick = onClick,
|
||||
onLongClick = {
|
||||
scope.launch {
|
||||
clipboardManager.setText(item.relay.url)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Column(itemModifier) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier,
|
||||
) {
|
||||
if (dragModifier != Modifier) {
|
||||
if (dragState != null && index >= 0) {
|
||||
Icon(
|
||||
Icons.Default.DragIndicator,
|
||||
contentDescription = stringRes(R.string.relay_reorder),
|
||||
modifier =
|
||||
dragModifier
|
||||
.size(24.dp),
|
||||
Modifier
|
||||
.size(24.dp)
|
||||
.relayDragHandle(index, dragState),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
|
||||
+4
-3
@@ -21,7 +21,6 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.vitorpamplona.amethyst.model.nip11RelayInfo.Nip11CachedRetriever
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
@@ -34,7 +33,8 @@ fun BasicRelaySetupInfoDialog(
|
||||
nip11CachedRetriever: Nip11CachedRetriever,
|
||||
onDelete: ((BasicRelaySetupInfo) -> Unit)?,
|
||||
countResult: RelayCountResult? = null,
|
||||
dragModifier: Modifier = Modifier,
|
||||
index: Int = -1,
|
||||
dragState: RelayDragState? = null,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
@@ -46,7 +46,8 @@ fun BasicRelaySetupInfoDialog(
|
||||
onClick = { nav.nav(Route.RelayInfo(item.relay.url)) },
|
||||
nip11CachedRetriever = nip11CachedRetriever,
|
||||
modifier = HalfVertPadding,
|
||||
dragModifier = dragModifier,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
countResult = countResult,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
|
||||
+96
-92
@@ -22,10 +22,8 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common
|
||||
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.gestures.detectDragGestures
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
@@ -38,106 +36,112 @@ import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.zIndex
|
||||
|
||||
@Composable
|
||||
fun DraggableRelayList(
|
||||
items: List<BasicRelaySetupInfo>,
|
||||
onMove: (from: Int, to: Int) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable (
|
||||
index: Int,
|
||||
item: BasicRelaySetupInfo,
|
||||
dragModifier: Modifier,
|
||||
) -> Unit,
|
||||
@Stable
|
||||
class RelayDragState(
|
||||
val onMove: (from: Int, to: Int) -> Unit,
|
||||
val itemCount: () -> Int,
|
||||
) {
|
||||
var draggedItemIndex by remember { mutableIntStateOf(-1) }
|
||||
var dragOffset by remember { mutableFloatStateOf(0f) }
|
||||
val itemHeights = remember { mutableStateMapOf<Int, Float>() }
|
||||
var draggedItemIndex by mutableIntStateOf(-1)
|
||||
var dragOffset by mutableFloatStateOf(0f)
|
||||
val itemHeights = mutableStateMapOf<Int, Float>()
|
||||
|
||||
Column(modifier = modifier.fillMaxWidth()) {
|
||||
items.forEachIndexed { index, item ->
|
||||
val isDragging = draggedItemIndex == index
|
||||
val targetElevation = if (isDragging) 8f else 0f
|
||||
val animatedElevation by animateFloatAsState(
|
||||
targetValue = targetElevation,
|
||||
label = "dragElevation",
|
||||
)
|
||||
fun onDragStart(index: Int) {
|
||||
draggedItemIndex = index
|
||||
dragOffset = 0f
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier =
|
||||
Modifier
|
||||
.zIndex(if (isDragging) 1f else 0f)
|
||||
.onGloballyPositioned { coordinates ->
|
||||
itemHeights[index] = coordinates.size.height.toFloat()
|
||||
}.graphicsLayer {
|
||||
translationY = if (isDragging) dragOffset else 0f
|
||||
shadowElevation = animatedElevation
|
||||
if (isDragging) {
|
||||
scaleX = 1.02f
|
||||
scaleY = 1.02f
|
||||
}
|
||||
},
|
||||
) {
|
||||
val dragModifier =
|
||||
Modifier.pointerInput(Unit) {
|
||||
detectDragGestures(
|
||||
onDragStart = {
|
||||
draggedItemIndex = index
|
||||
dragOffset = 0f
|
||||
},
|
||||
onDrag = { change, dragAmount ->
|
||||
change.consume()
|
||||
dragOffset += dragAmount.y
|
||||
fun onDrag(dragAmount: Float) {
|
||||
dragOffset += dragAmount
|
||||
|
||||
val currentIndex = draggedItemIndex
|
||||
if (currentIndex < 0) return@detectDragGestures
|
||||
val currentIndex = draggedItemIndex
|
||||
if (currentIndex < 0) return
|
||||
|
||||
// Check if we should swap with the item above
|
||||
if (dragOffset < 0 && currentIndex > 0) {
|
||||
val aboveHeight = itemHeights[currentIndex - 1] ?: 0f
|
||||
if (-dragOffset > aboveHeight / 2f) {
|
||||
onMove(currentIndex, currentIndex - 1)
|
||||
// Check if we should swap with the item above
|
||||
if (dragOffset < 0 && currentIndex > 0) {
|
||||
val aboveHeight = itemHeights[currentIndex - 1] ?: 0f
|
||||
if (-dragOffset > aboveHeight / 2f) {
|
||||
onMove(currentIndex, currentIndex - 1)
|
||||
|
||||
// Transfer heights
|
||||
val h1 = itemHeights[currentIndex]
|
||||
val h2 = itemHeights[currentIndex - 1]
|
||||
if (h1 != null) itemHeights[currentIndex - 1] = h1
|
||||
if (h2 != null) itemHeights[currentIndex] = h2
|
||||
val h1 = itemHeights[currentIndex]
|
||||
val h2 = itemHeights[currentIndex - 1]
|
||||
if (h1 != null) itemHeights[currentIndex - 1] = h1
|
||||
if (h2 != null) itemHeights[currentIndex] = h2
|
||||
|
||||
dragOffset += aboveHeight
|
||||
draggedItemIndex = currentIndex - 1
|
||||
}
|
||||
}
|
||||
dragOffset += aboveHeight
|
||||
draggedItemIndex = currentIndex - 1
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we should swap with the item below
|
||||
if (dragOffset > 0 && currentIndex < items.lastIndex) {
|
||||
val belowHeight = itemHeights[currentIndex + 1] ?: 0f
|
||||
if (dragOffset > belowHeight / 2f) {
|
||||
onMove(currentIndex, currentIndex + 1)
|
||||
// Check if we should swap with the item below
|
||||
if (dragOffset > 0 && currentIndex < itemCount() - 1) {
|
||||
val belowHeight = itemHeights[currentIndex + 1] ?: 0f
|
||||
if (dragOffset > belowHeight / 2f) {
|
||||
onMove(currentIndex, currentIndex + 1)
|
||||
|
||||
// Transfer heights
|
||||
val h1 = itemHeights[currentIndex]
|
||||
val h2 = itemHeights[currentIndex + 1]
|
||||
if (h1 != null) itemHeights[currentIndex + 1] = h1
|
||||
if (h2 != null) itemHeights[currentIndex] = h2
|
||||
val h1 = itemHeights[currentIndex]
|
||||
val h2 = itemHeights[currentIndex + 1]
|
||||
if (h1 != null) itemHeights[currentIndex + 1] = h1
|
||||
if (h2 != null) itemHeights[currentIndex] = h2
|
||||
|
||||
dragOffset -= belowHeight
|
||||
draggedItemIndex = currentIndex + 1
|
||||
}
|
||||
}
|
||||
},
|
||||
onDragEnd = {
|
||||
draggedItemIndex = -1
|
||||
dragOffset = 0f
|
||||
},
|
||||
onDragCancel = {
|
||||
draggedItemIndex = -1
|
||||
dragOffset = 0f
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
content(index, item, dragModifier)
|
||||
dragOffset -= belowHeight
|
||||
draggedItemIndex = currentIndex + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onDragEnd() {
|
||||
draggedItemIndex = -1
|
||||
dragOffset = 0f
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberRelayDragState(
|
||||
onMove: (from: Int, to: Int) -> Unit,
|
||||
itemCount: () -> Int,
|
||||
): RelayDragState =
|
||||
remember(onMove, itemCount) {
|
||||
RelayDragState(onMove, itemCount)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Modifier.draggableRelayItem(
|
||||
index: Int,
|
||||
dragState: RelayDragState,
|
||||
): Modifier {
|
||||
val isDragging = dragState.draggedItemIndex == index
|
||||
val targetElevation = if (isDragging) 8f else 0f
|
||||
val animatedElevation by animateFloatAsState(
|
||||
targetValue = targetElevation,
|
||||
label = "dragElevation",
|
||||
)
|
||||
|
||||
return this
|
||||
.zIndex(if (isDragging) 1f else 0f)
|
||||
.onGloballyPositioned { coordinates ->
|
||||
dragState.itemHeights[index] = coordinates.size.height.toFloat()
|
||||
}.graphicsLayer {
|
||||
translationY = if (isDragging) dragState.dragOffset else 0f
|
||||
shadowElevation = animatedElevation
|
||||
if (isDragging) {
|
||||
scaleX = 1.02f
|
||||
scaleY = 1.02f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifier.relayDragHandle(
|
||||
index: Int,
|
||||
dragState: RelayDragState,
|
||||
): Modifier =
|
||||
this.pointerInput(index) {
|
||||
detectDragGestures(
|
||||
onDragStart = { dragState.onDragStart(index) },
|
||||
onDrag = { change, dragAmount ->
|
||||
change.consume()
|
||||
dragState.onDrag(dragAmount.y)
|
||||
},
|
||||
onDragEnd = { dragState.onDragEnd() },
|
||||
onDragCancel = { dragState.onDragEnd() },
|
||||
)
|
||||
}
|
||||
|
||||
+21
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -51,12 +53,17 @@ fun DMRelayList(
|
||||
) {
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderDMItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderDMItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,22 +74,19 @@ fun LazyListScope.renderDMItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "DM_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "DM" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+20
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,9 +35,10 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
|
||||
@@ -48,14 +50,18 @@ fun RelayFeedsList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderRelayFeedsItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderRelayFeedsItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,21 +71,18 @@ fun LazyListScope.renderRelayFeedsItems(
|
||||
postViewModel: RelayFeedsListViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "RelayFeeds_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "RelayFeeds" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+21
-18
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -50,14 +52,18 @@ fun IndexerRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderIndexerItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderIndexerItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,22 +74,19 @@ fun LazyListScope.renderIndexerItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Indexer_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Indexer" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+20
-16
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,9 +35,10 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
|
||||
@@ -49,12 +51,17 @@ fun LocalRelayList(
|
||||
) {
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderLocalItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderLocalItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,21 +71,18 @@ fun LazyListScope.renderLocalItems(
|
||||
postViewModel: LocalRelayListViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Local_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Local" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+21
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -51,12 +53,17 @@ fun PrivateOutboxRelayList(
|
||||
) {
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderPrivateOutboxItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderPrivateOutboxItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,22 +74,19 @@ fun LazyListScope.renderPrivateOutboxItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Outbox_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Outbox" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+52
-37
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -54,12 +56,23 @@ fun Nip65RelayList(
|
||||
val homeFeedState by postViewModel.homeRelays.collectAsStateWithLifecycle()
|
||||
val notifFeedState by postViewModel.notificationRelays.collectAsStateWithLifecycle()
|
||||
|
||||
val homeDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveHomeRelay(from, to) },
|
||||
itemCount = { homeFeedState.size },
|
||||
)
|
||||
val notifDragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveNotifRelay(from, to) },
|
||||
itemCount = { notifFeedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderNip65HomeItems(homeFeedState, postViewModel, accountViewModel, newNav)
|
||||
renderNip65NotifItems(notifFeedState, postViewModel, accountViewModel, newNav)
|
||||
renderNip65HomeItems(homeFeedState, postViewModel, accountViewModel, newNav, dragState = homeDragState)
|
||||
renderNip65NotifItems(notifFeedState, postViewModel, accountViewModel, newNav, dragState = notifDragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,14 +85,18 @@ fun Nip65InboxRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
|
||||
val notifFeedState by postViewModel.notificationRelays.collectAsStateWithLifecycle()
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveNotifRelay(from, to) },
|
||||
itemCount = { notifFeedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderNip65NotifItems(notifFeedState, postViewModel, accountViewModel, newNav)
|
||||
renderNip65NotifItems(notifFeedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,14 +109,18 @@ fun Nip65OutboxRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
|
||||
val homeFeedState by postViewModel.homeRelays.collectAsStateWithLifecycle()
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveHomeRelay(from, to) },
|
||||
itemCount = { homeFeedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderNip65HomeItems(homeFeedState, postViewModel, accountViewModel, newNav)
|
||||
renderNip65HomeItems(homeFeedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,22 +131,19 @@ fun LazyListScope.renderNip65HomeItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Nip65Home_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveHomeRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteHomeRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Nip65Home" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteHomeRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
@@ -144,22 +162,19 @@ fun LazyListScope.renderNip65NotifItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Nip65Notif_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveNotifRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteNotifRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Nip65Notif" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteNotifRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+21
-18
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -50,14 +52,18 @@ fun ProxyRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderProxyItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderProxyItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,22 +74,19 @@ fun LazyListScope.renderProxyItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Proxy_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Proxy" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+21
-18
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,10 +35,11 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -50,14 +52,18 @@ fun SearchRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderSearchItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderSearchItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,22 +74,19 @@ fun LazyListScope.renderSearchItems(
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
countResults: Map<NormalizedRelayUrl, RelayCountResult> = emptyMap(),
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Search_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Search" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
countResult = countResults[item.relay],
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
+20
-17
@@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -34,9 +35,10 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.rememberExtendedNav
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoDialog
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.DraggableRelayList
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayUrlEditField
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
|
||||
@@ -48,14 +50,18 @@ fun TrustedRelayList(
|
||||
nav: INav,
|
||||
) {
|
||||
val feedState by postViewModel.relays.collectAsStateWithLifecycle()
|
||||
|
||||
val newNav = rememberExtendedNav(nav, onClose)
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
itemCount = { feedState.size },
|
||||
)
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
LazyColumn(
|
||||
contentPadding = FeedPadding,
|
||||
) {
|
||||
renderTrustedItems(feedState, postViewModel, accountViewModel, newNav)
|
||||
renderTrustedItems(feedState, postViewModel, accountViewModel, newNav, dragState = dragState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,21 +71,18 @@ fun LazyListScope.renderTrustedItems(
|
||||
postViewModel: TrustedRelayListViewModel,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
dragState: RelayDragState? = null,
|
||||
) {
|
||||
item(key = "Trusted_draggable_list") {
|
||||
DraggableRelayList(
|
||||
items = feedState,
|
||||
onMove = { from, to -> postViewModel.moveRelay(from, to) },
|
||||
) { _, item, dragModifier ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
dragModifier = dragModifier,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
itemsIndexed(feedState, key = { _, item -> "Trusted" + item.relay.url }) { index, item ->
|
||||
BasicRelaySetupInfoDialog(
|
||||
item,
|
||||
onDelete = { postViewModel.deleteRelay(item) },
|
||||
nip11CachedRetriever = Amethyst.instance.nip11Cache,
|
||||
index = index,
|
||||
dragState = dragState,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
|
||||
Reference in New Issue
Block a user