Custom Zap Amounts.
This commit is contained in:
@@ -23,6 +23,7 @@ class LocalPreferences(context: Context) {
|
|||||||
remove("relays")
|
remove("relays")
|
||||||
remove("dontTranslateFrom")
|
remove("dontTranslateFrom")
|
||||||
remove("translateTo")
|
remove("translateTo")
|
||||||
|
remove("zapAmounts")
|
||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ class LocalPreferences(context: Context) {
|
|||||||
account.localRelays.let { putString("relays", gson.toJson(it)) }
|
account.localRelays.let { putString("relays", gson.toJson(it)) }
|
||||||
account.dontTranslateFrom.let { putStringSet("dontTranslateFrom", it) }
|
account.dontTranslateFrom.let { putStringSet("dontTranslateFrom", it) }
|
||||||
account.translateTo.let { putString("translateTo", it) }
|
account.translateTo.let { putString("translateTo", it) }
|
||||||
|
account.zapAmountChoices.let { putString("zapAmounts", gson.toJson(it)) }
|
||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +54,11 @@ class LocalPreferences(context: Context) {
|
|||||||
val dontTranslateFrom = getStringSet("dontTranslateFrom", null) ?: setOf()
|
val dontTranslateFrom = getStringSet("dontTranslateFrom", null) ?: setOf()
|
||||||
val translateTo = getString("translateTo", null) ?: Locale.getDefault().language
|
val translateTo = getString("translateTo", null) ?: Locale.getDefault().language
|
||||||
|
|
||||||
|
val zapAmountChoices = gson.fromJson(
|
||||||
|
getString("zapAmounts", "[]"),
|
||||||
|
object : TypeToken<List<Long>>() {}.type
|
||||||
|
) ?: listOf(500L, 1000L, 5000L)
|
||||||
|
|
||||||
if (pubKey != null) {
|
if (pubKey != null) {
|
||||||
return Account(
|
return Account(
|
||||||
Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()),
|
Persona(privKey = privKey?.toByteArray(), pubKey = pubKey.toByteArray()),
|
||||||
@@ -59,7 +66,8 @@ class LocalPreferences(context: Context) {
|
|||||||
hiddenUsers,
|
hiddenUsers,
|
||||||
localRelays,
|
localRelays,
|
||||||
dontTranslateFrom,
|
dontTranslateFrom,
|
||||||
translateTo
|
translateTo,
|
||||||
|
zapAmountChoices
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ class Account(
|
|||||||
var hiddenUsers: Set<String> = setOf(),
|
var hiddenUsers: Set<String> = setOf(),
|
||||||
var localRelays: Set<RelaySetupInfo> = Constants.defaultRelays.toSet(),
|
var localRelays: Set<RelaySetupInfo> = Constants.defaultRelays.toSet(),
|
||||||
var dontTranslateFrom: Set<String> = getLanguagesSpokenByUser(),
|
var dontTranslateFrom: Set<String> = getLanguagesSpokenByUser(),
|
||||||
var translateTo: String = Locale.getDefault().language
|
var translateTo: String = Locale.getDefault().language,
|
||||||
|
var zapAmountChoices: List<Long> = listOf(500L, 1000L, 5000L)
|
||||||
) {
|
) {
|
||||||
var transientHiddenUsers: Set<String> = setOf()
|
var transientHiddenUsers: Set<String> = setOf()
|
||||||
|
|
||||||
@@ -327,6 +328,11 @@ class Account(
|
|||||||
invalidateData(live)
|
invalidateData(live)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun changeZapAmounts(newAmounts: List<Long>) {
|
||||||
|
zapAmountChoices = newAmounts
|
||||||
|
invalidateData(live)
|
||||||
|
}
|
||||||
|
|
||||||
fun sendChangeChannel(name: String, about: String, picture: String, channel: Channel) {
|
fun sendChangeChannel(name: String, about: String, picture: String, channel: Channel) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
|
|||||||
@@ -245,6 +245,25 @@ fun PostButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SaveButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier = Modifier) {
|
||||||
|
Button(
|
||||||
|
modifier = modifier,
|
||||||
|
onClick = {
|
||||||
|
if (isActive) {
|
||||||
|
onPost()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(20.dp),
|
||||||
|
colors = ButtonDefaults
|
||||||
|
.buttonColors(
|
||||||
|
backgroundColor = if (isActive) MaterialTheme.colors.primary else Color.Gray
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(text = "Save", color = Color.White)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CreateButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier = Modifier) {
|
fun CreateButton(onPost: () -> Unit = {}, isActive: Boolean, modifier: Modifier = Modifier) {
|
||||||
Button(
|
Button(
|
||||||
|
|||||||
@@ -1,24 +1,39 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.note
|
package com.vitorpamplona.amethyst.ui.note
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.ButtonDefaults
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.OutlinedTextField
|
||||||
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.TextFieldDefaults
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Bolt
|
import androidx.compose.material.icons.filled.Bolt
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
|
||||||
import androidx.compose.material.icons.outlined.BarChart
|
import androidx.compose.material.icons.outlined.BarChart
|
||||||
import androidx.compose.material.icons.outlined.Bolt
|
import androidx.compose.material.icons.outlined.Bolt
|
||||||
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -26,28 +41,48 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
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.ExperimentalComposeUiApi
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ColorFilter
|
import androidx.compose.ui.graphics.ColorFilter
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.semantics.Role
|
||||||
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.IntOffset
|
||||||
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.core.content.ContextCompat
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
import androidx.compose.ui.window.Popup
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.request.CachePolicy
|
import coil.request.CachePolicy
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
|
import com.vitorpamplona.amethyst.LocalPreferences
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.lnurl.LightningAddressResolver
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.CloseButton
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
||||||
|
import com.vitorpamplona.amethyst.ui.actions.SaveButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.RoundingMode
|
import java.math.RoundingMode
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
@@ -77,6 +112,9 @@ fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
|||||||
if (wantsToReplyTo != null)
|
if (wantsToReplyTo != null)
|
||||||
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, account)
|
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, account)
|
||||||
|
|
||||||
|
var wantsToZap by remember { mutableStateOf(false) }
|
||||||
|
var wantsToChangeZapAmount by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 8.dp)
|
.padding(top = 8.dp)
|
||||||
@@ -192,26 +230,69 @@ fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
|||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
||||||
IconButton(
|
|
||||||
modifier = Modifier.then(Modifier.size(20.dp)),
|
Row(
|
||||||
onClick = {
|
modifier = Modifier
|
||||||
if (account.isWriteable()) {
|
.then(Modifier.size(20.dp))
|
||||||
accountViewModel.zap(baseNote, 1000 * 1000, "", context) {
|
.combinedClickable(
|
||||||
scope.launch {
|
role = Role.Button,
|
||||||
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = rememberRipple(bounded = false, radius = 24.dp),
|
||||||
|
onClick = {
|
||||||
|
if (account.zapAmountChoices.isEmpty()) {
|
||||||
|
scope.launch {
|
||||||
|
Toast
|
||||||
|
.makeText(
|
||||||
|
context,
|
||||||
|
"No Zap Amount Setup. Long Press to change",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else if (!account.isWriteable()) {
|
||||||
|
scope.launch {
|
||||||
|
Toast
|
||||||
|
.makeText(
|
||||||
|
context,
|
||||||
|
"Login with a Private key to be able to send Zaps",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else if (account.zapAmountChoices.size == 1) {
|
||||||
|
accountViewModel.zap(baseNote, account.zapAmountChoices.first() * 1000, "", context) {
|
||||||
|
scope.launch {
|
||||||
|
Toast
|
||||||
|
.makeText(context, it, Toast.LENGTH_SHORT)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (account.zapAmountChoices.size > 1) {
|
||||||
|
wantsToZap = true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
wantsToChangeZapAmount = true
|
||||||
}
|
}
|
||||||
} else {
|
)
|
||||||
scope.launch {
|
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
"Login with a Private key to be able to send Zaps",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
|
if (wantsToZap) {
|
||||||
|
ZapAmountChoicePopup(
|
||||||
|
baseNote,
|
||||||
|
accountViewModel,
|
||||||
|
onDismiss = {
|
||||||
|
wantsToZap = false
|
||||||
|
},
|
||||||
|
onChangeAmount = {
|
||||||
|
wantsToZap = false
|
||||||
|
wantsToChangeZapAmount = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (wantsToChangeZapAmount) {
|
||||||
|
UpdateZapAmountDialog({ wantsToChangeZapAmount = false }, account = account)
|
||||||
|
}
|
||||||
|
|
||||||
if (zappedNote?.isZappedBy(account.userProfile()) == true) {
|
if (zappedNote?.isZappedBy(account.userProfile()) == true) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Bolt,
|
imageVector = Icons.Default.Bolt,
|
||||||
@@ -236,7 +317,6 @@ fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
|||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.then(Modifier.size(20.dp)),
|
modifier = Modifier.then(Modifier.size(20.dp)),
|
||||||
onClick = { uri.openUri("https://counter.amethyst.social/${baseNote.idHex}/") }
|
onClick = { uri.openUri("https://counter.amethyst.social/${baseNote.idHex}/") }
|
||||||
@@ -265,6 +345,173 @@ fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun ZapAmountChoicePopup(baseNote: Note, accountViewModel: AccountViewModel, onDismiss: () -> Unit, onChangeAmount: () -> Unit) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
|
val account = accountState?.account ?: return
|
||||||
|
|
||||||
|
Popup(
|
||||||
|
alignment = Alignment.BottomCenter,
|
||||||
|
offset = IntOffset(0, -50),
|
||||||
|
onDismissRequest = { onDismiss() }
|
||||||
|
) {
|
||||||
|
|
||||||
|
FlowRow() {
|
||||||
|
|
||||||
|
account.zapAmountChoices.forEach { amountInSats ->
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.padding(horizontal = 3.dp),
|
||||||
|
onClick = {
|
||||||
|
accountViewModel.zap(baseNote, amountInSats * 1000, "", context) {
|
||||||
|
scope.launch {
|
||||||
|
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDismiss()
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(20.dp),
|
||||||
|
colors = ButtonDefaults
|
||||||
|
.buttonColors(
|
||||||
|
backgroundColor = MaterialTheme.colors.primary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("⚡ ${showAmount(amountInSats.toBigDecimal())}",
|
||||||
|
color = Color.White,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.combinedClickable(
|
||||||
|
onClick = {
|
||||||
|
accountViewModel.zap(baseNote, amountInSats * 1000, "", context) {
|
||||||
|
scope.launch {
|
||||||
|
Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDismiss()
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
onChangeAmount()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateZapAmountViewModel: ViewModel() {
|
||||||
|
private var account: Account? = null
|
||||||
|
|
||||||
|
var amounts by mutableStateOf(TextFieldValue(""))
|
||||||
|
|
||||||
|
fun load(account: Account) {
|
||||||
|
this.account = account
|
||||||
|
this.amounts = TextFieldValue(account.zapAmountChoices.joinToString(", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toListOfAmounts(commaSeparatedAmounts: String): List<Long> {
|
||||||
|
return commaSeparatedAmounts.split(",").map { it.trim().toLongOrNull() ?: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateAmounts(commaSeparatedAmounts: TextFieldValue) {
|
||||||
|
val correctedText = toListOfAmounts(commaSeparatedAmounts.text).joinToString(", ")
|
||||||
|
amounts = TextFieldValue(correctedText, commaSeparatedAmounts.selection, commaSeparatedAmounts.composition)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendPost() {
|
||||||
|
account?.changeZapAmounts(toListOfAmounts(amounts.text))
|
||||||
|
amounts = TextFieldValue("")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancel() {
|
||||||
|
amounts = TextFieldValue("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
|
@Composable
|
||||||
|
fun UpdateZapAmountDialog(onClose: () -> Unit, account: Account) {
|
||||||
|
val postViewModel: UpdateZapAmountViewModel = viewModel()
|
||||||
|
|
||||||
|
postViewModel.load(account)
|
||||||
|
|
||||||
|
val ctx = LocalContext.current.applicationContext
|
||||||
|
|
||||||
|
// initialize focus reference to be able to request focus programmatically
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
delay(100)
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog(
|
||||||
|
onDismissRequest = { onClose() },
|
||||||
|
properties = DialogProperties(
|
||||||
|
dismissOnClickOutside = false
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Surface() {
|
||||||
|
Column(modifier = Modifier.padding(10.dp)) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
CloseButton(onCancel = {
|
||||||
|
postViewModel.cancel()
|
||||||
|
onClose()
|
||||||
|
})
|
||||||
|
|
||||||
|
SaveButton(
|
||||||
|
onPost = {
|
||||||
|
postViewModel.sendPost()
|
||||||
|
LocalPreferences(ctx).saveToEncryptedStorage(account)
|
||||||
|
onClose()
|
||||||
|
},
|
||||||
|
isActive = postViewModel.amounts.text.isNotBlank()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
OutlinedTextField(
|
||||||
|
label = { Text(text = "Comma-separated Zap amounts in sats") },
|
||||||
|
value = postViewModel.amounts,
|
||||||
|
onValueChange = {
|
||||||
|
postViewModel.updateAmounts(it)
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
|
capitalization = KeyboardCapitalization.None,
|
||||||
|
keyboardType = KeyboardType.Number
|
||||||
|
),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = "100, 1000, 5000",
|
||||||
|
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
singleLine = true,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onFocusChanged {
|
||||||
|
if (it.isFocused) {
|
||||||
|
keyboardController?.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun showCount(count: Int?): String {
|
fun showCount(count: Int?): String {
|
||||||
if (count == null) return " "
|
if (count == null) return " "
|
||||||
if (count == 0) return " "
|
if (count == 0) return " "
|
||||||
|
|||||||
Reference in New Issue
Block a user