mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 00:16:59 +00:00
Merge pull request #3054 from vitorpamplona/claude/pensive-brown-UVDZf
Replace wallet reorder buttons with drag-and-drop UI
This commit is contained in:
@@ -285,9 +285,9 @@ fun BuildNavigation(
|
||||
composable<Route.Chess> { ChessLobbyScreen(accountViewModel, nav) }
|
||||
|
||||
composableFromEnd<Route.Wallet> { WalletScreen(accountViewModel, nav) }
|
||||
composableFromEnd<Route.WalletSend> { WalletSendScreen(accountViewModel, nav) }
|
||||
composableFromEnd<Route.WalletReceive> { WalletReceiveScreen(accountViewModel, nav) }
|
||||
composableFromEnd<Route.WalletTransactions> { WalletTransactionsScreen(accountViewModel, nav) }
|
||||
composableFromEndArgs<Route.WalletSend> { WalletSendScreen(it.walletId, accountViewModel, nav) }
|
||||
composableFromEndArgs<Route.WalletReceive> { WalletReceiveScreen(it.walletId, accountViewModel, nav) }
|
||||
composableFromEndArgs<Route.WalletTransactions> { WalletTransactionsScreen(it.walletId, accountViewModel, nav) }
|
||||
composableFromEnd<Route.OnchainTransactions> { OnchainTransactionsScreen(accountViewModel, nav) }
|
||||
composableFromEndArgs<Route.WalletDetail> { WalletDetailScreen(it.walletId, accountViewModel, nav) }
|
||||
composableFromEnd<Route.WalletAdd> { AddWalletScreen(accountViewModel, nav) }
|
||||
|
||||
@@ -146,11 +146,20 @@ sealed class Route {
|
||||
|
||||
@Serializable object Wallet : Route()
|
||||
|
||||
@Serializable object WalletSend : Route()
|
||||
@Serializable
|
||||
data class WalletSend(
|
||||
val walletId: String,
|
||||
) : Route()
|
||||
|
||||
@Serializable object WalletReceive : Route()
|
||||
@Serializable
|
||||
data class WalletReceive(
|
||||
val walletId: String,
|
||||
) : Route()
|
||||
|
||||
@Serializable object WalletTransactions : Route()
|
||||
@Serializable
|
||||
data class WalletTransactions(
|
||||
val walletId: String,
|
||||
) : Route()
|
||||
|
||||
@Serializable object OnchainTransactions : Route()
|
||||
|
||||
|
||||
+3
-3
@@ -149,7 +149,7 @@ fun WalletDetailScreen(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Button(
|
||||
onClick = { nav.nav(Route.WalletReceive) },
|
||||
onClick = { nav.nav(Route.WalletReceive(walletId)) },
|
||||
modifier =
|
||||
Modifier
|
||||
.weight(1f)
|
||||
@@ -171,7 +171,7 @@ fun WalletDetailScreen(
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = { nav.nav(Route.WalletSend) },
|
||||
onClick = { nav.nav(Route.WalletSend(walletId)) },
|
||||
modifier =
|
||||
Modifier
|
||||
.weight(1f)
|
||||
@@ -192,7 +192,7 @@ fun WalletDetailScreen(
|
||||
|
||||
// Transactions button
|
||||
OutlinedButton(
|
||||
onClick = { nav.nav(Route.WalletTransactions) },
|
||||
onClick = { nav.nav(Route.WalletTransactions(walletId)) },
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
|
||||
+3
-1
@@ -74,13 +74,15 @@ import java.text.NumberFormat
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun WalletReceiveScreen(
|
||||
walletId: String,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val walletViewModel: WalletViewModel = viewModel()
|
||||
|
||||
LaunchedEffect(accountViewModel) {
|
||||
LaunchedEffect(accountViewModel, walletId) {
|
||||
walletViewModel.init(accountViewModel)
|
||||
walletViewModel.selectWallet(walletId)
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
|
||||
+26
-36
@@ -73,6 +73,10 @@ import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.draggableRelayItem
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relayDragHandle
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.rememberRelayDragState
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.NumberFormat
|
||||
@@ -197,6 +201,12 @@ private fun MultiWalletHomeContent(
|
||||
}
|
||||
}
|
||||
|
||||
val dragState =
|
||||
rememberRelayDragState(
|
||||
onMove = { from, to -> walletViewModel.moveWallet(from, to) },
|
||||
itemCount = { walletInfoList.size },
|
||||
)
|
||||
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier =
|
||||
@@ -204,6 +214,7 @@ private fun MultiWalletHomeContent(
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
userScrollEnabled = !dragState.isDragging,
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
@@ -218,7 +229,7 @@ private fun MultiWalletHomeContent(
|
||||
WalletCard(
|
||||
walletInfo = walletInfo,
|
||||
index = index,
|
||||
totalCount = walletInfoList.size,
|
||||
dragState = if (walletInfoList.size > 1) dragState else null,
|
||||
onSelect = {
|
||||
walletViewModel.selectWallet(walletInfo.walletId)
|
||||
nav.nav(Route.WalletDetail(walletInfo.walletId))
|
||||
@@ -229,12 +240,6 @@ private fun MultiWalletHomeContent(
|
||||
onRename = { newName ->
|
||||
walletViewModel.renameWallet(walletInfo.walletId, newName)
|
||||
},
|
||||
onMoveUp = {
|
||||
walletViewModel.moveWallet(index, index - 1)
|
||||
},
|
||||
onMoveDown = {
|
||||
walletViewModel.moveWallet(index, index + 1)
|
||||
},
|
||||
onRemove = {
|
||||
walletViewModel.removeWallet(walletInfo.walletId)
|
||||
},
|
||||
@@ -264,12 +269,10 @@ private fun MultiWalletHomeContent(
|
||||
private fun WalletCard(
|
||||
walletInfo: WalletInfo,
|
||||
index: Int,
|
||||
totalCount: Int,
|
||||
dragState: RelayDragState?,
|
||||
onSelect: () -> Unit,
|
||||
onSetDefault: () -> Unit,
|
||||
onRename: (String) -> Unit,
|
||||
onMoveUp: () -> Unit,
|
||||
onMoveDown: () -> Unit,
|
||||
onRemove: () -> Unit,
|
||||
) {
|
||||
var showRemoveDialog by remember { mutableStateOf(false) }
|
||||
@@ -311,6 +314,7 @@ private fun WalletCard(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.let { if (dragState != null) it.draggableRelayItem(index, dragState) else it }
|
||||
.clickable(onClick = onSelect),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
border =
|
||||
@@ -363,32 +367,18 @@ private fun WalletCard(
|
||||
}
|
||||
}
|
||||
|
||||
// Reorder buttons
|
||||
if (totalCount > 1) {
|
||||
Column {
|
||||
IconButton(
|
||||
onClick = onMoveUp,
|
||||
enabled = index > 0,
|
||||
modifier = Modifier.size(28.dp),
|
||||
) {
|
||||
Icon(
|
||||
MaterialSymbols.KeyboardArrowUp,
|
||||
contentDescription = stringRes(R.string.wallet_move_up),
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onMoveDown,
|
||||
enabled = index < totalCount - 1,
|
||||
modifier = Modifier.size(28.dp),
|
||||
) {
|
||||
Icon(
|
||||
MaterialSymbols.KeyboardArrowDown,
|
||||
contentDescription = stringRes(R.string.wallet_move_down),
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
// Drag handle for reordering
|
||||
if (dragState != null) {
|
||||
Icon(
|
||||
MaterialSymbols.DragIndicator,
|
||||
contentDescription = stringRes(R.string.wallet_reorder),
|
||||
modifier =
|
||||
Modifier
|
||||
.size(24.dp)
|
||||
.relayDragHandle(index, dragState),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
|
||||
// Balance
|
||||
|
||||
+3
-1
@@ -64,13 +64,15 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun WalletSendScreen(
|
||||
walletId: String,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val walletViewModel: WalletViewModel = viewModel()
|
||||
|
||||
LaunchedEffect(accountViewModel) {
|
||||
LaunchedEffect(accountViewModel, walletId) {
|
||||
walletViewModel.init(accountViewModel)
|
||||
walletViewModel.selectWallet(walletId)
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
|
||||
+3
-1
@@ -73,13 +73,15 @@ import java.util.Locale
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun WalletTransactionsScreen(
|
||||
walletId: String,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val walletViewModel: WalletViewModel = viewModel()
|
||||
|
||||
LaunchedEffect(accountViewModel) {
|
||||
LaunchedEffect(accountViewModel, walletId) {
|
||||
walletViewModel.init(accountViewModel)
|
||||
walletViewModel.selectWallet(walletId)
|
||||
walletViewModel.fetchTransactions()
|
||||
}
|
||||
|
||||
|
||||
@@ -1870,6 +1870,7 @@
|
||||
<string name="wallet_invalid_uri">Invalid NWC connection URI</string>
|
||||
<string name="wallet_move_up">Move Up</string>
|
||||
<string name="wallet_move_down">Move Down</string>
|
||||
<string name="wallet_reorder">Reorder wallet</string>
|
||||
<string name="wallet_onchain_transactions">Onchain Transactions</string>
|
||||
<string name="wallet_onchain_no_address">No on-chain address available for this account.</string>
|
||||
<string name="wallet_onchain_no_backend">No chain backend is configured.</string>
|
||||
|
||||
Reference in New Issue
Block a user