feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import '../../shared/relay/relay.dart';
|
||||
|
||||
/// In-memory cache of other users' presence.
|
||||
///
|
||||
/// Subscribes to kind:20001 presence events over the relay WebSocket for
|
||||
/// real-time updates. There is no longer a REST backstop — agents that
|
||||
/// publish presence purely over WS are fine, and TTL expiry will be handled
|
||||
/// by the relay-side `presence:true` filter extension when that lands.
|
||||
class PresenceCacheNotifier extends Notifier<Map<String, String>> {
|
||||
final Set<String> _tracked = {};
|
||||
void Function()? _presenceUnsub;
|
||||
int _subscriptionVersion = 0;
|
||||
|
||||
@override
|
||||
Map<String, String> build() {
|
||||
final sessionState = ref.watch(relaySessionProvider);
|
||||
|
||||
ref.onDispose(() {
|
||||
_presenceUnsub?.call();
|
||||
_presenceUnsub = null;
|
||||
});
|
||||
|
||||
if (sessionState.status == SessionStatus.connected) {
|
||||
_subscribePresenceUpdates();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/// Track presence for [pubkeys].
|
||||
///
|
||||
/// Currently a no-op for the actual fetch — we rely on live kind:20001
|
||||
/// events. The tracked set is still used to filter incoming events so the
|
||||
/// cache doesn't grow unbounded.
|
||||
void track(List<String> pubkeys) {
|
||||
final normalized = pubkeys.map((pk) => pk.toLowerCase()).toList();
|
||||
_tracked.addAll(normalized);
|
||||
// TODO(presence): once the relay supports a `presence:true` filter
|
||||
// extension, issue a one-shot fetch here for the latest known state per
|
||||
// pubkey. Until then, presence is "online whenever they publish".
|
||||
}
|
||||
|
||||
/// Subscribe to kind:20001 presence events over WebSocket.
|
||||
Future<void> _subscribePresenceUpdates() async {
|
||||
_presenceUnsub?.call();
|
||||
_presenceUnsub = null;
|
||||
_subscriptionVersion++;
|
||||
final version = _subscriptionVersion;
|
||||
|
||||
final session = ref.read(relaySessionProvider.notifier);
|
||||
try {
|
||||
final unsub = await session.subscribe(
|
||||
const NostrFilter(kinds: [EventKind.presenceUpdate], limit: 0),
|
||||
_handlePresenceEvent,
|
||||
);
|
||||
// Guard: if build() re-fired while we were awaiting, discard this
|
||||
// subscription to avoid leaking it.
|
||||
if (version != _subscriptionVersion) {
|
||||
unsub();
|
||||
return;
|
||||
}
|
||||
_presenceUnsub = unsub;
|
||||
} catch (error) {
|
||||
debugPrint(
|
||||
'[PresenceCacheNotifier] presence subscription failed: $error',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _handlePresenceEvent(NostrEvent event) {
|
||||
final pubkey = event.pubkey.toLowerCase();
|
||||
if (!_tracked.contains(pubkey)) return;
|
||||
final status = event.content;
|
||||
if (status != 'online' && status != 'away' && status != 'offline') return;
|
||||
if (state[pubkey] == status) return;
|
||||
final updated = Map<String, String>.from(state);
|
||||
updated[pubkey] = status;
|
||||
state = updated;
|
||||
}
|
||||
}
|
||||
|
||||
final presenceCacheProvider =
|
||||
NotifierProvider<PresenceCacheNotifier, Map<String, String>>(
|
||||
PresenceCacheNotifier.new,
|
||||
);
|
||||
Reference in New Issue
Block a user