mirror of
https://github.com/block/buzz.git
synced 2026-10-30 14:01:37 +00:00
mobile: share and test the page typing selector
Channel and thread pages now watch one visibleTypingProvider, and a test checks that the user's own echoed indicator does not notify it while another user's typing does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
@@ -366,12 +366,10 @@ class _ResolvedChannelDetailPage extends HookConsumerWidget {
|
||||
// Ordinary channels keep thread activity inside the thread view.
|
||||
final typingEntries = ref
|
||||
.watch(
|
||||
channelTypingProvider(channel.id).select(
|
||||
(all) => VisibleTyping(
|
||||
all,
|
||||
selfPubkey: currentPubkey,
|
||||
include: (e) => personalChat || e.threadHeadId == null,
|
||||
),
|
||||
visibleTypingProvider(
|
||||
channel.id,
|
||||
selfPubkey: currentPubkey,
|
||||
include: (e) => personalChat || e.threadHeadId == null,
|
||||
),
|
||||
)
|
||||
.entries;
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:hooks_riverpod/misc.dart' show ProviderListenable;
|
||||
|
||||
import '../../shared/relay/relay.dart';
|
||||
|
||||
@@ -56,6 +57,17 @@ class VisibleTyping {
|
||||
int get hashCode => Object.hashAll(entries);
|
||||
}
|
||||
|
||||
/// What a page watches to show typing in [channelId]: everyone but
|
||||
/// [selfPubkey], filtered by [include]. The user's own echoed indicator
|
||||
/// refreshes its expiry every few seconds, and this skips those updates.
|
||||
ProviderListenable<VisibleTyping> visibleTypingProvider(
|
||||
String channelId, {
|
||||
required String? selfPubkey,
|
||||
required bool Function(TypingEntry entry) include,
|
||||
}) => channelTypingProvider(
|
||||
channelId,
|
||||
).select((all) => VisibleTyping(all, selfPubkey: selfPubkey, include: include));
|
||||
|
||||
/// Tracks who is currently typing in a specific channel.
|
||||
///
|
||||
/// Subscribes to typing and message events so a reply ends its typing signal.
|
||||
|
||||
@@ -786,12 +786,10 @@ class ThreadDetailPage extends HookConsumerWidget {
|
||||
// Thread-scoped typing indicators (exclude self).
|
||||
final threadTyping = ref
|
||||
.watch(
|
||||
channelTypingProvider(channelId).select(
|
||||
(all) => VisibleTyping(
|
||||
all,
|
||||
selfPubkey: currentPubkey,
|
||||
include: (e) => e.threadHeadId == threadHead.id,
|
||||
),
|
||||
visibleTypingProvider(
|
||||
channelId,
|
||||
selfPubkey: currentPubkey,
|
||||
include: (e) => e.threadHeadId == threadHead.id,
|
||||
),
|
||||
)
|
||||
.entries;
|
||||
|
||||
@@ -247,4 +247,47 @@ void main() {
|
||||
container.dispose();
|
||||
}),
|
||||
);
|
||||
test(
|
||||
'pages ignore the user\'s own typing echo but see others',
|
||||
() => fakeAsync((async) {
|
||||
final relay = _Relay();
|
||||
final container = ProviderContainer(
|
||||
overrides: [relaySessionProvider.overrideWith(() => relay)],
|
||||
);
|
||||
final seen = <List<String>>[];
|
||||
container.listen(
|
||||
visibleTypingProvider(
|
||||
'chat',
|
||||
selfPubkey: 'ME',
|
||||
include: (e) => e.threadHeadId == null,
|
||||
),
|
||||
(_, next) => seen.add([for (final e in next.entries) e.pubkey]),
|
||||
);
|
||||
_settle(container, async);
|
||||
void typing(String id, String pubkey) => relay.receive(
|
||||
NostrEvent(
|
||||
id: id,
|
||||
pubkey: pubkey,
|
||||
kind: 20002,
|
||||
createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
content: '',
|
||||
sig: '',
|
||||
tags: [
|
||||
['h', 'chat'],
|
||||
],
|
||||
),
|
||||
);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
typing('self-$i', 'me');
|
||||
async.elapse(const Duration(seconds: 3));
|
||||
}
|
||||
expect(container.read(channelTypingProvider('chat')), hasLength(1));
|
||||
expect(seen, isEmpty);
|
||||
typing('other', 'agent');
|
||||
expect(seen, [
|
||||
['agent'],
|
||||
]);
|
||||
container.dispose();
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user