fix: ui stuff

This commit is contained in:
2026-06-04 15:04:29 +02:00
parent 18cbf94092
commit 4dadc75aca
4 changed files with 74 additions and 47 deletions
@@ -196,7 +196,7 @@ fun HistoryScreen(
derivedStateOf { derivedStateOf {
val lastVisible = listState.layoutInfo.visibleItemsInfo.lastOrNull() val lastVisible = listState.layoutInfo.visibleItemsInfo.lastOrNull()
val totalItems = listState.layoutInfo.totalItemsCount val totalItems = listState.layoutInfo.totalItemsCount
lastVisible != null && lastVisible.index >= totalItems - 3 lastVisible != null && lastVisible.index >= totalItems - 8
} }
} }
LaunchedEffect(shouldLoadMore) { LaunchedEffect(shouldLoadMore) {
@@ -88,6 +88,15 @@ internal fun QrDisplayCard(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
OutlinedButton(
onClick = { IntentUtils.shareText(context, textToCopy, shareTitle) },
modifier = Modifier.weight(1f)
) {
Icon(Icons.Filled.Share, contentDescription = "Share",
modifier = Modifier.size(18.dp))
Spacer(Modifier.width(6.dp))
Text("Share")
}
OutlinedButton( OutlinedButton(
onClick = { onClick = {
scope.launch { scope.launch {
@@ -103,17 +112,6 @@ internal fun QrDisplayCard(
Spacer(Modifier.width(6.dp)) Spacer(Modifier.width(6.dp))
Text("Copy") Text("Copy")
} }
Button(
onClick = { IntentUtils.shareText(context, textToCopy, shareTitle) },
modifier = Modifier.weight(1f)
) {
Icon(Icons.Filled.Share, contentDescription = "Share",
modifier = Modifier.size(18.dp))
Spacer(Modifier.width(6.dp))
Text("Share")
}
BrightnessToggleButton(isOn = brightnessOn, onToggle = onToggleBrightness) BrightnessToggleButton(isOn = brightnessOn, onToggle = onToggleBrightness)
} }
} }
@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -27,6 +28,7 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
@@ -47,7 +49,9 @@ import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -339,7 +343,7 @@ private fun ReceiveIdleContent(
Column( Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.Top
) { ) {
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))
@@ -354,7 +358,7 @@ private fun ReceiveIdleContent(
style = MaterialTheme.typography.headlineSmall style = MaterialTheme.typography.headlineSmall
) )
if (lightningAddress != null) { if (lightningAddress != null) {
IconButton(onClick = onToggleAddressWithDismiss) { // ← use wrapped version IconButton(onClick = onToggleAddressWithDismiss) {
Text( Text(
text = "@", text = "@",
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
@@ -404,6 +408,10 @@ private fun ReceiveIdleContent(
} }
} }
if (showAddress && lightningAddress != null) {
Spacer(Modifier.height(16.dp))
}
if (step == 1) { if (step == 1) {
AmountStepContent( AmountStepContent(
fiatRate = fiatRate, fiatRate = fiatRate,
@@ -448,6 +456,11 @@ private fun AmountStepContent(
val parsedAmount = amountText.trim().toDoubleOrNull() val parsedAmount = amountText.trim().toDoubleOrNull()
val amountValid = parsedAmount != null && parsedAmount > 0 val amountValid = parsedAmount != null && parsedAmount > 0
fun tryNext() {
if (!amountValid) amountError = "Enter a valid amount"
else { amountError = null; onNext(amountText, activeUnit) }
}
val conversionLabel: String? = remember(amountText, activeUnit, fiatRate, fiatCurrency) { val conversionLabel: String? = remember(amountText, activeUnit, fiatRate, fiatCurrency) {
if (!showFiatToggle) return@remember null if (!showFiatToggle) return@remember null
val number = amountText.trim().toDoubleOrNull() ?: return@remember null val number = amountText.trim().toDoubleOrNull() ?: return@remember null
@@ -470,7 +483,12 @@ private fun AmountStepContent(
value = amountText, value = amountText,
onValueChange = { amountText = it; amountError = null }, onValueChange = { amountText = it; amountError = null },
placeholder = { placeholder = {
Text(if (activeUnit == AmountUnit.SATS || !showFiatToggle) "0" else "0.00") Text(
if (activeUnit == AmountUnit.SATS || !showFiatToggle) "0" else "0.00",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.End,
fontFamily = FontFamily.Monospace
)
}, },
isError = amountError != null, isError = amountError != null,
supportingText = when { supportingText = when {
@@ -478,34 +496,39 @@ private fun AmountStepContent(
conversionLabel != null -> { { Text(conversionLabel, color = MaterialTheme.colorScheme.onSurfaceVariant) } } conversionLabel != null -> { { Text(conversionLabel, color = MaterialTheme.colorScheme.onSurfaceVariant) } }
else -> null else -> null
}, },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), textStyle = LocalTextStyle.current.copy(
textAlign = TextAlign.End,
fontFamily = FontFamily.Monospace
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Decimal,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = { tryNext() }
),
singleLine = true, singleLine = true,
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.onFocusChanged { if (it.isFocused && addressShowing) onCollapseAddress() } .onFocusChanged { if (it.isFocused && addressShowing) onCollapseAddress() }
) )
if (showFiatToggle) { UnitWheelPicker(
UnitWheelPicker( units = if (showFiatToggle) listOf("sats", fiatCurrency!!) else listOf("sats"),
units = listOf("sats", fiatCurrency), selectedIndex = if (activeUnit == AmountUnit.SATS) 0 else 1,
selectedIndex = if (activeUnit == AmountUnit.SATS) 0 else 1, onIndexSelected = { newIndex ->
onIndexSelected = { newIndex -> val newUnit = if (newIndex == 0) AmountUnit.SATS else AmountUnit.FIAT
val newUnit = if (newIndex == 0) AmountUnit.SATS else AmountUnit.FIAT if (newUnit != activeUnit) {
if (newUnit != activeUnit) { activeUnit = newUnit
activeUnit = newUnit amountText = ""
amountText = "" }
} },
}, modifier = Modifier.width(64.dp)
modifier = Modifier.width(64.dp) )
)
}
} }
Button( OutlinedButton(
onClick = { onClick = { tryNext() },
if (!amountValid) amountError = "Enter a valid amount"
else { amountError = null; onNext(amountText, activeUnit) }
},
enabled = amountText.isNotBlank(), enabled = amountText.isNotBlank(),
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
@@ -50,12 +50,19 @@ fun SendScreen(vm: WalletViewModel, onViewDetails: (paymentHash: String) -> Unit
.fillMaxSize() .fillMaxSize()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.padding(24.dp), .padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top verticalArrangement = Arrangement.Top
) { ) {
Spacer(Modifier.height(16.dp)) Spacer(Modifier.height(32.dp))
Text("Send", style = MaterialTheme.typography.headlineSmall)
Spacer(Modifier.height(24.dp)) // ── Header row (matches ReceiveIdleContent) ──────────────────────────
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text("Send", style = MaterialTheme.typography.headlineSmall)
}
if (sendState !is SendState.PaymentSent) { if (sendState !is SendState.PaymentSent) {
OutlinedTextField( OutlinedTextField(
@@ -69,8 +76,8 @@ fun SendScreen(vm: WalletViewModel, onViewDetails: (paymentHash: String) -> Unit
maxLines = 4, maxLines = 4,
textStyle = MaterialTheme.typography.bodySmall.copy(fontFamily = FontFamily.Monospace), textStyle = MaterialTheme.typography.bodySmall.copy(fontFamily = FontFamily.Monospace),
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Uri, keyboardType = KeyboardType.Uri,
imeAction = ImeAction.Go imeAction = ImeAction.Go
), ),
keyboardActions = KeyboardActions( keyboardActions = KeyboardActions(
onGo = { if (input.isNotBlank()) vm.scan(input) } onGo = { if (input.isNotBlank()) vm.scan(input) }
@@ -123,7 +130,7 @@ fun SendScreen(vm: WalletViewModel, onViewDetails: (paymentHash: String) -> Unit
is SendState.Bolt11Decoded -> { is SendState.Bolt11Decoded -> {
Bolt11ConfirmCard( Bolt11ConfirmCard(
state = state, state = state,
activity = activity, activity = activity,
vm = vm, vm = vm,
fiatRate = fiatRate, fiatRate = fiatRate,
fiatCurrency = fiatCurrency fiatCurrency = fiatCurrency
@@ -141,15 +148,14 @@ fun SendScreen(vm: WalletViewModel, onViewDetails: (paymentHash: String) -> Unit
is SendState.LnurlInvoiceReady -> { is SendState.LnurlInvoiceReady -> {
LnurlInvoiceConfirmCard( LnurlInvoiceConfirmCard(
state = state, state = state,
activity = activity, activity = activity,
vm = vm, vm = vm,
fiatRate = fiatRate, fiatRate = fiatRate,
fiatCurrency = fiatCurrency fiatCurrency = fiatCurrency
) )
} }
is SendState.Paying -> { is SendState.Paying -> {
Spacer(Modifier.height(16.dp)) Spacer(Modifier.height(16.dp))
CircularProgressIndicator() CircularProgressIndicator()