feat(chat): app-wide inbox listener so messages arrive without opening the chat
Reception only ran inside an open ChatScreen for a known peer, so a first message from a new peer was invisible: nothing in local storage -> nothing in the inbox list -> you never opened the chat -> you never subscribed. Add InboxService: one long-lived NIP-17 inbox subscription for the whole app (foreground), persisting every incoming message to MessageStore and firing a 'changes' signal the inbox list live-reloads on. Reconnects when the network returns; degrades to nothing offline. Started from main when a social identity exists. Make MessageStore.append idempotent (dedup by sender+timestamp+text) and serialized behind a write lock — the global listener and an open chat's own subscription now write the same conversation concurrently and relays re-deliver stored gift wraps on every resubscribe. Tests for both. Known trade-offs (follow-ups): foreground-only (no push yet); each of InboxService/ChatScreen/MarketScreen opens its own RelayPool (a shared connection is a later optimization).
This commit is contained in:
parent
e852b569ce
commit
73ee98206f
8 changed files with 280 additions and 4 deletions
|
|
@ -21,6 +21,7 @@ import '../services/auto_backup_store.dart';
|
|||
import '../services/export_import_service.dart';
|
||||
import '../services/file_picker_file_service.dart';
|
||||
import '../services/file_service.dart';
|
||||
import '../services/inbox_service.dart';
|
||||
import '../services/locale_store.dart';
|
||||
import '../services/ocr/label_text_extractor.dart';
|
||||
import '../services/ocr/ocr_language.dart';
|
||||
|
|
@ -167,7 +168,18 @@ Future<void> configureDependencies() async {
|
|||
// Optional: absent only if the derivation above failed — then the app runs
|
||||
// inventory-only, by design (market/chat/profile hidden).
|
||||
if (socialService != null) {
|
||||
getIt.registerSingleton<SocialService>(socialService);
|
||||
getIt
|
||||
..registerSingleton<SocialService>(socialService)
|
||||
// App-wide inbox listener so private messages arrive (and land in the
|
||||
// inbox list) even when the specific chat isn't open. Started in `main`.
|
||||
..registerSingleton<InboxService>(
|
||||
InboxService(
|
||||
social: socialService,
|
||||
settings: getIt<SocialSettings>(),
|
||||
store: getIt<MessageStore>(),
|
||||
profileCache: getIt<ProfileCache>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Registered LAST: the "fully wired" sentinel the guard above checks. Anything
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue