refactor
This commit is contained in:
@@ -3,6 +3,7 @@ package com.bitcointxoko.gudariwallet.ui
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.runtime.*
|
||||
@@ -10,14 +11,11 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Visibility
|
||||
import androidx.compose.material.icons.filled.VisibilityOff
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||
@@ -29,7 +27,7 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import com.bitcointxoko.gudariwallet.util.formatFiat
|
||||
import kotlinx.coroutines.delay
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
|
||||
|
||||
|
||||
@@ -43,18 +41,6 @@ fun HomeTab(
|
||||
|
||||
val balanceHidden by vm.balanceHidden.collectAsState()
|
||||
|
||||
var eyeVisible by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(balanceHidden) {
|
||||
eyeVisible = true
|
||||
delay(1_500)
|
||||
eyeVisible = false
|
||||
}
|
||||
val eyeAlpha by animateFloatAsState(
|
||||
targetValue = if (eyeVisible) 1f else 0f,
|
||||
animationSpec = tween(durationMillis = 400),
|
||||
label = "eyeAlpha"
|
||||
)
|
||||
|
||||
val isRefreshing = balanceState is BalanceState.Loading
|
||||
|| (balanceState as? BalanceState.Success)?.isRefreshing == true
|
||||
|
||||
@@ -96,9 +82,7 @@ fun HomeTab(
|
||||
}
|
||||
}
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (balanceHidden)
|
||||
@@ -109,14 +93,15 @@ fun HomeTab(
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.alpha(eyeAlpha)
|
||||
)
|
||||
|
||||
Spacer(Modifier.width(8.dp))
|
||||
|
||||
Text(
|
||||
text = if (balanceHidden) "••••••" else "${s.sats}",
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
text = if (balanceHidden) "••••••" else formatSats(s.sats),
|
||||
style = MaterialTheme.typography.displayLarge.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
),
|
||||
color = if (balanceHidden)
|
||||
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.35f)
|
||||
else
|
||||
@@ -124,74 +109,93 @@ fun HomeTab(
|
||||
maxLines = 1,
|
||||
softWrap = false,
|
||||
modifier = Modifier
|
||||
.weight(1f, fill = false)
|
||||
.clickable(
|
||||
onClick = { vm.toggleBalanceVisibility() },
|
||||
onClickLabel = if (balanceHidden) "Reveal balance" else "Hide balance",
|
||||
.widthIn(max = 280.dp)
|
||||
.combinedClickable(
|
||||
onClick = { if (!balanceHidden) vm.toggleBalanceVisibility() },
|
||||
onClickLabel = if (balanceHidden) null else "Hide balance",
|
||||
onLongClick = { if (balanceHidden) vm.toggleBalanceVisibility() },
|
||||
onLongClickLabel = if (balanceHidden) "Reveal balance" else null,
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
)
|
||||
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Spacer(Modifier.size(20.dp))
|
||||
Text(
|
||||
text = "sats",
|
||||
style = MaterialTheme.typography.titleMedium.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(Modifier.width(8.dp))
|
||||
}
|
||||
Text(
|
||||
text = "sats",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(Modifier.height(2.dp))
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
if (s.fiatAmount != null && s.fiatCurrency != null) {
|
||||
Text(
|
||||
text = if (balanceHidden) "≈ ••••"
|
||||
else "≈ ${formatFiat(s.fiatAmount, s.fiatCurrency)}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (balanceHidden)
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.35f)
|
||||
else
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.75f),
|
||||
maxLines = 1,
|
||||
softWrap = false
|
||||
)
|
||||
Spacer(Modifier.width(2.dp))
|
||||
}
|
||||
val currency = selectedCurrency
|
||||
if (currency != null) {
|
||||
// ── Fiat amount + tappable currency code ──────────────────────────
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { showCurrencyPicker = true },
|
||||
onClickLabel = "Change currency",
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
.padding(start = 0.dp, end = 4.dp, top = 4.dp, bottom = 4.dp)
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = selectedCurrency ?: "—",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = if (selectedCurrency != null)
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.75f)
|
||||
else
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f)
|
||||
)
|
||||
// Triangle only shown when null — signals "tap to set a currency"
|
||||
if (selectedCurrency == null) {
|
||||
if (s.fiatAmount != null && s.fiatCurrency != null) {
|
||||
Text(
|
||||
text = if (balanceHidden) "••••"
|
||||
else formatFiat(s.fiatAmount, s.fiatCurrency),
|
||||
style = MaterialTheme.typography.bodyMedium.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
),
|
||||
color = if (balanceHidden)
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.35f)
|
||||
else
|
||||
MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.75f),
|
||||
maxLines = 1,
|
||||
softWrap = false
|
||||
)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
}
|
||||
// Currency code — always shown when a currency is selected, tappable to change
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
onClick = { showCurrencyPicker = true },
|
||||
onClickLabel = "Change currency",
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
)
|
||||
.padding(horizontal = 4.dp, vertical = 4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = currency,
|
||||
style = MaterialTheme.typography.bodyMedium.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.75f)
|
||||
)
|
||||
Spacer(Modifier.width(2.dp))
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowDropDown,
|
||||
contentDescription = "Change currency",
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f),
|
||||
modifier = Modifier.size(14.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ── No currency selected — ghost prompt ───────────────────────────
|
||||
TextButton(
|
||||
onClick = { showCurrencyPicker = true },
|
||||
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 2.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "+ Show fiat",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.45f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
if (!s.isRefreshing) {
|
||||
@@ -231,8 +235,10 @@ fun HomeTab(
|
||||
is BalanceState.Error -> {
|
||||
if (s.staleSats != null) {
|
||||
Text(
|
||||
text = if (balanceHidden) "••••••" else "${s.staleSats}",
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
text = if (balanceHidden) "••••••" else formatSats(s.staleSats),
|
||||
style = MaterialTheme.typography.displayLarge.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
),
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.4f)
|
||||
)
|
||||
Text(
|
||||
@@ -264,6 +270,9 @@ fun HomeTab(
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatSats(sats: Long): String =
|
||||
"%,d".format(sats).replace(',', ' ')
|
||||
|
||||
private fun formatLastUpdated(epochMs: Long): String {
|
||||
val ageMs = System.currentTimeMillis() - epochMs
|
||||
return when {
|
||||
|
||||
Reference in New Issue
Block a user