mirror of
https://github.com/block/buzz.git
synced 2026-10-27 12:40:30 +00:00
## Summary Hiding a DM row and then receiving a new message from that person never brought the row back — the reader was left with only an Inbox notification. This restores the row from live activity, client-side, with no relay or database changes. - Subscribe to hidden-DM activity **channel-scoped** over the hidden-DM id set (`#h`), re-registering whenever the set changes. The relay's `fan_out_scoped` only routes channel-scoped events (every kind:9 DM carries a `channel_id`) to channel-scoped subscriptions, so a community-global `#p` filter receives nothing. Hiding a DM never drops membership, so `#h` authorization holds. Because every delivered event is already for a hidden DM the reader belongs to, eligibility no longer needs a self `p` tag — untagged CLI/agent DMs resurface too — and no per-event visibility fetch is required. - On qualifying activity, invoke the existing open-DM action (`41010`) to reopen the hidden one-to-one or group DM, validating that the relay reopened the same channel. - Preserve the existing relay-synced hide snapshot (`41012` → `30622`); hide state still syncs across devices. - Let Inbox reopen a hidden DM before navigating to its message, with a busy state on the row and context-menu "Open in channel" action while a reopen is pending. - Coalesce resurface attempts per channel: a concurrent message that arrives while a reopen is in flight triggers a retry on failure instead of being marked handled and dropped. - Write exact dm-visibility query keys on open/hide mutations. This is the client-only replacement agreed in the Buzz design thread and supersedes #6713. The accepted limitation is that resurface only fires while a client is running — a message that arrives while all clients are closed does not restore the row on next launch (the `30622` snapshot has no watermark); Inbox click-through is the safety net for that case. Addresses #6316. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz>
28 lines
1.1 KiB
Dart
28 lines
1.1 KiB
Dart
import '../../shared/relay/relay.dart';
|
|
|
|
final _hexPubkey = RegExp(r'^[0-9a-f]{64}$');
|
|
|
|
Set<String> dmPeerPubkeysFromMembers(
|
|
Iterable<String> memberPubkeys,
|
|
String currentPubkey,
|
|
) {
|
|
final self = currentPubkey.trim().toLowerCase();
|
|
final members = memberPubkeys
|
|
.map((pubkey) => pubkey.trim().toLowerCase())
|
|
.where(_hexPubkey.hasMatch)
|
|
.toSet();
|
|
if (!_hexPubkey.hasMatch(self) || !members.contains(self)) return {};
|
|
return members..remove(self);
|
|
}
|
|
|
|
// The resurface subscription is `#h`-scoped to the hidden-DM set, so the relay
|
|
// only delivers events already addressed to a hidden channel the reader belongs
|
|
// to. Eligibility therefore drops the `#p` requirement — an untagged DM (a CLI
|
|
// or agent send that omits participant `p` tags) still resurfaces the row.
|
|
bool isIncomingChannelMessageFromOther(NostrEvent event, String currentPubkey) {
|
|
final self = currentPubkey.trim().toLowerCase();
|
|
return event.channelId != null &&
|
|
EventKind.channelMessageEventKinds.contains(event.kind) &&
|
|
event.pubkey.toLowerCase() != self;
|
|
}
|