Files
buzz/mobile/lib/features/channels/thread_reply_ownership.dart
Tom Brow a61239f0d8 fix(mobile): avoid opening empty threads on message tap (#7756)
Tapping a mobile channel message with no replies currently opens an
empty thread. Only enable message-row thread navigation when the
existing thread summary reports replies, including replies known to the
relay but not loaded locally. Long-press → Reply still starts a new
thread.

Added widget tests for zero replies, loaded replies, relay-only replies,
and starting a thread through Reply. The zero-reply test failed before
the fix and passes afterward.

Validation: all 227 channel-page tests, the full mobile pre-push checks,
and all PR CI checks passed. The full repository gate failed in
unchanged Rust ACP timing tests (idle reset, keepalive, and steering
deadlines); this PR changes only mobile Dart files.

No duplicate open PR or issue found.

---------

Signed-off-by: Tom Brow <tomb@block.xyz>
2026-09-21 08:51:05 -07:00

27 lines
855 B
Dart

import '../../shared/relay/relay.dart';
/// Bounded identity-only evidence for replies whose payloads may be evicted.
class ThreadReplyOwnership {
final Map<String, String> _roots = {};
/// Remembers recent ownership without retaining event payloads.
void record(Iterable<NostrEvent> events) {
for (final event in events) {
final thread = event.threadReference;
if (!EventKind.channelTimelineContentKinds.contains(event.kind) ||
thread.parentId == null ||
thread.rootId == null) {
continue;
}
_roots.remove(event.id);
_roots[event.id] = thread.rootId!;
while (_roots.length > 8192) {
_roots.remove(_roots.keys.first);
}
}
}
/// Returns known ownership or null when the identity evidence was evicted.
String? rootFor(String eventId) => _roots[eventId];
}