Merge pull request #2183 from greenart7c3/claude/move-payment-targets-wallet-KQlnM
Integrate Lightning Address and Payment Targets into NIP47 Setup
This commit is contained in:
@@ -227,22 +227,6 @@ fun NewUserMetadataScreen(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
label = { Text(text = stringRes(R.string.lightning_address)) },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
value = postViewModel.lnAddress.value,
|
|
||||||
onValueChange = { postViewModel.lnAddress.value = it },
|
|
||||||
placeholder = {
|
|
||||||
Text(
|
|
||||||
text = "me@mylightningnode.com",
|
|
||||||
color = MaterialTheme.colorScheme.placeholderText,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
singleLine = true,
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(10.dp))
|
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
label = { Text(text = stringRes(R.string.nip_05) + " (NIP-05)") },
|
label = { Text(text = stringRes(R.string.nip_05) + " (NIP-05)") },
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
|||||||
-8
@@ -57,8 +57,6 @@ class NewUserMetadataViewModel : ViewModel() {
|
|||||||
val website = mutableStateOf("")
|
val website = mutableStateOf("")
|
||||||
val pronouns = mutableStateOf("")
|
val pronouns = mutableStateOf("")
|
||||||
val nip05 = mutableStateOf("")
|
val nip05 = mutableStateOf("")
|
||||||
val lnAddress = mutableStateOf("")
|
|
||||||
val lnURL = mutableStateOf("")
|
|
||||||
|
|
||||||
val twitter = mutableStateOf("")
|
val twitter = mutableStateOf("")
|
||||||
val github = mutableStateOf("")
|
val github = mutableStateOf("")
|
||||||
@@ -82,8 +80,6 @@ class NewUserMetadataViewModel : ViewModel() {
|
|||||||
website.value = it.info.website ?: ""
|
website.value = it.info.website ?: ""
|
||||||
pronouns.value = it.info.pronouns ?: ""
|
pronouns.value = it.info.pronouns ?: ""
|
||||||
nip05.value = it.info.nip05 ?: ""
|
nip05.value = it.info.nip05 ?: ""
|
||||||
lnAddress.value = it.info.lud16 ?: ""
|
|
||||||
lnURL.value = it.info.lud06 ?: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
twitter.value = ""
|
twitter.value = ""
|
||||||
@@ -121,8 +117,6 @@ class NewUserMetadataViewModel : ViewModel() {
|
|||||||
pronouns = pronouns.value,
|
pronouns = pronouns.value,
|
||||||
about = about.value,
|
about = about.value,
|
||||||
nip05 = nip05.value,
|
nip05 = nip05.value,
|
||||||
lnAddress = lnAddress.value,
|
|
||||||
lnURL = lnURL.value,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val identities =
|
val identities =
|
||||||
@@ -146,8 +140,6 @@ class NewUserMetadataViewModel : ViewModel() {
|
|||||||
banner.value = ""
|
banner.value = ""
|
||||||
website.value = ""
|
website.value = ""
|
||||||
nip05.value = ""
|
nip05.value = ""
|
||||||
lnAddress.value = ""
|
|
||||||
lnURL.value = ""
|
|
||||||
twitter.value = ""
|
twitter.value = ""
|
||||||
github.value = ""
|
github.value = ""
|
||||||
mastodon.value = ""
|
mastodon.value = ""
|
||||||
|
|||||||
+8
-2
@@ -79,9 +79,15 @@ class PaymentTargetsViewModel : ViewModel() {
|
|||||||
fun savePaymentTargets() {
|
fun savePaymentTargets() {
|
||||||
if (isModified) {
|
if (isModified) {
|
||||||
accountViewModel.launchSigner {
|
accountViewModel.launchSigner {
|
||||||
account.savePaymentTargets(_paymentTargets.value)
|
savePaymentTargetsSuspend()
|
||||||
refresh()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun savePaymentTargetsSuspend() {
|
||||||
|
if (isModified) {
|
||||||
|
account.savePaymentTargets(_paymentTargets.value)
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import androidx.compose.animation.togetherWith
|
|||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
@@ -148,6 +149,7 @@ fun UpdateZapAmountContent(
|
|||||||
onClose: () -> Unit,
|
onClose: () -> Unit,
|
||||||
nip47uri: String? = null,
|
nip47uri: String? = null,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
|
trailingContent: @Composable ColumnScope.() -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val clipboardManager = LocalClipboard.current
|
val clipboardManager = LocalClipboard.current
|
||||||
@@ -649,6 +651,8 @@ fun UpdateZapAmountContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trailingContent()
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -84,6 +84,12 @@ class UpdateZapAmountViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun sendPost() {
|
fun sendPost() {
|
||||||
|
accountViewModel.launchSigner {
|
||||||
|
sendPostSuspend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun sendPostSuspend() {
|
||||||
val nip47Update =
|
val nip47Update =
|
||||||
if (walletConnectRelay.text.isNotBlank() && walletConnectPubkey.text.isNotBlank()) {
|
if (walletConnectRelay.text.isNotBlank() && walletConnectPubkey.text.isNotBlank()) {
|
||||||
val pubkeyHex =
|
val pubkeyHex =
|
||||||
@@ -110,7 +116,7 @@ class UpdateZapAmountViewModel : ViewModel() {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
accountViewModel.updateZapAmounts(amountSet, selectedZapType, nip47Update)
|
accountViewModel.account.updateZapAmounts(amountSet, selectedZapType, nip47Update)
|
||||||
|
|
||||||
nextAmount = TextFieldValue("")
|
nextAmount = TextFieldValue("")
|
||||||
}
|
}
|
||||||
|
|||||||
-8
@@ -29,7 +29,6 @@ import androidx.compose.foundation.layout.size
|
|||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.AccountBalanceWallet
|
|
||||||
import androidx.compose.material.icons.outlined.Bolt
|
import androidx.compose.material.icons.outlined.Bolt
|
||||||
import androidx.compose.material.icons.outlined.CloudUpload
|
import androidx.compose.material.icons.outlined.CloudUpload
|
||||||
import androidx.compose.material.icons.outlined.DeleteForever
|
import androidx.compose.material.icons.outlined.DeleteForever
|
||||||
@@ -122,13 +121,6 @@ fun AllSettingsScreen(
|
|||||||
onClick = { nav.nav(Route.EditMediaServers) },
|
onClick = { nav.nav(Route.EditMediaServers) },
|
||||||
)
|
)
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
SettingsNavigationRow(
|
|
||||||
title = R.string.payment_targets,
|
|
||||||
icon = Icons.Outlined.AccountBalanceWallet,
|
|
||||||
tint = tint,
|
|
||||||
onClick = { nav.nav(Route.EditPaymentTargets) },
|
|
||||||
)
|
|
||||||
HorizontalDivider()
|
|
||||||
SettingsNavigationRow(
|
SettingsNavigationRow(
|
||||||
title = R.string.reactions,
|
title = R.string.reactions,
|
||||||
icon = Icons.Outlined.FavoriteBorder,
|
icon = Icons.Outlined.FavoriteBorder,
|
||||||
|
|||||||
+146
-6
@@ -20,20 +20,45 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.Delete
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.paymentTargets.PaymentTargetAddField
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.paymentTargets.PaymentTargetsViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.SavingTopBar
|
||||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountContent
|
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountContent
|
||||||
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountViewModel
|
import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.SettingsCategory
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet.WalletViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.SettingsCategorySpacingModifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.grayText
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
|
import com.vitorpamplona.quartz.experimental.nipA3.PaymentTarget
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NIP47SetupScreen(
|
fun NIP47SetupScreen(
|
||||||
@@ -44,17 +69,27 @@ fun NIP47SetupScreen(
|
|||||||
val postViewModel: UpdateZapAmountViewModel = viewModel()
|
val postViewModel: UpdateZapAmountViewModel = viewModel()
|
||||||
postViewModel.init(accountViewModel)
|
postViewModel.init(accountViewModel)
|
||||||
|
|
||||||
|
val walletViewModel: WalletViewModel = viewModel()
|
||||||
|
walletViewModel.init(accountViewModel)
|
||||||
|
|
||||||
|
val paymentTargetsViewModel: PaymentTargetsViewModel = viewModel()
|
||||||
|
paymentTargetsViewModel.init(accountViewModel)
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel, postViewModel) {
|
LaunchedEffect(accountViewModel, postViewModel) {
|
||||||
postViewModel.load()
|
postViewModel.load()
|
||||||
|
walletViewModel.loadLnAddress()
|
||||||
|
paymentTargetsViewModel.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
NIP47SetupScreen(postViewModel, accountViewModel, nav, nip47)
|
NIP47SetupScreen(postViewModel, walletViewModel, paymentTargetsViewModel, accountViewModel, nav, nip47)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun NIP47SetupScreen(
|
fun NIP47SetupScreen(
|
||||||
postViewModel: UpdateZapAmountViewModel,
|
postViewModel: UpdateZapAmountViewModel,
|
||||||
|
walletViewModel: WalletViewModel,
|
||||||
|
paymentTargetsViewModel: PaymentTargetsViewModel,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
nip47: String?,
|
nip47: String?,
|
||||||
@@ -66,20 +101,125 @@ fun NIP47SetupScreen(
|
|||||||
isActive = postViewModel::hasChanged,
|
isActive = postViewModel::hasChanged,
|
||||||
onCancel = {
|
onCancel = {
|
||||||
postViewModel.cancel()
|
postViewModel.cancel()
|
||||||
|
paymentTargetsViewModel.refresh()
|
||||||
nav.popBack()
|
nav.popBack()
|
||||||
},
|
},
|
||||||
onPost = {
|
onPost = {
|
||||||
postViewModel.sendPost()
|
accountViewModel.launchSigner {
|
||||||
|
postViewModel.sendPostSuspend()
|
||||||
|
walletViewModel.saveLnAddressSuspend()
|
||||||
|
paymentTargetsViewModel.savePaymentTargetsSuspend()
|
||||||
|
}
|
||||||
nav.popBack()
|
nav.popBack()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Column(Modifier.padding(it)) {
|
Column(Modifier.padding(it)) {
|
||||||
UpdateZapAmountContent(postViewModel, onClose = {
|
UpdateZapAmountContent(
|
||||||
postViewModel.cancel()
|
postViewModel,
|
||||||
nav.popBack()
|
onClose = {
|
||||||
}, nip47, accountViewModel)
|
postViewModel.cancel()
|
||||||
|
paymentTargetsViewModel.refresh()
|
||||||
|
nav.popBack()
|
||||||
|
},
|
||||||
|
nip47,
|
||||||
|
accountViewModel,
|
||||||
|
) {
|
||||||
|
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||||
|
LightningAddressSetupSection(walletViewModel)
|
||||||
|
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
||||||
|
PaymentTargetsInlineSection(paymentTargetsViewModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun LightningAddressSetupSection(walletViewModel: WalletViewModel) {
|
||||||
|
val lnAddress by walletViewModel.lnAddress.collectAsState()
|
||||||
|
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(R.string.lightning_address),
|
||||||
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
modifier = SettingsCategorySpacingModifier,
|
||||||
|
)
|
||||||
|
OutlinedTextField(
|
||||||
|
value = lnAddress,
|
||||||
|
onValueChange = { walletViewModel.updateLnAddress(it) },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "me@mylightningnode.com",
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
singleLine = true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PaymentTargetsInlineSection(viewModel: PaymentTargetsViewModel) {
|
||||||
|
val targets by viewModel.paymentTargets.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
SettingsCategory(
|
||||||
|
R.string.payment_targets,
|
||||||
|
R.string.payment_targets_section_explainer,
|
||||||
|
SettingsCategorySpacingModifier,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (targets.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
text = stringRes(id = R.string.no_payment_targets_message),
|
||||||
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
|
color = MaterialTheme.colorScheme.grayText,
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Column {
|
||||||
|
targets.forEach { target ->
|
||||||
|
PaymentTargetInlineEntry(target = target, onDelete = { viewModel.removeTarget(target) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PaymentTargetAddField { type, authority ->
|
||||||
|
viewModel.addTarget(type, authority)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PaymentTargetInlineEntry(
|
||||||
|
target: PaymentTarget,
|
||||||
|
onDelete: () -> Unit,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 6.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
|
Text(
|
||||||
|
text = target.type.replaceFirstChar(Char::titlecase),
|
||||||
|
style = MaterialTheme.typography.bodyLarge,
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = target.authority,
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
color = MaterialTheme.colorScheme.grayText,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IconButton(onClick = onDelete) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Delete,
|
||||||
|
contentDescription = stringRes(id = R.string.delete_payment_target),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ fun WalletReceiveScreen(
|
|||||||
val walletViewModel: WalletViewModel = viewModel()
|
val walletViewModel: WalletViewModel = viewModel()
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel) {
|
LaunchedEffect(accountViewModel) {
|
||||||
walletViewModel.init(accountViewModel.account)
|
walletViewModel.init(accountViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
|
|||||||
+12
-1
@@ -36,6 +36,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||||||
import androidx.compose.material.icons.automirrored.filled.List
|
import androidx.compose.material.icons.automirrored.filled.List
|
||||||
import androidx.compose.material.icons.filled.ArrowDownward
|
import androidx.compose.material.icons.filled.ArrowDownward
|
||||||
import androidx.compose.material.icons.filled.ArrowUpward
|
import androidx.compose.material.icons.filled.ArrowUpward
|
||||||
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
@@ -73,7 +74,7 @@ fun WalletScreen(
|
|||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val walletViewModel: WalletViewModel = viewModel()
|
val walletViewModel: WalletViewModel = viewModel()
|
||||||
walletViewModel.init(accountViewModel.account)
|
walletViewModel.init(accountViewModel)
|
||||||
|
|
||||||
val hasWallet by walletViewModel.hasWalletSetup.collectAsState()
|
val hasWallet by walletViewModel.hasWalletSetup.collectAsState()
|
||||||
|
|
||||||
@@ -89,6 +90,16 @@ fun WalletScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
actions = {
|
||||||
|
if (hasWallet) {
|
||||||
|
IconButton(onClick = { nav.nav(Route.Nip47NWCSetup()) }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Settings,
|
||||||
|
contentDescription = stringRes(R.string.settings),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { padding ->
|
) { padding ->
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ fun WalletSendScreen(
|
|||||||
val walletViewModel: WalletViewModel = viewModel()
|
val walletViewModel: WalletViewModel = viewModel()
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel) {
|
LaunchedEffect(accountViewModel) {
|
||||||
walletViewModel.init(accountViewModel.account)
|
walletViewModel.init(accountViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposableEffect(Unit) {
|
DisposableEffect(Unit) {
|
||||||
|
|||||||
+1
-1
@@ -83,7 +83,7 @@ fun WalletTransactionsScreen(
|
|||||||
val walletViewModel: WalletViewModel = viewModel()
|
val walletViewModel: WalletViewModel = viewModel()
|
||||||
|
|
||||||
LaunchedEffect(accountViewModel) {
|
LaunchedEffect(accountViewModel) {
|
||||||
walletViewModel.init(accountViewModel.account)
|
walletViewModel.init(accountViewModel)
|
||||||
walletViewModel.fetchTransactions()
|
walletViewModel.fetchTransactions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-3
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetBalanceMethod
|
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetBalanceMethod
|
||||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetBalanceSuccessResponse
|
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetBalanceSuccessResponse
|
||||||
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetInfoMethod
|
import com.vitorpamplona.quartz.nip47WalletConnect.rpc.GetInfoMethod
|
||||||
@@ -86,10 +87,14 @@ private const val PAYMENT_FAILED = "Payment failed"
|
|||||||
|
|
||||||
class WalletViewModel : ViewModel() {
|
class WalletViewModel : ViewModel() {
|
||||||
private var account: Account? = null
|
private var account: Account? = null
|
||||||
|
private var accountViewModel: AccountViewModel? = null
|
||||||
|
|
||||||
private val _hasWalletSetup = MutableStateFlow(false)
|
private val _hasWalletSetup = MutableStateFlow(false)
|
||||||
val hasWalletSetup = _hasWalletSetup.asStateFlow()
|
val hasWalletSetup = _hasWalletSetup.asStateFlow()
|
||||||
|
|
||||||
|
private val _lnAddress = MutableStateFlow("")
|
||||||
|
val lnAddress = _lnAddress.asStateFlow()
|
||||||
|
|
||||||
private val _balanceSats = MutableStateFlow<Long?>(null)
|
private val _balanceSats = MutableStateFlow<Long?>(null)
|
||||||
val balanceSats = _balanceSats.asStateFlow()
|
val balanceSats = _balanceSats.asStateFlow()
|
||||||
|
|
||||||
@@ -137,15 +142,46 @@ class WalletViewModel : ViewModel() {
|
|||||||
onTimeout()
|
onTimeout()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun init(account: Account) {
|
fun init(accountViewModel: AccountViewModel) {
|
||||||
this.account = account
|
this.accountViewModel = accountViewModel
|
||||||
_hasWalletSetup.value = account.nip47SignerState.hasWalletConnectSetup()
|
this.account = accountViewModel.account
|
||||||
|
_hasWalletSetup.value = accountViewModel.account.nip47SignerState.hasWalletConnectSetup()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshWalletSetup() {
|
fun refreshWalletSetup() {
|
||||||
_hasWalletSetup.value = account?.nip47SignerState?.hasWalletConnectSetup() == true
|
_hasWalletSetup.value = account?.nip47SignerState?.hasWalletConnectSetup() == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadLnAddress() {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val info =
|
||||||
|
account
|
||||||
|
?.userProfile()
|
||||||
|
?.metadataOrNull()
|
||||||
|
?.flow
|
||||||
|
?.value
|
||||||
|
?.info
|
||||||
|
_lnAddress.value = info?.lud16 ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateLnAddress(address: String) {
|
||||||
|
_lnAddress.value = address
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveLnAddress() {
|
||||||
|
val accountVm = accountViewModel ?: return
|
||||||
|
accountVm.launchSigner {
|
||||||
|
saveLnAddressSuspend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun saveLnAddressSuspend() {
|
||||||
|
val acc = account ?: return
|
||||||
|
val event = acc.userMetadata.sendNewUserMetadata(lnAddress = _lnAddress.value)
|
||||||
|
acc.sendLiterallyEverywhere(event)
|
||||||
|
}
|
||||||
|
|
||||||
fun fetchBalance() {
|
fun fetchBalance() {
|
||||||
val acc = account ?: return
|
val acc = account ?: return
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
|||||||
Reference in New Issue
Block a user