add option tally percentage bars,

create new PollNoteViewModel for each PollNote,
fix isVoteAmountAtomic to directly launch wallet
This commit is contained in:
toadlyBroodle
2023-03-25 15:46:54 +09:00
parent 5b1e7c3451
commit 12a1c3fe6d
2 changed files with 48 additions and 22 deletions

View File

@@ -26,7 +26,6 @@ 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.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
@@ -44,21 +43,19 @@ fun PollNote(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
navController: NavController navController: NavController
) { ) {
val pollViewModel: PollNoteViewModel = viewModel() val pollViewModel = PollNoteViewModel()
pollViewModel.load(note) pollViewModel.load(note)
pollViewModel.pollEvent?.pollOptions()?.forEach { poll_op -> pollViewModel.pollEvent?.pollOptions()?.forEach { poll_op ->
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically
modifier = Modifier.fillMaxWidth()
) { ) {
TranslateableRichTextViewer( TranslateableRichTextViewer(
poll_op.value, poll_op.value,
canPreview, canPreview,
modifier = Modifier modifier = Modifier
.width(250.dp) .width(250.dp)
.border(BorderStroke(1.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.32f))) .border(BorderStroke(1.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.32f))),
.padding(4.dp),
pollViewModel.pollEvent?.tags(), pollViewModel.pollEvent?.tags(),
backgroundColor, backgroundColor,
accountViewModel, accountViewModel,
@@ -67,6 +64,18 @@ fun PollNote(
ZapVote(note, accountViewModel, pollViewModel, poll_op.key) ZapVote(note, accountViewModel, pollViewModel, poll_op.key)
} }
Row(
verticalAlignment = Alignment.CenterVertically
) {
// only show tallies after user has zapped note
if (note.isZappedBy(accountViewModel.userProfile())) {
LinearProgressIndicator(
modifier = Modifier.width(250.dp),
progress = pollViewModel.optionVoteTally(poll_op.key)
)
}
}
} }
} }
@@ -119,7 +128,7 @@ fun ZapVote(
) )
.show() .show()
} }
} else if (pollViewModel.isVoteAmountAtomic) { } else if (pollViewModel.isVoteAmountAtomic()) {
accountViewModel.zap( accountViewModel.zap(
baseNote, baseNote,
pollViewModel.valueMaximum!!.toLong() * 1000, pollViewModel.valueMaximum!!.toLong() * 1000,
@@ -174,6 +183,7 @@ fun ZapVote(
} }
} }
// only show tallies after a user has zapped note
if (zappedNote?.isZappedBy(account.userProfile()) == true) { if (zappedNote?.isZappedBy(account.userProfile()) == true) {
Text( Text(
showAmount(zappedNote.zappedPollOptionAmount(pollOption)), showAmount(zappedNote.zappedPollOptionAmount(pollOption)),
@@ -196,7 +206,7 @@ fun ZapVoteAmountChoicePopup(
) { ) {
val context = LocalContext.current val context = LocalContext.current
var textAmount by rememberSaveable { mutableStateOf("") } var inputAmountText by rememberSaveable { mutableStateOf("") }
val colorInValid = TextFieldDefaults.outlinedTextFieldColors( val colorInValid = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = MaterialTheme.colors.error, focusedBorderColor = MaterialTheme.colors.error,
@@ -221,14 +231,14 @@ fun ZapVoteAmountChoicePopup(
modifier = Modifier modifier = Modifier
.padding(10.dp) .padding(10.dp)
) { ) {
val amount = pollViewModel.amount(textAmount) val amount = pollViewModel.inputAmountLong(inputAmountText)
OutlinedTextField( OutlinedTextField(
value = textAmount, value = inputAmountText,
onValueChange = { textAmount = it }, onValueChange = { inputAmountText = it },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.width(150.dp), modifier = Modifier.width(150.dp),
colors = if (pollViewModel.isValidAmount(amount)) colorValid else colorInValid, colors = if (pollViewModel.isValidInputAmount(amount)) colorValid else colorInValid,
label = { label = {
Text( Text(
text = stringResource(R.string.poll_zap_amount), text = stringResource(R.string.poll_zap_amount),
@@ -245,7 +255,7 @@ fun ZapVoteAmountChoicePopup(
Button( Button(
modifier = Modifier.padding(horizontal = 3.dp), modifier = Modifier.padding(horizontal = 3.dp),
enabled = pollViewModel.isValidAmount(amount), enabled = pollViewModel.isValidInputAmount(amount),
onClick = { onClick = {
if (amount != null) { if (amount != null) {
accountViewModel.zap( accountViewModel.zap(

View File

@@ -1,24 +1,25 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.lifecycle.ViewModel
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.model.* import com.vitorpamplona.amethyst.service.model.*
import java.util.* import java.util.*
class PollNoteViewModel : ViewModel() { class PollNoteViewModel {
var account: Account? = null var account: Account? = null
var pollNote: Note? = null private var pollNote: Note? = null
var pollEvent: PollNoteEvent? = null var pollEvent: PollNoteEvent? = null
private var pollOptions: Map<Int, String>? = null
var valueMaximum: Int? = null var valueMaximum: Int? = null
var valueMinimum: Int? = null private var valueMinimum: Int? = null
var closedAt: Int? = null private var closedAt: Int? = null
var consensusThreshold: Int? = null private var consensusThreshold: Int? = null
fun load(note: Note?) { fun load(note: Note?) {
pollNote = note pollNote = note
pollEvent = pollNote?.event as PollNoteEvent pollEvent = pollNote?.event as PollNoteEvent
pollOptions = pollEvent?.pollOptions()
valueMaximum = pollEvent?.getTagInt(VALUE_MAXIMUM) valueMaximum = pollEvent?.getTagInt(VALUE_MAXIMUM)
valueMinimum = pollEvent?.getTagInt(VALUE_MINIMUM) valueMinimum = pollEvent?.getTagInt(VALUE_MINIMUM)
consensusThreshold = pollEvent?.getTagInt(CONSENSUS_THRESHOLD) consensusThreshold = pollEvent?.getTagInt(CONSENSUS_THRESHOLD)
@@ -29,7 +30,7 @@ class PollNoteViewModel : ViewModel() {
pollNote?.createdAt()?.plus(it * (86400 + 120))!! > Date().time / 1000 pollNote?.createdAt()?.plus(it * (86400 + 120))!! > Date().time / 1000
} == true } == true
val isVoteAmountAtomic = valueMaximum != null && valueMinimum != null && valueMinimum == valueMaximum fun isVoteAmountAtomic(): Boolean = valueMaximum != null && valueMinimum != null && valueMinimum == valueMaximum
fun voteAmountPlaceHolderText(sats: String): String = if (valueMinimum == null && valueMaximum == null) { fun voteAmountPlaceHolderText(sats: String): String = if (valueMinimum == null && valueMaximum == null) {
sats sats
@@ -41,13 +42,13 @@ class PollNoteViewModel : ViewModel() {
"$valueMinimum$valueMaximum $sats" "$valueMinimum$valueMaximum $sats"
} }
fun amount(textAmount: String) = if (textAmount.isEmpty()) { null } else { fun inputAmountLong(textAmount: String) = if (textAmount.isEmpty()) { null } else {
try { try {
textAmount.toLong() textAmount.toLong()
} catch (e: Exception) { null } } catch (e: Exception) { null }
} }
fun isValidAmount(amount: Long?): Boolean { fun isValidInputAmount(amount: Long?): Boolean {
if (amount == null) { if (amount == null) {
return false return false
} else if (valueMinimum == null && valueMaximum == null) { } else if (valueMinimum == null && valueMaximum == null) {
@@ -69,4 +70,19 @@ class PollNoteViewModel : ViewModel() {
} }
return false return false
} }
fun optionVoteTally(op: Int): Float {
val tally = pollNote?.zappedPollOptionAmount(op)?.toFloat()?.div(zappedVoteTotal()) ?: 0f
return if (tally.isNaN()) { // catch div by 0
0f
} else { tally }
}
private fun zappedVoteTotal(): Float {
var total = 0f
pollOptions?.keys?.forEach {
total += pollNote?.zappedPollOptionAmount(it)?.toFloat() ?: 0f
}
return total
}
} }