From 19557bf358ba317ddf3d26669113fbcad90876b7 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 22 Sep 2023 16:50:25 -0400 Subject: [PATCH] Filters zap payments outside the established min-max parameters on polls. --- .../amethyst/ui/note/PollNoteViewModel.kt | 67 ++++++++++++++----- .../quartz/events/PollNoteEvent.kt | 24 +++++-- 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt index e5cd1c436..b29068ac0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNoteViewModel.kt @@ -33,9 +33,12 @@ class PollNoteViewModel : ViewModel() { private var pollEvent: PollNoteEvent? = null private var pollOptions: Map? = null - private var valueMaximum: Int? = null - private var valueMinimum: Int? = null - private var closedAt: Int? = null + private var valueMaximum: Long? = null + private var valueMinimum: Long? = null + private var valueMaximumBD: BigDecimal? = null + private var valueMinimumBD: BigDecimal? = null + + private var closedAt: Long? = null private var consensusThreshold: BigDecimal? = null private var totalZapped: BigDecimal = BigDecimal.ZERO @@ -49,10 +52,12 @@ class PollNoteViewModel : ViewModel() { pollNote = note pollEvent = pollNote?.event as PollNoteEvent pollOptions = pollEvent?.pollOptions() - valueMaximum = pollEvent?.getTagInt(VALUE_MAXIMUM) - valueMinimum = pollEvent?.getTagInt(VALUE_MINIMUM) - consensusThreshold = pollEvent?.getTagInt(CONSENSUS_THRESHOLD)?.toFloat()?.div(100)?.toBigDecimal() - closedAt = pollEvent?.getTagInt(CLOSED_AT) + valueMaximum = pollEvent?.getTagLong(VALUE_MAXIMUM) + valueMinimum = pollEvent?.getTagLong(VALUE_MINIMUM) + valueMinimumBD = valueMinimum?.let { BigDecimal(it) } + valueMaximumBD = valueMaximum?.let { BigDecimal(it) } + consensusThreshold = pollEvent?.getTagLong(CONSENSUS_THRESHOLD)?.toFloat()?.div(100)?.toBigDecimal() + closedAt = pollEvent?.getTagLong(CLOSED_AT) } fun refreshTallies() { @@ -110,6 +115,29 @@ class PollNoteViewModel : ViewModel() { } catch (e: Exception) { null } } + fun isValidInputVoteAmount(amount: BigDecimal?): Boolean { + if (amount == null) { + return false + } else if (valueMinimum == null && valueMaximum == null) { + if (amount > BigDecimal.ZERO) { + return true + } + } else if (valueMinimum == null) { + if (amount > BigDecimal.ZERO && amount <= valueMaximumBD!!) { + return true + } + } else if (valueMaximum == null) { + if (amount >= valueMinimumBD!!) { + return true + } + } else { + if ((valueMinimumBD!! <= amount) && (amount <= valueMaximumBD!!)) { + return true + } + } + return false + } + fun isValidInputVoteAmount(amount: Long?): Boolean { if (amount == null) { return false @@ -145,24 +173,29 @@ class PollNoteViewModel : ViewModel() { private fun zappedPollOptionAmount(option: Int): BigDecimal { return pollNote?.zaps?.values?.sumOf { val event = it?.event as? LnZapEvent - if (event?.zappedPollOption() == option) { - event.amount ?: BigDecimal(0) + val zapAmount = event?.amount ?: BigDecimal.ZERO + val isValidAmount = isValidInputVoteAmount(event?.amount) + + if (isValidAmount && event?.zappedPollOption() == option) { + zapAmount } else { - BigDecimal(0) + BigDecimal.ZERO } - } ?: BigDecimal(0) + } ?: BigDecimal.ZERO } private fun totalZapped(): BigDecimal { return pollNote?.zaps?.values?.sumOf { val zapEvent = (it?.event as? LnZapEvent) + val zapAmount = zapEvent?.amount ?: BigDecimal.ZERO + val isValidAmount = isValidInputVoteAmount(zapEvent?.amount) - if (zapEvent?.zappedPollOption() != null) { - zapEvent.amount ?: BigDecimal(0) + if (isValidAmount && zapEvent?.zappedPollOption() != null) { + zapAmount } else { - BigDecimal(0) + BigDecimal.ZERO } - } ?: BigDecimal(0) + } ?: BigDecimal.ZERO } fun createZapOptionsThatMatchThePollingParameters(): List { @@ -176,8 +209,8 @@ class PollNoteViewModel : ViewModel() { } } } - valueMinimum?.let { options.add(it.toLong()) } - valueMaximum?.let { options.add(it.toLong()) } + valueMinimum?.let { options.add(it) } + valueMaximum?.let { options.add(it) } return options.toSet().sorted() } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt index 5414afe3b..739964019 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/PollNoteEvent.kt @@ -27,13 +27,16 @@ class PollNoteEvent( tags.filter { it.size > 2 && it[0] == POLL_OPTION } .associate { it[1].toInt() to it[2] } - fun getTagInt(property: String): Int? { + fun minimumAmount() = tags.firstOrNull() { it.size > 1 && it[0] == VALUE_MINIMUM }?.getOrNull(1)?.toLongOrNull() + fun maximumAmount() = tags.firstOrNull() { it.size > 1 && it[0] == VALUE_MAXIMUM }?.getOrNull(1)?.toLongOrNull() + + fun getTagLong(property: String): Long? { val number = tags.firstOrNull() { it.size > 1 && it[0] == property }?.get(1) return if (number.isNullOrBlank() || number == "null") { null } else { - number.toInt() + number.toLong() } } @@ -71,11 +74,18 @@ class PollNoteEvent( pollOptions.forEach { poll_op -> tags.add(listOf(POLL_OPTION, poll_op.key.toString(), poll_op.value)) } - tags.add(listOf(VALUE_MAXIMUM, valueMaximum.toString())) - tags.add(listOf(VALUE_MINIMUM, valueMinimum.toString())) - tags.add(listOf(CONSENSUS_THRESHOLD, consensusThreshold.toString())) - tags.add(listOf(CLOSED_AT, closedAt.toString())) - + valueMaximum?.let { + tags.add(listOf(VALUE_MAXIMUM, valueMaximum.toString())) + } + valueMinimum?.let { + tags.add(listOf(VALUE_MINIMUM, valueMinimum.toString())) + } + consensusThreshold?.let { + tags.add(listOf(CONSENSUS_THRESHOLD, consensusThreshold.toString())) + } + closedAt?.let { + tags.add(listOf(CLOSED_AT, closedAt.toString())) + } zapReceiver?.forEach { tags.add(listOf("zap", it.lnAddressOrPubKeyHex, it.relay ?: "", it.weight.toString())) }