Moves the default zap type to a state flow and avoids passing on to the screen when using the default value.

This commit is contained in:
Vitor Pamplona
2024-08-16 17:45:53 -04:00
parent ec83ad9d20
commit 29c5b45764
12 changed files with 80 additions and 75 deletions
@@ -296,7 +296,7 @@ object LocalPreferences {
PrefKeys.REACTION_CHOICES, PrefKeys.REACTION_CHOICES,
Event.mapper.writeValueAsString(account.reactionChoices), Event.mapper.writeValueAsString(account.reactionChoices),
) )
putString(PrefKeys.DEFAULT_ZAPTYPE, account.defaultZapType.name) putString(PrefKeys.DEFAULT_ZAPTYPE, account.defaultZapType.value.name)
putString( putString(
PrefKeys.DEFAULT_FILE_SERVER, PrefKeys.DEFAULT_FILE_SERVER,
Event.mapper.writeValueAsString(account.defaultFileServer), Event.mapper.writeValueAsString(account.defaultFileServer),
@@ -658,7 +658,7 @@ object LocalPreferences {
translateTo = translateTo, translateTo = translateTo,
zapAmountChoices = zapAmountChoices, zapAmountChoices = zapAmountChoices,
reactionChoices = reactionChoices, reactionChoices = reactionChoices,
defaultZapType = defaultZapType, defaultZapType = MutableStateFlow(defaultZapType),
defaultFileServer = defaultFileServer, defaultFileServer = defaultFileServer,
defaultHomeFollowList = MutableStateFlow(defaultHomeFollowList), defaultHomeFollowList = MutableStateFlow(defaultHomeFollowList),
defaultStoriesFollowList = MutableStateFlow(defaultStoriesFollowList), defaultStoriesFollowList = MutableStateFlow(defaultStoriesFollowList),
@@ -184,7 +184,7 @@ class Account(
var translateTo: String = Locale.getDefault().language, var translateTo: String = Locale.getDefault().language,
var zapAmountChoices: List<Long> = DefaultZapAmounts, var zapAmountChoices: List<Long> = DefaultZapAmounts,
var reactionChoices: List<String> = DefaultReactions, var reactionChoices: List<String> = DefaultReactions,
var defaultZapType: LnZapEvent.ZapType = LnZapEvent.ZapType.PUBLIC, var defaultZapType: MutableStateFlow<LnZapEvent.ZapType> = MutableStateFlow(LnZapEvent.ZapType.PUBLIC),
var defaultFileServer: Nip96MediaServers.ServerName = Nip96MediaServers.DEFAULT[0], var defaultFileServer: Nip96MediaServers.ServerName = Nip96MediaServers.DEFAULT[0],
var defaultHomeFollowList: MutableStateFlow<String> = MutableStateFlow(KIND3_FOLLOWS), var defaultHomeFollowList: MutableStateFlow<String> = MutableStateFlow(KIND3_FOLLOWS),
var defaultStoriesFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS), var defaultStoriesFollowList: MutableStateFlow<String> = MutableStateFlow(GLOBAL_FOLLOWS),
@@ -2665,7 +2665,7 @@ class Account(
} }
fun changeDefaultZapType(zapType: LnZapEvent.ZapType) { fun changeDefaultZapType(zapType: LnZapEvent.ZapType) {
defaultZapType = zapType defaultZapType.tryEmit(zapType)
live.invalidateData() live.invalidateData()
saveable.invalidateData() saveable.invalidateData()
} }
@@ -355,7 +355,7 @@ fun EditPostView(
InvoiceRequest( InvoiceRequest(
lud16, lud16,
user.pubkeyHex, user.pubkeyHex,
accountViewModel.account, accountViewModel,
stringRes(id = R.string.lightning_invoice), stringRes(id = R.string.lightning_invoice),
stringRes(id = R.string.lightning_create_and_add_invoice), stringRes(id = R.string.lightning_create_and_add_invoice),
onSuccess = { onSuccess = {
@@ -515,7 +515,7 @@ fun NewPostView(
InvoiceRequest( InvoiceRequest(
lud16, lud16,
accountViewModel.account.userProfile().pubkeyHex, accountViewModel.account.userProfile().pubkeyHex,
accountViewModel.account, accountViewModel,
stringRes(id = R.string.lightning_invoice), stringRes(id = R.string.lightning_invoice),
stringRes(id = R.string.lightning_create_and_add_invoice), stringRes(id = R.string.lightning_create_and_add_invoice),
onSuccess = { onSuccess = {
@@ -37,7 +37,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -52,24 +51,19 @@ import androidx.compose.ui.unit.sp
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons import com.vitorpamplona.amethyst.commons.hashtags.CustomHashTagIcons
import com.vitorpamplona.amethyst.commons.hashtags.Lightning import com.vitorpamplona.amethyst.commons.hashtags.Lightning
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.amethyst.ui.theme.subtleBorder import com.vitorpamplona.amethyst.ui.theme.subtleBorder
import com.vitorpamplona.quartz.events.LnZapEvent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Composable @Composable
fun InvoiceRequestCard( fun InvoiceRequestCard(
lud16: String, lud16: String,
toUserPubKeyHex: String, toUserPubKeyHex: String,
account: Account, accountViewModel: AccountViewModel,
titleText: String? = null, titleText: String? = null,
buttonText: String? = null, buttonText: String? = null,
onSuccess: (String) -> Unit, onSuccess: (String) -> Unit,
@@ -90,7 +84,7 @@ fun InvoiceRequestCard(
InvoiceRequest( InvoiceRequest(
lud16, lud16,
toUserPubKeyHex, toUserPubKeyHex,
account, accountViewModel,
titleText, titleText,
buttonText, buttonText,
onSuccess, onSuccess,
@@ -105,7 +99,7 @@ fun InvoiceRequestCard(
fun InvoiceRequest( fun InvoiceRequest(
lud16: String, lud16: String,
toUserPubKeyHex: String, toUserPubKeyHex: String,
account: Account, accountViewModel: AccountViewModel,
titleText: String? = null, titleText: String? = null,
buttonText: String? = null, buttonText: String? = null,
onSuccess: (String) -> Unit, onSuccess: (String) -> Unit,
@@ -113,7 +107,6 @@ fun InvoiceRequest(
onError: (String, String) -> Unit, onError: (String, String) -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope()
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@@ -186,36 +179,16 @@ fun InvoiceRequest(
Button( Button(
modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp), modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp),
onClick = { onClick = {
scope.launch(Dispatchers.IO) { accountViewModel.sendSats(
if (account.defaultZapType == LnZapEvent.ZapType.NONZAP) { lnaddress = lud16,
LightningAddressResolver() milliSats = amount * 1000,
.lnAddressInvoice( message = message,
lud16, toUserPubKeyHex = toUserPubKeyHex,
amount * 1000,
message,
null,
onSuccess = onSuccess, onSuccess = onSuccess,
onError = onError, onError = onError,
onProgress = {}, onProgress = {},
context = context, context = context,
) )
} else {
account.createZapRequestFor(toUserPubKeyHex, message, account.defaultZapType) { zapRequest ->
LocalCache.justConsume(zapRequest, null)
LightningAddressResolver()
.lnAddressInvoice(
lud16,
amount * 1000,
message,
zapRequest.toJson(),
onSuccess = onSuccess,
onError = onError,
onProgress = {},
context = context,
)
}
}
}
}, },
shape = QuoteBorder, shape = QuoteBorder,
colors = colors =
@@ -85,7 +85,6 @@ import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.EmptyTagList import com.vitorpamplona.quartz.events.EmptyTagList
import com.vitorpamplona.quartz.events.ImmutableListOfLists import com.vitorpamplona.quartz.events.ImmutableListOfLists
import com.vitorpamplona.quartz.events.LnZapEvent
import com.vitorpamplona.quartz.events.toImmutableListOfLists import com.vitorpamplona.quartz.events.toImmutableListOfLists
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@@ -398,7 +397,6 @@ fun ZapVote(
}, },
onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } }, onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } },
onPayViaIntent = {}, onPayViaIntent = {},
zapType = accountViewModel.account.defaultZapType,
) )
} else { } else {
wantsToZap = true wantsToZap = true
@@ -522,10 +520,6 @@ fun FilteredZapAmountChoicePopup(
val context = LocalContext.current val context = LocalContext.current
val accountState by accountViewModel.accountLiveData.observeAsState() val accountState by accountViewModel.accountLiveData.observeAsState()
val defaultZapType by
remember(accountState) {
derivedStateOf { accountState?.account?.defaultZapType ?: LnZapEvent.ZapType.PRIVATE }
}
val zapMessage = "" val zapMessage = ""
@@ -554,7 +548,6 @@ fun FilteredZapAmountChoicePopup(
onError, onError,
onProgress, onProgress,
onPayViaIntent, onPayViaIntent,
defaultZapType,
) )
onDismiss() onDismiss()
}, },
@@ -581,7 +574,6 @@ fun FilteredZapAmountChoicePopup(
onError, onError,
onProgress, onProgress,
onPayViaIntent, onPayViaIntent,
defaultZapType,
) )
onDismiss() onDismiss()
}, },
@@ -1180,7 +1180,6 @@ fun zapClick(
context, context,
onError = onError, onError = onError,
onProgress = { onZappingProgress(it) }, onProgress = { onZappingProgress(it) },
zapType = accountViewModel.account.defaultZapType,
onPayViaIntent = onPayViaIntent, onPayViaIntent = onPayViaIntent,
) )
} else if (accountViewModel.account.zapAmountChoices.size > 1) { } else if (accountViewModel.account.zapAmountChoices.size > 1) {
@@ -1501,7 +1500,6 @@ fun ZapAmountChoicePopup(
onError, onError,
onProgress, onProgress,
onPayViaIntent, onPayViaIntent,
accountViewModel.account.defaultZapType,
) )
onDismiss() onDismiss()
}, },
@@ -1528,7 +1526,6 @@ fun ZapAmountChoicePopup(
onError, onError,
onProgress, onProgress,
onPayViaIntent, onPayViaIntent,
accountViewModel.account.defaultZapType,
) )
onDismiss() onDismiss()
}, },
@@ -134,7 +134,7 @@ class UpdateZapAmountViewModel(
account.zapPaymentRequest?.relayUri?.let { TextFieldValue(it) } ?: TextFieldValue("") account.zapPaymentRequest?.relayUri?.let { TextFieldValue(it) } ?: TextFieldValue("")
this.walletConnectSecret = this.walletConnectSecret =
account.zapPaymentRequest?.secret?.let { TextFieldValue(it) } ?: TextFieldValue("") account.zapPaymentRequest?.secret?.let { TextFieldValue(it) } ?: TextFieldValue("")
this.selectedZapType = account.defaultZapType this.selectedZapType = account.defaultZapType.value
} }
fun toListOfAmounts(commaSeparatedAmounts: String): List<Long> = commaSeparatedAmounts.split(",").map { it.trim().toLongOrNull() ?: 0 } fun toListOfAmounts(commaSeparatedAmounts: String): List<Long> = commaSeparatedAmounts.split(",").map { it.trim().toLongOrNull() ?: 0 }
@@ -196,7 +196,7 @@ class UpdateZapAmountViewModel(
fun hasChanged(): Boolean = fun hasChanged(): Boolean =
( (
selectedZapType != account?.defaultZapType || selectedZapType != account?.defaultZapType?.value ||
amountSet != account?.zapAmountChoices || amountSet != account?.zapAmountChoices ||
walletConnectPubkey.text != (account?.zapPaymentRequest?.pubKeyHex ?: "") || walletConnectPubkey.text != (account?.zapPaymentRequest?.pubKeyHex ?: "") ||
walletConnectRelay.text != (account?.zapPaymentRequest?.relayUri ?: "") || walletConnectRelay.text != (account?.zapPaymentRequest?.relayUri ?: "") ||
@@ -151,8 +151,9 @@ fun ZapCustomDialog(
remember { remember {
zapTypes.map { TitleExplainer(it.second, it.third) }.toImmutableList() zapTypes.map { TitleExplainer(it.second, it.third) }.toImmutableList()
} }
var selectedZapType by var selectedZapType by
remember(accountViewModel) { mutableStateOf(accountViewModel.account.defaultZapType) } remember(accountViewModel) { mutableStateOf(accountViewModel.account.defaultZapType.value) }
Dialog( Dialog(
onDismissRequest = { onClose() }, onDismissRequest = { onClose() },
@@ -223,7 +224,7 @@ fun ZapCustomDialog(
label = stringRes(id = R.string.zap_type), label = stringRes(id = R.string.zap_type),
placeholder = placeholder =
zapTypes zapTypes
.filter { it.first == accountViewModel.account.defaultZapType } .filter { it.first == accountViewModel.account.defaultZapType.value }
.first() .first()
.second, .second,
options = zapOptions, options = zapOptions,
@@ -501,7 +501,6 @@ fun customZapClick(
showErrorIfNoLnAddress = false, showErrorIfNoLnAddress = false,
onError = onError, onError = onError,
onProgress = { onZappingProgress(it) }, onProgress = { onZappingProgress(it) },
zapType = accountViewModel.account.defaultZapType,
onPayViaIntent = onPayViaIntent, onPayViaIntent = onPayViaIntent,
) )
} else { } else {
@@ -56,6 +56,7 @@ import com.vitorpamplona.amethyst.service.Nip11Retriever
import com.vitorpamplona.amethyst.service.OnlineChecker import com.vitorpamplona.amethyst.service.OnlineChecker
import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.ZapPaymentHandler
import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.lnurl.LightningAddressResolver
import com.vitorpamplona.amethyst.ui.actions.Dao import com.vitorpamplona.amethyst.ui.actions.Dao
import com.vitorpamplona.amethyst.ui.components.UrlPreviewState import com.vitorpamplona.amethyst.ui.components.UrlPreviewState
import com.vitorpamplona.amethyst.ui.navigation.Route import com.vitorpamplona.amethyst.ui.navigation.Route
@@ -616,23 +617,23 @@ class AccountViewModel(
onError: (String, String) -> Unit, onError: (String, String) -> Unit,
onProgress: (percent: Float) -> Unit, onProgress: (percent: Float) -> Unit,
onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit, onPayViaIntent: (ImmutableList<ZapPaymentHandler.Payable>) -> Unit,
zapType: LnZapEvent.ZapType, zapType: LnZapEvent.ZapType? = null,
) { ) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
ZapPaymentHandler(account) ZapPaymentHandler(account)
.zap( .zap(
note, note = note,
amount, amountMilliSats = amount,
pollOption, pollOption = pollOption,
message, message = message,
context, context = context,
showErrorIfNoLnAddress, showErrorIfNoLnAddress = showErrorIfNoLnAddress,
onError, onError = onError,
onProgress = { onProgress = {
onProgress(it) onProgress(it)
}, },
onPayViaIntent, onPayViaIntent = onPayViaIntent,
zapType, zapType = zapType ?: account.defaultZapType.value,
) )
} }
} }
@@ -857,7 +858,7 @@ class AccountViewModel(
} }
} }
fun defaultZapType(): LnZapEvent.ZapType = account.defaultZapType fun defaultZapType(): LnZapEvent.ZapType = account.defaultZapType.value
fun unwrap( fun unwrap(
event: GiftWrapEvent, event: GiftWrapEvent,
@@ -1470,6 +1471,48 @@ class AccountViewModel(
AdvertisedRelayListEvent.createAddressTag(user.pubkeyHex), AdvertisedRelayListEvent.createAddressTag(user.pubkeyHex),
) )
fun sendSats(
lnaddress: String,
milliSats: Long,
message: String,
toUserPubKeyHex: HexKey,
onSuccess: (String) -> Unit,
onError: (String, String) -> Unit,
onProgress: (percent: Float) -> Unit,
context: Context,
) {
viewModelScope.launch(Dispatchers.IO) {
if (account.defaultZapType.value == LnZapEvent.ZapType.NONZAP) {
LightningAddressResolver()
.lnAddressInvoice(
lnaddress,
milliSats * 1000,
message,
null,
onSuccess = onSuccess,
onError = onError,
onProgress = onProgress,
context = context,
)
} else {
account.createZapRequestFor(toUserPubKeyHex, message, account.defaultZapType.value) { zapRequest ->
LocalCache.justConsume(zapRequest, null)
LightningAddressResolver()
.lnAddressInvoice(
lnaddress,
milliSats * 1000,
message,
zapRequest.toJson(),
onSuccess = onSuccess,
onError = onError,
onProgress = onProgress,
context = context,
)
}
}
}
}
val draftNoteCache = CachedDraftNotes(this) val draftNoteCache = CachedDraftNotes(this)
class CachedDraftNotes( class CachedDraftNotes(
@@ -1190,7 +1190,7 @@ fun DisplayLNAddress(
InvoiceRequestCard( InvoiceRequestCard(
lud16, lud16,
userHex, userHex,
accountViewModel.account, accountViewModel,
onSuccess = { onSuccess = {
zapExpanded = false zapExpanded = false
// pay directly // pay directly