mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
refactor(nests): route host actions through AccountViewModel.launchSigner
Replace the raw viewModelScope.launch + runCatching with launchSigner, matching the rest of the codebase. Same survival-past-dismiss guarantee, plus signer errors (read-only key, NIP-46 unauthorized / timeout, signer not found) now surface as toasts instead of being silently swallowed.
This commit is contained in:
+5
-10
@@ -42,7 +42,6 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.ui.MainActivity
|
||||
import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage
|
||||
@@ -56,7 +55,6 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ROLE
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Per-participant context sheet (T2 #2). Always shows the
|
||||
@@ -97,16 +95,13 @@ internal fun ParticipantHostActionsSheet(
|
||||
relay = null,
|
||||
)
|
||||
|
||||
// Use the AccountViewModel's scope so the launched broadcast
|
||||
// survives the onDismiss() that every action row triggers. A
|
||||
// composition-scoped rememberCoroutineScope() gets cancelled the
|
||||
// moment hostMenuTarget flips to null and the sheet leaves the
|
||||
// tree — which races (and reliably loses) against the suspending
|
||||
// signer.sign(template) call, so the promote/demote/kick events
|
||||
// never actually went out.
|
||||
// Go through accountViewModel.launchSigner so the broadcast runs on
|
||||
// viewModelScope (survives onDismiss() removing the sheet from
|
||||
// composition) and signer errors surface as toasts instead of being
|
||||
// silently swallowed.
|
||||
fun broadcast(template: com.vitorpamplona.quartz.nip01Core.signers.EventTemplate<out com.vitorpamplona.quartz.nip01Core.core.Event>?) {
|
||||
template ?: return
|
||||
accountViewModel.viewModelScope.launch { runCatching { accountViewModel.account.signAndComputeBroadcast(template) } }
|
||||
accountViewModel.launchSigner { accountViewModel.account.signAndComputeBroadcast(template) }
|
||||
}
|
||||
|
||||
val targetUser =
|
||||
|
||||
+8
-11
@@ -40,7 +40,6 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.viewmodels.NestViewModel
|
||||
import com.vitorpamplona.amethyst.commons.viewmodels.RoomPresence
|
||||
@@ -53,7 +52,6 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35dp
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.tags.ROLE
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Host-only queue of audience members whose latest kind-10312
|
||||
@@ -111,16 +109,15 @@ internal fun HandRaiseQueueSection(
|
||||
hand = hand,
|
||||
accountViewModel = accountViewModel,
|
||||
onApprove = {
|
||||
// Approving makes `canSpeak()` true for this user, which
|
||||
// removes them from `hands` on the next recompose. If the
|
||||
// queue empties (no other raised hands), the whole
|
||||
// section leaves composition — a rememberCoroutineScope()
|
||||
// bound here would cancel the in-flight signer.sign(...)
|
||||
// and the promote never goes out. Launch on the
|
||||
// AccountViewModel's scope so signing outlives the row.
|
||||
accountViewModel.viewModelScope.launch {
|
||||
// launchSigner runs on viewModelScope (+ Dispatchers.IO)
|
||||
// and surfaces signer errors as toasts. Composition-scoped
|
||||
// alternatives get cancelled when this row leaves the tree:
|
||||
// approving flips `canSpeak()` true, the hand is filtered
|
||||
// out, and if it was the last hand the section disposes
|
||||
// entirely — killing the in-flight sign(...) before it ran.
|
||||
accountViewModel.launchSigner {
|
||||
val template = RoomParticipantActions.setRole(event, hand.pubkey, ROLE.SPEAKER)
|
||||
template?.let { runCatching { accountViewModel.account.signAndComputeBroadcast(it) } }
|
||||
template?.let { accountViewModel.account.signAndComputeBroadcast(it) }
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user