refactor(social): one shared relay connection per identity
Every feature (offers, messaging, trust, profile, the inbox listener) used to open its OWN RelayPool via social.openSession — several sockets to the same relays, more battery, and reconnection logic living only in the inbox listener. Add SocialConnection: ONE shared session per identity, lazily connected and reused by all. It watches connectivity — dropping the session when the network goes and reconnecting when it returns, announcing each change on a sessions stream so the inbox listener re-subscribes automatically. Callers get the session via connection.session() and never close it (the connection owns its lifecycle); recreated/disposed on an identity switch. - InboxService now consumes the shared connection (subscribes on its sessions stream) instead of owning its own socket + connectivity code. - createOffersCubit + the chat/market/profile screens use the shared connection; dead createMessagesCubit/createTrustCubit factories removed. - DI registers SocialConnection per identity; Bootstrap starts it (after the inbox subscribes); switchSocialAccount disposes + recreates it. Tests: SocialConnection lifecycle (reuse, concurrent connect, offline drop + reconnect, unreachable retry) with a fake opener + online stream; inbox test updated. nostr added as a dev_dependency for the channel fake.
This commit is contained in:
parent
e2b88b4f26
commit
bb4ee2fd89
19 changed files with 431 additions and 280 deletions
|
|
@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||
import 'package:tane/services/inbox_service.dart';
|
||||
import 'package:tane/services/message_store.dart';
|
||||
import 'package:tane/services/notification_service.dart';
|
||||
import 'package:tane/services/social_connection.dart';
|
||||
import 'package:tane/services/social_service.dart';
|
||||
import 'package:tane/services/social_settings.dart';
|
||||
import 'package:tane/services/unread_service.dart';
|
||||
|
|
@ -26,21 +27,29 @@ class _RecordingNotifications extends NotificationService {
|
|||
}
|
||||
}
|
||||
|
||||
/// The app-wide inbox listener persists incoming messages and announces changes,
|
||||
/// so the inbox list refreshes even when the specific chat isn't open. Driven
|
||||
/// through the [InboxService.ingest] seam so no relay/network is involved.
|
||||
/// The app-wide inbox listener persists incoming messages, updates unread and
|
||||
/// notifies — even when the specific chat isn't open. Driven through the
|
||||
/// [InboxService.ingest] seam so no relay/network is involved.
|
||||
void main() {
|
||||
const seedHex =
|
||||
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
|
||||
|
||||
// A connection that never actually opens — ingest doesn't use it.
|
||||
Future<SocialConnection> offlineConnection() async => SocialConnection(
|
||||
social: await SocialService.fromRootSeedHex(seedHex),
|
||||
settings: SocialSettings(InMemorySecretStore()),
|
||||
open: (_) async => throw StateError('unused in ingest tests'),
|
||||
online: const Stream.empty(),
|
||||
);
|
||||
|
||||
late MessageStore store;
|
||||
late InboxService inbox;
|
||||
|
||||
setUp(() async {
|
||||
store = MessageStore(InMemorySecretStore());
|
||||
inbox = InboxService(
|
||||
social: await SocialService.fromRootSeedHex(seedHex),
|
||||
settings: SocialSettings(InMemorySecretStore()),
|
||||
connection: await offlineConnection(),
|
||||
selfPubkey: 'me',
|
||||
store: store,
|
||||
);
|
||||
});
|
||||
|
|
@ -75,16 +84,14 @@ void main() {
|
|||
group('unread + notification hooks', () {
|
||||
late UnreadService unread;
|
||||
late _RecordingNotifications notifications;
|
||||
late String myPubkey;
|
||||
const myPubkey = 'me';
|
||||
|
||||
setUp(() async {
|
||||
final social = await SocialService.fromRootSeedHex(seedHex);
|
||||
myPubkey = social.publicKeyHex;
|
||||
unread = UnreadService(store, InMemorySecretStore());
|
||||
notifications = _RecordingNotifications();
|
||||
inbox = InboxService(
|
||||
social: social,
|
||||
settings: SocialSettings(InMemorySecretStore()),
|
||||
connection: await offlineConnection(),
|
||||
selfPubkey: myPubkey,
|
||||
store: store,
|
||||
unread: unread,
|
||||
notifications: notifications,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue