Fixing stack overflow with more than 200 zaps in a single note.
This commit is contained in:
@@ -729,7 +729,7 @@ class Account(
|
|||||||
zapResponseEvent.response(signer, onReady)
|
zapResponseEvent.response(signer, onReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun calculateIfNoteWasZappedByAccount(
|
suspend fun calculateIfNoteWasZappedByAccount(
|
||||||
zappedNote: Note?,
|
zappedNote: Note?,
|
||||||
onWasZapped: () -> Unit,
|
onWasZapped: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import com.vitorpamplona.quartz.events.LiveActivitiesEvent
|
|||||||
import com.vitorpamplona.quartz.events.LnZapEvent
|
import com.vitorpamplona.quartz.events.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.events.LnZapPaymentRequestEvent
|
import com.vitorpamplona.quartz.events.LnZapPaymentRequestEvent
|
||||||
import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent
|
import com.vitorpamplona.quartz.events.LnZapPaymentResponseEvent
|
||||||
|
import com.vitorpamplona.quartz.events.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
import com.vitorpamplona.quartz.events.LongTextNoteEvent
|
||||||
import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse
|
import com.vitorpamplona.quartz.events.PayInvoiceSuccessResponse
|
||||||
import com.vitorpamplona.quartz.events.RepostEvent
|
import com.vitorpamplona.quartz.events.RepostEvent
|
||||||
@@ -66,10 +67,13 @@ import com.vitorpamplona.quartz.utils.containsAny
|
|||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class AddressableNote(val address: ATag) : Note(address.toTag()) {
|
class AddressableNote(val address: ATag) : Note(address.toTag()) {
|
||||||
@@ -521,7 +525,7 @@ open class Note(val idHex: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveIsZappedByCalculation(
|
private suspend fun isZappedByCalculation(
|
||||||
option: Int?,
|
option: Int?,
|
||||||
user: User,
|
user: User,
|
||||||
account: Account,
|
account: Account,
|
||||||
@@ -532,48 +536,65 @@ open class Note(val idHex: String) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val next = remainingZapEvents.first()
|
remainingZapEvents.forEach { next ->
|
||||||
|
val zapRequest = next.first.event as LnZapRequestEvent
|
||||||
|
val zapEvent = next.second?.event as? LnZapEvent
|
||||||
|
|
||||||
if (next.first.author?.pubkeyHex == user.pubkeyHex) {
|
if (!zapRequest.isPrivateZap()) {
|
||||||
onWasZappedByAuthor()
|
// public events
|
||||||
} else {
|
if (zapRequest.pubKey == user.pubkeyHex && (option == null || option == zapEvent?.zappedPollOption())) {
|
||||||
account.decryptZapContentAuthor(next.first) {
|
|
||||||
if (
|
|
||||||
it.pubKey == user.pubkeyHex &&
|
|
||||||
(option == null || option == (it as? LnZapEvent)?.zappedPollOption())
|
|
||||||
) {
|
|
||||||
onWasZappedByAuthor()
|
onWasZappedByAuthor()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// private events
|
||||||
|
|
||||||
|
// if has already decrypted
|
||||||
|
val privateZap = zapRequest.cachedPrivateZap()
|
||||||
|
if (privateZap != null) {
|
||||||
|
if (privateZap.pubKey == user.pubkeyHex && (option == null || option == zapEvent?.zappedPollOption())) {
|
||||||
|
onWasZappedByAuthor()
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
recursiveIsZappedByCalculation(
|
if (account.isWriteable()) {
|
||||||
option,
|
val result =
|
||||||
user,
|
withTimeoutOrNull(1000) {
|
||||||
account,
|
suspendCancellableCoroutine { continuation ->
|
||||||
remainingZapEvents.minus(next),
|
zapRequest.decryptPrivateZap(account.signer) {
|
||||||
onWasZappedByAuthor,
|
continuation.resume(it)
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result?.pubKey == user.pubkeyHex && (option == null || option == zapEvent?.zappedPollOption())) {
|
||||||
|
onWasZappedByAuthor()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isZappedBy(
|
suspend fun isZappedBy(
|
||||||
user: User,
|
user: User,
|
||||||
account: Account,
|
account: Account,
|
||||||
onWasZappedByAuthor: () -> Unit,
|
onWasZappedByAuthor: () -> Unit,
|
||||||
) {
|
) {
|
||||||
recursiveIsZappedByCalculation(null, user, account, zaps.toList(), onWasZappedByAuthor)
|
isZappedByCalculation(null, user, account, zaps.toList(), onWasZappedByAuthor)
|
||||||
if (account.userProfile() == user) {
|
if (account.userProfile() == user) {
|
||||||
recursiveIsPaidByCalculation(account, zapPayments.toList(), onWasZappedByAuthor)
|
recursiveIsPaidByCalculation(account, zapPayments.toList(), onWasZappedByAuthor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isZappedBy(
|
suspend fun isZappedBy(
|
||||||
option: Int?,
|
option: Int?,
|
||||||
user: User,
|
user: User,
|
||||||
account: Account,
|
account: Account,
|
||||||
onWasZappedByAuthor: () -> Unit,
|
onWasZappedByAuthor: () -> Unit,
|
||||||
) {
|
) {
|
||||||
recursiveIsZappedByCalculation(option, user, account, zaps.toList(), onWasZappedByAuthor)
|
isZappedByCalculation(option, user, account, zaps.toList(), onWasZappedByAuthor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReactionBy(user: User): String? {
|
fun getReactionBy(user: User): String? {
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ class PollNoteViewModel : ViewModel() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPollOptionZappedBy(
|
suspend fun isPollOptionZappedBy(
|
||||||
option: Int,
|
option: Int,
|
||||||
user: User,
|
user: User,
|
||||||
onWasZappedByAuthor: () -> Unit,
|
onWasZappedByAuthor: () -> Unit,
|
||||||
|
|||||||
Reference in New Issue
Block a user