mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
fix(concord): an open channel reacts to a key cut, ban or dissolution; say "removed" after a cut
The channel screen read canPost() once, from plain fields the revision tick rewrites, so a key rotation that cut us out (or a ban, or a dissolution) landing while the screen was open left the composer up until it was reopened. It now observes the channel's metadata flow, which that tick invalidates. A member cut from a Private Channel was told they "don't hold its key, so you can't read it" — as if they never had access. The cut now has its own notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fa85e3222b
commit
b1e87e7667
+20
-2
@@ -69,6 +69,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.user.observeUserInfo
|
||||
import com.vitorpamplona.amethyst.commons.resources.Res
|
||||
import com.vitorpamplona.amethyst.commons.resources.back
|
||||
import com.vitorpamplona.amethyst.commons.resources.concord_dissolved_read_only
|
||||
import com.vitorpamplona.amethyst.commons.resources.concord_private_channel_cut
|
||||
import com.vitorpamplona.amethyst.commons.resources.concord_private_channel_no_key
|
||||
import com.vitorpamplona.amethyst.commons.resources.concord_send_image_title
|
||||
import com.vitorpamplona.amethyst.commons.resources.concord_timer_active
|
||||
@@ -116,6 +117,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.DisplayReplying
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.EditingMessageBanner
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.utils.toConcordImeta
|
||||
import com.vitorpamplona.quartz.concord.cord03Channels.ConcordChannelId
|
||||
import com.vitorpamplona.quartz.concord.cord03Channels.ConcordChannelKeyring
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.paging.RelayPagingProgress
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
@@ -282,7 +284,15 @@ fun ConcordChannelScreen(
|
||||
|
||||
ConcordTypingIndicator(communityId, channelId, accountViewModel)
|
||||
|
||||
if (channel.canPost()) {
|
||||
// canPost()/keyHeld are plain fields the revision tick rewrites; observing the channel's
|
||||
// metadata flow (invalidated on every such change) is what makes a key cut, a ban or a
|
||||
// dissolution landing while this screen is open swap the composer for its notice.
|
||||
val channelInfo by channel
|
||||
.flow()
|
||||
.metadata.stateFlow
|
||||
.collectAsStateWithLifecycle()
|
||||
val canPost = remember(channelInfo) { channel.canPost() }
|
||||
if (canPost) {
|
||||
ConcordTimerIndicator(communityId, accountViewModel)
|
||||
Spacer(modifier = DoubleVertSpacer)
|
||||
ConcordMessageComposer(
|
||||
@@ -298,7 +308,15 @@ fun ConcordChannelScreen(
|
||||
} else if (!channel.keyHeld) {
|
||||
// CORD-03 §1: a Private Channel is keyed independently; without its key there is no
|
||||
// plane only its members can read, so nothing may be posted (never to the root plane).
|
||||
ConcordReadOnlyNotice(Res.string.concord_private_channel_no_key)
|
||||
// A rotation that left us out (CORD-06 §2): say we were removed, not that we never had access.
|
||||
val wasCut =
|
||||
remember(channelInfo) {
|
||||
account.concordSessions
|
||||
.sessionFor(communityId)
|
||||
?.entry
|
||||
?.let { ConcordChannelKeyring.cutsOf(it).containsKey(channelId.lowercase()) } == true
|
||||
}
|
||||
ConcordReadOnlyNotice(if (wasCut) Res.string.concord_private_channel_cut else Res.string.concord_private_channel_no_key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,6 +616,7 @@
|
||||
<string name="concord_timer_active">Messages disappear after %1$s</string>
|
||||
<string name="concord_dissolved_read_only">This community has been dissolved and is now read-only. You can still read its history, but no new messages can be posted.</string>
|
||||
<string name="concord_private_channel_no_key">This is a private channel and you don't hold its key, so you can't read it or post here.</string>
|
||||
<string name="concord_private_channel_cut">You no longer have access to this private channel: its key was rotated without you, so you can't read new messages or post here.</string>
|
||||
<string name="concord_pinned_title">Pinned messages</string>
|
||||
<string name="concord_pinned_empty">No pinned messages in this channel yet.</string>
|
||||
<string name="concord_pinned_unavailable">This channel's pins are sealed under a key you don't hold, so they can't be shown here, and pinning is paused until they can be read.</string>
|
||||
|
||||
Reference in New Issue
Block a user