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:
Claude
2026-04-06 15:29:19 +00:00
parent ce11edc352
commit 5b95a47e0e
15 changed files with 465 additions and 332 deletions
@@ -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(
@@ -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 {
@@ -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 {
@@ -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,
)
}
@@ -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,
@@ -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() },
)
}
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {