mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 05:05:20 +00:00
better receive view but it freezes
This commit is contained in:
@@ -27,10 +27,11 @@ fun QRCodeCanvas(
|
|||||||
size: Dp = 200.dp
|
size: Dp = 200.dp
|
||||||
) {
|
) {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val sizePx = with(density) { size.toPx() }.toInt()
|
|
||||||
|
|
||||||
|
// Use a larger fixed size for better quality
|
||||||
val qrCodeBitMatrix = remember(text) {
|
val qrCodeBitMatrix = remember(text) {
|
||||||
try {
|
try {
|
||||||
|
val sizePx = with(density) { 512.dp.toPx() }.toInt() // Fixed high resolution
|
||||||
val writer = QRCodeWriter()
|
val writer = QRCodeWriter()
|
||||||
writer.encode(text, BarcodeFormat.QR_CODE, sizePx, sizePx)
|
writer.encode(text, BarcodeFormat.QR_CODE, sizePx, sizePx)
|
||||||
} catch (e: WriterException) {
|
} catch (e: WriterException) {
|
||||||
@@ -40,20 +41,21 @@ fun QRCodeCanvas(
|
|||||||
|
|
||||||
Canvas(
|
Canvas(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.size(size)
|
|
||||||
.background(Color.White)
|
.background(Color.White)
|
||||||
) {
|
) {
|
||||||
qrCodeBitMatrix?.let { bitMatrix ->
|
qrCodeBitMatrix?.let { bitMatrix ->
|
||||||
drawQRCode(bitMatrix, sizePx)
|
// Use the actual canvas size, not a calculated size
|
||||||
|
val canvasSize = minOf(this.size.width, this.size.height)
|
||||||
|
drawQRCode(bitMatrix, canvasSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DrawScope.drawQRCode(
|
private fun DrawScope.drawQRCode(
|
||||||
bitMatrix: com.google.zxing.common.BitMatrix,
|
bitMatrix: com.google.zxing.common.BitMatrix,
|
||||||
sizePx: Int
|
sizePx: Float
|
||||||
) {
|
) {
|
||||||
val cellSize = sizePx.toFloat() / bitMatrix.width
|
val cellSize = sizePx / bitMatrix.width
|
||||||
|
|
||||||
for (x in 0 until bitMatrix.width) {
|
for (x in 0 until bitMatrix.width) {
|
||||||
for (y in 0 until bitMatrix.height) {
|
for (y in 0 until bitMatrix.height) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.bitchat.android.wallet.ui
|
package com.bitchat.android.wallet.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
@@ -13,132 +14,156 @@ import androidx.compose.runtime.*
|
|||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
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.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.window.Dialog
|
|
||||||
import androidx.compose.ui.window.DialogProperties
|
|
||||||
import com.bitchat.android.wallet.data.MintQuote
|
import com.bitchat.android.wallet.data.MintQuote
|
||||||
import com.bitchat.android.wallet.data.CashuToken
|
import com.bitchat.android.wallet.data.CashuToken
|
||||||
import com.bitchat.android.wallet.viewmodel.WalletViewModel
|
import com.bitchat.android.wallet.viewmodel.WalletViewModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive dialog with options for Cashu tokens or Lightning invoices
|
* Full-screen receive view with options for Cashu tokens or Lightning invoices
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun ReceiveDialog(
|
fun ReceiveView(
|
||||||
viewModel: WalletViewModel,
|
viewModel: WalletViewModel,
|
||||||
onDismiss: () -> Unit
|
onNavigateBack: () -> Unit
|
||||||
) {
|
) {
|
||||||
val receiveType by viewModel.receiveType.observeAsState(WalletViewModel.ReceiveType.CASHU)
|
val receiveType by viewModel.receiveType.observeAsState(WalletViewModel.ReceiveType.CASHU)
|
||||||
val decodedToken by viewModel.decodedToken.observeAsState()
|
val decodedToken by viewModel.decodedToken.observeAsState()
|
||||||
val currentMintQuote by viewModel.currentMintQuote.observeAsState()
|
val currentMintQuote by viewModel.currentMintQuote.observeAsState()
|
||||||
val isLoading by viewModel.isLoading.observeAsState(false)
|
val isLoading by viewModel.isLoading.observeAsState(false)
|
||||||
|
|
||||||
Dialog(
|
// Determine if we should show type selector
|
||||||
onDismissRequest = onDismiss,
|
val showTypeSelector = decodedToken == null && currentMintQuote == null
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(Color.Black)
|
||||||
) {
|
) {
|
||||||
Card(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxSize()
|
||||||
.padding(16.dp),
|
.padding(16.dp)
|
||||||
shape = RoundedCornerShape(16.dp),
|
.verticalScroll(rememberScrollState())
|
||||||
colors = CardDefaults.cardColors(containerColor = Color(0xFF1A1A1A))
|
|
||||||
) {
|
) {
|
||||||
Column(
|
// Header with back button
|
||||||
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(24.dp)
|
.fillMaxWidth()
|
||||||
.verticalScroll(rememberScrollState())
|
.padding(bottom = 24.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
// Header
|
IconButton(
|
||||||
Row(
|
onClick = onNavigateBack,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
.size(48.dp)
|
||||||
verticalAlignment = Alignment.CenterVertically
|
.clip(RoundedCornerShape(12.dp))
|
||||||
|
.background(Color(0xFF1A1A1A))
|
||||||
) {
|
) {
|
||||||
Text(
|
Icon(
|
||||||
text = "Receive",
|
imageVector = Icons.Filled.ArrowBack,
|
||||||
color = Color.White,
|
contentDescription = "Back",
|
||||||
fontSize = 20.sp,
|
tint = Color.White,
|
||||||
fontWeight = FontWeight.Bold,
|
modifier = Modifier.size(24.dp)
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
|
|
||||||
IconButton(onClick = onDismiss) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.Close,
|
|
||||||
contentDescription = "Close",
|
|
||||||
tint = Color.Gray
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
|
|
||||||
// Receive type selector
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
FilterChip(
|
|
||||||
onClick = { viewModel.setReceiveType(WalletViewModel.ReceiveType.CASHU) },
|
|
||||||
label = {
|
|
||||||
Text(
|
|
||||||
text = "Cashu",
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
},
|
|
||||||
selected = receiveType == WalletViewModel.ReceiveType.CASHU,
|
|
||||||
colors = FilterChipDefaults.filterChipColors(
|
|
||||||
selectedContainerColor = Color(0xFF00C851),
|
|
||||||
selectedLabelColor = Color.Black
|
|
||||||
),
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
|
|
||||||
FilterChip(
|
|
||||||
onClick = { viewModel.setReceiveType(WalletViewModel.ReceiveType.LIGHTNING) },
|
|
||||||
label = {
|
|
||||||
Text(
|
|
||||||
text = "Lightning",
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
},
|
|
||||||
selected = receiveType == WalletViewModel.ReceiveType.LIGHTNING,
|
|
||||||
colors = FilterChipDefaults.filterChipColors(
|
|
||||||
selectedContainerColor = Color(0xFF00C851),
|
|
||||||
selectedLabelColor = Color.Black
|
|
||||||
),
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Text(
|
||||||
|
text = "RECEIVE",
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 2.sp
|
||||||
|
)
|
||||||
|
|
||||||
// Content based on receive type
|
// Spacer to center the title
|
||||||
when (receiveType) {
|
Spacer(modifier = Modifier.width(48.dp))
|
||||||
WalletViewModel.ReceiveType.CASHU -> {
|
}
|
||||||
CashuReceiveContent(
|
|
||||||
viewModel = viewModel,
|
// Receive type selector (only show when not displaying QR code or token info)
|
||||||
decodedToken = decodedToken,
|
if (showTypeSelector) {
|
||||||
isLoading = isLoading
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 24.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color(0xFF1A1A1A))
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
FilterChip(
|
||||||
|
onClick = { viewModel.setReceiveType(WalletViewModel.ReceiveType.CASHU) },
|
||||||
|
label = {
|
||||||
|
Text(
|
||||||
|
text = "Cashu Token",
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
},
|
||||||
|
selected = receiveType == WalletViewModel.ReceiveType.CASHU,
|
||||||
|
colors = FilterChipDefaults.filterChipColors(
|
||||||
|
selectedContainerColor = Color(0xFF00C851),
|
||||||
|
selectedLabelColor = Color.Black,
|
||||||
|
containerColor = Color(0xFF2A2A2A),
|
||||||
|
labelColor = Color.White
|
||||||
|
),
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
WalletViewModel.ReceiveType.LIGHTNING -> {
|
FilterChip(
|
||||||
LightningReceiveContent(
|
onClick = { viewModel.setReceiveType(WalletViewModel.ReceiveType.LIGHTNING) },
|
||||||
viewModel = viewModel,
|
label = {
|
||||||
currentMintQuote = currentMintQuote,
|
Text(
|
||||||
isLoading = isLoading
|
text = "Lightning Invoice",
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
},
|
||||||
|
selected = receiveType == WalletViewModel.ReceiveType.LIGHTNING,
|
||||||
|
colors = FilterChipDefaults.filterChipColors(
|
||||||
|
selectedContainerColor = Color(0xFF00C851),
|
||||||
|
selectedLabelColor = Color.Black,
|
||||||
|
containerColor = Color(0xFF2A2A2A),
|
||||||
|
labelColor = Color.White
|
||||||
|
),
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Content based on receive type
|
||||||
|
when (receiveType) {
|
||||||
|
WalletViewModel.ReceiveType.CASHU -> {
|
||||||
|
CashuReceiveContent(
|
||||||
|
viewModel = viewModel,
|
||||||
|
decodedToken = decodedToken,
|
||||||
|
isLoading = isLoading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
WalletViewModel.ReceiveType.LIGHTNING -> {
|
||||||
|
LightningReceiveContent(
|
||||||
|
viewModel = viewModel,
|
||||||
|
currentMintQuote = currentMintQuote,
|
||||||
|
isLoading = isLoading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,116 +179,126 @@ private fun CashuReceiveContent(
|
|||||||
|
|
||||||
if (decodedToken != null) {
|
if (decodedToken != null) {
|
||||||
// Show decoded token info and receive button
|
// Show decoded token info and receive button
|
||||||
Column {
|
Column(
|
||||||
Text(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = "Cashu Token Details",
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
color = Color(0xFF00C851),
|
) {
|
||||||
fontSize = 16.sp,
|
// Token info card
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
shape = RoundedCornerShape(8.dp),
|
.fillMaxWidth()
|
||||||
colors = CardDefaults.cardColors(containerColor = Color(0xFF2A2A2A))
|
.padding(bottom = 32.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color(0xFF1A1A1A))
|
||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding(16.dp)) {
|
Column(
|
||||||
Row(
|
modifier = Modifier
|
||||||
modifier = Modifier.fillMaxWidth(),
|
.fillMaxWidth()
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
.padding(24.dp),
|
||||||
) {
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
Text(
|
) {
|
||||||
text = "Amount:",
|
Icon(
|
||||||
color = Color.Gray,
|
imageVector = Icons.Filled.Toll,
|
||||||
fontFamily = FontFamily.Monospace
|
contentDescription = "Token",
|
||||||
)
|
tint = Color(0xFF00C851),
|
||||||
Text(
|
modifier = Modifier.size(48.dp)
|
||||||
text = formatSats(decodedToken.amount.toLong()),
|
)
|
||||||
color = Color.White,
|
|
||||||
fontFamily = FontFamily.Monospace,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
Row(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
text = "CASHU TOKEN",
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
color = Color(0xFF00C851),
|
||||||
) {
|
fontSize = 16.sp,
|
||||||
Text(
|
fontWeight = FontWeight.Bold,
|
||||||
text = "Mint:",
|
fontFamily = FontFamily.Monospace,
|
||||||
color = Color.Gray,
|
letterSpacing = 1.sp
|
||||||
fontFamily = FontFamily.Monospace
|
)
|
||||||
)
|
|
||||||
Text(
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
text = decodedToken.mint.take(20) + if (decodedToken.mint.length > 20) "..." else "",
|
|
||||||
color = Color.White,
|
// Amount
|
||||||
fontFamily = FontFamily.Monospace
|
Text(
|
||||||
)
|
text = formatSats(decodedToken.amount.toLong()),
|
||||||
}
|
color = Color.White,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Mint info
|
||||||
|
Text(
|
||||||
|
text = "From: ${decodedToken.mint.take(30)}${if (decodedToken.mint.length > 30) "..." else ""}",
|
||||||
|
color = Color.Gray,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
if (!decodedToken.memo.isNullOrEmpty()) {
|
if (!decodedToken.memo.isNullOrEmpty()) {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
Row(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
text = "Memo: ${decodedToken.memo}",
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
color = Color.Gray,
|
||||||
) {
|
fontSize = 14.sp,
|
||||||
Text(
|
fontFamily = FontFamily.Monospace,
|
||||||
text = "Memo:",
|
textAlign = TextAlign.Center
|
||||||
color = Color.Gray,
|
)
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = decodedToken.memo,
|
|
||||||
color = Color.White,
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
// Receive button
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.receiveCashuToken(decodedToken.token)
|
viewModel.receiveCashuToken(decodedToken.token)
|
||||||
},
|
},
|
||||||
enabled = !isLoading,
|
enabled = !isLoading,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color(0xFF00C851)
|
containerColor = Color(0xFF00C851),
|
||||||
|
disabledContainerColor = Color(0xFF2A2A2A)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(8.dp)
|
shape = RoundedCornerShape(16.dp)
|
||||||
) {
|
) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
modifier = Modifier.size(16.dp)
|
modifier = Modifier.size(24.dp)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Icon(
|
Row(
|
||||||
imageVector = Icons.Filled.Download,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
contentDescription = "Receive",
|
) {
|
||||||
tint = Color.Black
|
Icon(
|
||||||
)
|
imageVector = Icons.Filled.Download,
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
contentDescription = "Receive",
|
||||||
Text(
|
tint = Color.Black,
|
||||||
text = "Receive Token",
|
modifier = Modifier.size(24.dp)
|
||||||
color = Color.Black,
|
)
|
||||||
fontWeight = FontWeight.Bold,
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
fontFamily = FontFamily.Monospace
|
Text(
|
||||||
)
|
text = "RECEIVE TOKEN",
|
||||||
|
color = Color.Black,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Show token input
|
// Show token input
|
||||||
Column {
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
// Token input field
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = token,
|
value = token,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -288,11 +323,17 @@ private fun CashuReceiveContent(
|
|||||||
colors = OutlinedTextFieldDefaults.colors(
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
focusedBorderColor = Color(0xFF00C851),
|
focusedBorderColor = Color(0xFF00C851),
|
||||||
focusedLabelColor = Color(0xFF00C851),
|
focusedLabelColor = Color(0xFF00C851),
|
||||||
|
unfocusedBorderColor = Color(0xFF2A2A2A),
|
||||||
|
unfocusedLabelColor = Color.Gray,
|
||||||
unfocusedTextColor = Color.White,
|
unfocusedTextColor = Color.White,
|
||||||
focusedTextColor = Color.White
|
focusedTextColor = Color.White
|
||||||
),
|
),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
maxLines = 3,
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 24.dp),
|
||||||
|
minLines = 3,
|
||||||
|
maxLines = 4,
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -300,7 +341,7 @@ private fun CashuReceiveContent(
|
|||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.CameraAlt,
|
imageVector = Icons.Filled.QrCode,
|
||||||
contentDescription = "Scan QR",
|
contentDescription = "Scan QR",
|
||||||
tint = Color(0xFF00C851)
|
tint = Color(0xFF00C851)
|
||||||
)
|
)
|
||||||
@@ -308,8 +349,7 @@ private fun CashuReceiveContent(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
// Paste button
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
clipboardManager.getText()?.text?.let { clipText ->
|
clipboardManager.getText()?.text?.let { clipText ->
|
||||||
@@ -319,28 +359,37 @@ private fun CashuReceiveContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color.Transparent
|
containerColor = Color.Transparent
|
||||||
),
|
),
|
||||||
border = androidx.compose.foundation.BorderStroke(
|
border = androidx.compose.foundation.BorderStroke(
|
||||||
1.dp,
|
2.dp,
|
||||||
Color(0xFF00C851)
|
Color(0xFF00C851)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(8.dp)
|
shape = RoundedCornerShape(16.dp)
|
||||||
) {
|
) {
|
||||||
Icon(
|
Row(
|
||||||
imageVector = Icons.Filled.ContentPaste,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
contentDescription = "Paste",
|
) {
|
||||||
tint = Color(0xFF00C851)
|
Icon(
|
||||||
)
|
imageVector = Icons.Filled.ContentPaste,
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
contentDescription = "Paste",
|
||||||
Text(
|
tint = Color(0xFF00C851),
|
||||||
text = "Paste from clipboard",
|
modifier = Modifier.size(24.dp)
|
||||||
color = Color(0xFF00C851),
|
)
|
||||||
fontWeight = FontWeight.Bold,
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
fontFamily = FontFamily.Monospace
|
Text(
|
||||||
)
|
text = "PASTE FROM CLIPBOARD",
|
||||||
|
color = Color(0xFF00C851),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,29 +407,91 @@ private fun LightningReceiveContent(
|
|||||||
|
|
||||||
if (currentMintQuote != null) {
|
if (currentMintQuote != null) {
|
||||||
// Show Lightning invoice QR code and details
|
// Show Lightning invoice QR code and details
|
||||||
Column {
|
Column(
|
||||||
Text(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = "Lightning Invoice",
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
color = Color(0xFF00C851),
|
) {
|
||||||
fontSize = 16.sp,
|
// Invoice header
|
||||||
fontWeight = FontWeight.Bold,
|
Card(
|
||||||
fontFamily = FontFamily.Monospace
|
modifier = Modifier
|
||||||
)
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 24.dp),
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color(0xFF1A1A1A))
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(24.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.FlashOn,
|
||||||
|
contentDescription = "Lightning",
|
||||||
|
tint = Color(0xFFFFB000),
|
||||||
|
modifier = Modifier.size(48.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "LIGHTNING INVOICE",
|
||||||
|
color = Color(0xFFFFB000),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
|
// Amount
|
||||||
|
Text(
|
||||||
|
text = formatSats(currentMintQuote.amount.toLong()),
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 32.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
// Status
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.size(12.dp)
|
||||||
|
.clip(RoundedCornerShape(6.dp))
|
||||||
|
.background(if (currentMintQuote.paid) Color(0xFF00C851) else Color(0xFFFFB000))
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = if (currentMintQuote.paid) "PAID" else "WAITING FOR PAYMENT",
|
||||||
|
color = if (currentMintQuote.paid) Color(0xFF00C851) else Color(0xFFFFB000),
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// QR Code
|
// QR Code
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.aspectRatio(1f),
|
.aspectRatio(1f)
|
||||||
shape = RoundedCornerShape(8.dp),
|
.padding(bottom = 24.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
colors = CardDefaults.cardColors(containerColor = Color.White)
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxSize(),
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
QRCodeCanvas(
|
QRCodeCanvas(
|
||||||
@@ -390,85 +501,50 @@ private fun LightningReceiveContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
|
|
||||||
// Invoice details
|
|
||||||
Card(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
shape = RoundedCornerShape(8.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = Color(0xFF2A2A2A))
|
|
||||||
) {
|
|
||||||
Column(modifier = Modifier.padding(16.dp)) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Amount:",
|
|
||||||
color = Color.Gray,
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = formatSats(currentMintQuote.amount.toLong()),
|
|
||||||
color = Color.White,
|
|
||||||
fontFamily = FontFamily.Monospace,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Status:",
|
|
||||||
color = Color.Gray,
|
|
||||||
fontFamily = FontFamily.Monospace
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = if (currentMintQuote.paid) "Paid" else "Waiting...",
|
|
||||||
color = if (currentMintQuote.paid) Color(0xFF00C851) else Color.Yellow,
|
|
||||||
fontFamily = FontFamily.Monospace,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
|
|
||||||
// Copy invoice button
|
// Copy invoice button
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
clipboardManager.setText(AnnotatedString(currentMintQuote.request))
|
clipboardManager.setText(AnnotatedString(currentMintQuote.request))
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color.Transparent
|
containerColor = Color.Transparent
|
||||||
),
|
),
|
||||||
border = androidx.compose.foundation.BorderStroke(
|
border = androidx.compose.foundation.BorderStroke(
|
||||||
1.dp,
|
2.dp,
|
||||||
Color(0xFF00C851)
|
Color(0xFFFFB000)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(8.dp)
|
shape = RoundedCornerShape(16.dp)
|
||||||
) {
|
) {
|
||||||
Icon(
|
Row(
|
||||||
imageVector = Icons.Filled.ContentCopy,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
contentDescription = "Copy",
|
) {
|
||||||
tint = Color(0xFF00C851)
|
Icon(
|
||||||
)
|
imageVector = Icons.Filled.ContentCopy,
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
contentDescription = "Copy",
|
||||||
Text(
|
tint = Color(0xFFFFB000),
|
||||||
text = "Copy Invoice",
|
modifier = Modifier.size(24.dp)
|
||||||
color = Color(0xFF00C851),
|
)
|
||||||
fontWeight = FontWeight.Bold,
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
fontFamily = FontFamily.Monospace
|
Text(
|
||||||
)
|
text = "COPY INVOICE",
|
||||||
|
color = Color(0xFFFFB000),
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Show amount input
|
// Show amount input
|
||||||
Column {
|
Column(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
// Amount input
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = amount,
|
value = amount,
|
||||||
onValueChange = { amount = it },
|
onValueChange = { amount = it },
|
||||||
@@ -482,14 +558,18 @@ private fun LightningReceiveContent(
|
|||||||
colors = OutlinedTextFieldDefaults.colors(
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
focusedBorderColor = Color(0xFF00C851),
|
focusedBorderColor = Color(0xFF00C851),
|
||||||
focusedLabelColor = Color(0xFF00C851),
|
focusedLabelColor = Color(0xFF00C851),
|
||||||
|
unfocusedBorderColor = Color(0xFF2A2A2A),
|
||||||
|
unfocusedLabelColor = Color.Gray,
|
||||||
unfocusedTextColor = Color.White,
|
unfocusedTextColor = Color.White,
|
||||||
focusedTextColor = Color.White
|
focusedTextColor = Color.White
|
||||||
),
|
),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 16.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
// Description input
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = description,
|
value = description,
|
||||||
onValueChange = { description = it },
|
onValueChange = { description = it },
|
||||||
@@ -502,14 +582,18 @@ private fun LightningReceiveContent(
|
|||||||
colors = OutlinedTextFieldDefaults.colors(
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
focusedBorderColor = Color(0xFF00C851),
|
focusedBorderColor = Color(0xFF00C851),
|
||||||
focusedLabelColor = Color(0xFF00C851),
|
focusedLabelColor = Color(0xFF00C851),
|
||||||
unfocusedTextColor = Color.White,
|
unfocusedBorderColor = Color(0xFF2A2A2A),
|
||||||
|
unfocusedLabelColor = Color.Gray,
|
||||||
|
unfocusedTextColor = Color.White,
|
||||||
focusedTextColor = Color.White
|
focusedTextColor = Color.White
|
||||||
),
|
),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 32.dp),
|
||||||
|
shape = RoundedCornerShape(16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
// Create invoice button
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
amount.toLongOrNull()?.let { amountSats ->
|
amount.toLongOrNull()?.let { amountSats ->
|
||||||
@@ -517,30 +601,40 @@ private fun LightningReceiveContent(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = !isLoading && amount.toLongOrNull()?.let { it > 0 } == true,
|
enabled = !isLoading && amount.toLongOrNull()?.let { it > 0 } == true,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color(0xFF00C851)
|
containerColor = Color(0xFF00C851),
|
||||||
|
disabledContainerColor = Color(0xFF2A2A2A)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(8.dp)
|
shape = RoundedCornerShape(16.dp)
|
||||||
) {
|
) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
modifier = Modifier.size(16.dp)
|
modifier = Modifier.size(24.dp)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Icon(
|
Row(
|
||||||
imageVector = Icons.Filled.FlashOn,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
contentDescription = "Create Invoice",
|
) {
|
||||||
tint = Color.Black
|
Icon(
|
||||||
)
|
imageVector = Icons.Filled.FlashOn,
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
contentDescription = "Create Invoice",
|
||||||
Text(
|
tint = Color.Black,
|
||||||
text = "Create Invoice",
|
modifier = Modifier.size(24.dp)
|
||||||
color = Color.Black,
|
)
|
||||||
fontWeight = FontWeight.Bold,
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
fontFamily = FontFamily.Monospace
|
Text(
|
||||||
)
|
text = "CREATE INVOICE",
|
||||||
|
color = Color.Black,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
letterSpacing = 1.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,29 +25,49 @@ fun WalletScreen(
|
|||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
var selectedTab by remember { mutableStateOf(0) }
|
var selectedTab by remember { mutableStateOf(0) }
|
||||||
|
var showReceiveView by remember { mutableStateOf(false) }
|
||||||
val showSendDialog by walletViewModel.showSendDialog.observeAsState(false)
|
val showSendDialog by walletViewModel.showSendDialog.observeAsState(false)
|
||||||
val showReceiveDialog by walletViewModel.showReceiveDialog.observeAsState(false)
|
val showReceiveDialog by walletViewModel.showReceiveDialog.observeAsState(false)
|
||||||
|
|
||||||
Column(modifier = modifier.fillMaxSize()) {
|
if (showReceiveView) {
|
||||||
// Content
|
// Full-screen ReceiveView
|
||||||
when (selectedTab) {
|
ReceiveView(
|
||||||
0 -> WalletOverview(viewModel = walletViewModel, modifier = Modifier.weight(1f))
|
viewModel = walletViewModel,
|
||||||
1 -> TransactionHistory(
|
onNavigateBack = {
|
||||||
transactions = walletViewModel.getAllTransactions().observeAsState(initial = emptyList()).value,
|
showReceiveView = false
|
||||||
modifier = Modifier.weight(1f)
|
walletViewModel.hideReceiveDialog()
|
||||||
)
|
}
|
||||||
2 -> MintsScreen(viewModel = walletViewModel, modifier = Modifier.weight(1f))
|
)
|
||||||
3 -> WalletSettings(
|
} else {
|
||||||
viewModel = walletViewModel,
|
Column(modifier = modifier.fillMaxSize()) {
|
||||||
onBackClick = { /* No back action needed in tab navigation */ }
|
// Content
|
||||||
|
when (selectedTab) {
|
||||||
|
0 -> WalletOverview(viewModel = walletViewModel, modifier = Modifier.weight(1f))
|
||||||
|
1 -> TransactionHistory(
|
||||||
|
transactions = walletViewModel.getAllTransactions().observeAsState(initial = emptyList()).value,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
onTransactionClick = { transaction ->
|
||||||
|
// For lightning receive transactions, open the receive view with the quote
|
||||||
|
if (transaction.type == com.bitchat.android.wallet.data.TransactionType.LIGHTNING_RECEIVE &&
|
||||||
|
transaction.quote != null) {
|
||||||
|
walletViewModel.setCurrentMintQuote(transaction.quote!!)
|
||||||
|
showReceiveView = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
2 -> MintsScreen(viewModel = walletViewModel, modifier = Modifier.weight(1f))
|
||||||
|
3 -> WalletSettings(
|
||||||
|
viewModel = walletViewModel,
|
||||||
|
onBackClick = { /* No back action needed in tab navigation */ }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom Navigation
|
||||||
|
WalletBottomNavigation(
|
||||||
|
selectedTab = selectedTab,
|
||||||
|
onTabSelected = { selectedTab = it }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom Navigation
|
|
||||||
WalletBottomNavigation(
|
|
||||||
selectedTab = selectedTab,
|
|
||||||
onTabSelected = { selectedTab = it }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
@@ -59,10 +79,11 @@ fun WalletScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (showReceiveDialog) {
|
if (showReceiveDialog) {
|
||||||
ReceiveDialog(
|
LaunchedEffect(showReceiveDialog) {
|
||||||
viewModel = walletViewModel,
|
if (showReceiveDialog) {
|
||||||
onDismiss = { walletViewModel.hideReceiveDialog() }
|
showReceiveView = true
|
||||||
)
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -274,6 +274,11 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
|||||||
val updatedQuote = quote.copy(paid = true, state = MintQuoteState.PAID)
|
val updatedQuote = quote.copy(paid = true, state = MintQuoteState.PAID)
|
||||||
repository.saveMintQuote(updatedQuote)
|
repository.saveMintQuote(updatedQuote)
|
||||||
|
|
||||||
|
// Update currentMintQuote if it's the same quote
|
||||||
|
if (_currentMintQuote.value?.id == quote.id) {
|
||||||
|
_currentMintQuote.value = updatedQuote
|
||||||
|
}
|
||||||
|
|
||||||
val transaction = WalletTransaction(
|
val transaction = WalletTransaction(
|
||||||
id = UUID.randomUUID().toString(),
|
id = UUID.randomUUID().toString(),
|
||||||
type = TransactionType.LIGHTNING_RECEIVE,
|
type = TransactionType.LIGHTNING_RECEIVE,
|
||||||
@@ -372,6 +377,22 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
|||||||
_errorMessage.value = null
|
_errorMessage.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a specific mint quote as current (for reopening from transaction list)
|
||||||
|
*/
|
||||||
|
fun setCurrentMintQuote(quoteId: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
repository.getMintQuotes().onSuccess { quotes ->
|
||||||
|
val quote = quotes.find { it.id == quoteId }
|
||||||
|
if (quote != null) {
|
||||||
|
_currentMintQuote.value = quote
|
||||||
|
_receiveType.value = ReceiveType.LIGHTNING
|
||||||
|
showReceiveDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wallet Operations
|
// Wallet Operations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user