mirror of
https://github.com/mollyim/monero-wallet-sdk.git
synced 2025-01-12 07:59:30 -05:00
demo: add initial balance view
This commit is contained in:
parent
471f22777c
commit
a84375d384
@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.onStart
|
||||
sealed interface Result<out T> {
|
||||
data class Success<T>(val data: T) : Result<T>
|
||||
data class Error(val exception: Throwable? = null) : Result<Nothing>
|
||||
object Loading : Result<Nothing>
|
||||
data object Loading : Result<Nothing>
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,16 +21,16 @@ class HomeViewModel(
|
||||
}
|
||||
|
||||
sealed interface HomeUiState {
|
||||
object Loading : HomeUiState
|
||||
data object Loading : HomeUiState
|
||||
|
||||
// data class Ready(
|
||||
// val wallets: List<WalletDetails>
|
||||
// ) : HomeUiState
|
||||
|
||||
object Empty : HomeUiState
|
||||
data object Empty : HomeUiState
|
||||
}
|
||||
|
||||
sealed interface WalletListUiState {
|
||||
data class Success(val ids: List<Long>) : WalletListUiState
|
||||
object Loading : WalletListUiState
|
||||
data object Loading : WalletListUiState
|
||||
}
|
||||
|
@ -98,5 +98,5 @@ sealed interface SettingsUiState {
|
||||
val remoteNodes: List<RemoteNode>,
|
||||
) : SettingsUiState
|
||||
|
||||
object Loading : SettingsUiState
|
||||
data object Loading : SettingsUiState
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
package im.molly.monero.demo.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import im.molly.monero.MoneroAmount
|
||||
import im.molly.monero.Balance
|
||||
import im.molly.monero.BlockchainTime
|
||||
import im.molly.monero.MoneroCurrency
|
||||
import im.molly.monero.TimeLocked
|
||||
import im.molly.monero.demo.ui.theme.AppTheme
|
||||
import im.molly.monero.xmr
|
||||
import kotlinx.coroutines.delay
|
||||
import java.math.BigDecimal
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.toKotlinDuration
|
||||
|
||||
@Composable
|
||||
fun WalletBalanceView(
|
||||
balance: Balance,
|
||||
blockchainTime: BlockchainTime,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var now by remember { mutableStateOf(Instant.now()) }
|
||||
|
||||
LaunchedEffect(now) {
|
||||
delay(1.seconds)
|
||||
now = Instant.now()
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
text = "Balance at Block #${blockchainTime.height}",
|
||||
)
|
||||
|
||||
BalanceRow("Confirmed", balance.confirmedAmount)
|
||||
BalanceRow("Pending", balance.pendingAmount)
|
||||
Divider()
|
||||
BalanceRow("Total", balance.totalAmount)
|
||||
|
||||
BalanceRow("Unlocked", balance.unlockedAmountAt(blockchainTime.height, now))
|
||||
balance.lockedAmountsAt(blockchainTime.height, now).forEach { (timeSpan, amount) ->
|
||||
LockedBalanceRow("Locked", amount, timeSpan.blocks, timeSpan.timeRemaining)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BalanceRow(
|
||||
label: String,
|
||||
amount: MoneroAmount,
|
||||
format: MoneroCurrency.Format = MoneroCurrency.Format(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(text = label)
|
||||
Text(text = format.format(amount))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LockedBalanceRow(
|
||||
label: String,
|
||||
amount: MoneroAmount,
|
||||
blockCount: Int,
|
||||
timeRemaining: Duration,
|
||||
moneroFormat: MoneroCurrency.Format = MoneroCurrency.DefaultFormat,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
val durationText =
|
||||
"${timeRemaining.toKotlinDuration()} ($blockCount blocks)"
|
||||
Column {
|
||||
Text(text = label)
|
||||
Text(text = durationText, fontSize = 12.sp)
|
||||
}
|
||||
Text(text = moneroFormat.format(amount))
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun WalletBalanceDetailsPreview() {
|
||||
AppTheme {
|
||||
WalletBalanceView(
|
||||
balance = Balance(
|
||||
pendingAmount = 5.xmr,
|
||||
timeLockedAmounts = listOf(
|
||||
TimeLocked(10.xmr, BlockchainTime.Genesis),
|
||||
TimeLocked(BigDecimal("0.000000000001").xmr, BlockchainTime.Block(10)),
|
||||
TimeLocked(30.xmr, BlockchainTime.Block(500)),
|
||||
),
|
||||
),
|
||||
blockchainTime = BlockchainTime.Genesis,
|
||||
)
|
||||
}
|
||||
}
|
@ -113,11 +113,16 @@ private fun WalletScreenPopulated(
|
||||
text = buildAnnotatedString {
|
||||
append(MoneroCurrency.SYMBOL + " ")
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(MoneroCurrency.Formatter(precision = 5).format(ledger.balance.confirmedAmount))
|
||||
append(MoneroCurrency.Format(precision = 5).format(ledger.balance.confirmedAmount))
|
||||
}
|
||||
}
|
||||
)
|
||||
Text(text = walletConfig.name, style = MaterialTheme.typography.headlineSmall)
|
||||
|
||||
WalletBalanceView(
|
||||
balance = ledger.balance,
|
||||
blockchainTime = ledger.checkedAt,
|
||||
)
|
||||
}
|
||||
|
||||
if (showRenameDialog) {
|
||||
|
@ -71,6 +71,6 @@ sealed interface WalletUiState {
|
||||
val ledger: Ledger,
|
||||
) : WalletUiState
|
||||
|
||||
object Error : WalletUiState
|
||||
object Loading : WalletUiState
|
||||
data object Error : WalletUiState
|
||||
data object Loading : WalletUiState
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ object MoneroCurrency {
|
||||
|
||||
const val MAX_PRECISION = MoneroAmount.ATOMIC_UNIT_SCALE
|
||||
|
||||
val DefaultFormatter = Formatter()
|
||||
val DefaultFormat = Format()
|
||||
|
||||
data class Formatter(
|
||||
data class Format(
|
||||
val precision: Int = MAX_PRECISION,
|
||||
val locale: Locale = Locale.US,
|
||||
) {
|
||||
|
Loading…
Reference in New Issue
Block a user