mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-10-09 18:32:37 +02:00
add option tally percentage bars,
create new PollNoteViewModel for each PollNote, fix isVoteAmountAtomic to directly launch wallet
This commit is contained in:
@@ -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(
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user