From b2600b98794bc3ff15dadcab350298bb24f31915 Mon Sep 17 00:00:00 2001 From: balzack Date: Mon, 10 Feb 2025 21:33:05 -0800 Subject: [PATCH] emit when content loaded --- .../mobile/src/session/useSession.hook.ts | 9 +++++- app/sdk/src/api.ts | 3 ++ app/sdk/src/contact.ts | 18 +++++++++++ app/sdk/src/content.ts | 30 +++++++++++++++++++ app/sdk/src/stream.ts | 18 +++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/app/client/mobile/src/session/useSession.hook.ts b/app/client/mobile/src/session/useSession.hook.ts index 1ece799e..bfef660d 100644 --- a/app/client/mobile/src/session/useSession.hook.ts +++ b/app/client/mobile/src/session/useSession.hook.ts @@ -20,6 +20,10 @@ export function useSession() { }; useEffect(() => { + const setContentState = (loaded: boolean) => { + console.log('content loaded: ', loaded); + updateState({ loaded }); + } const setSdkState = (state: string) => { updateState({ sdkState: state === 'connected' }); } @@ -28,10 +32,13 @@ export function useSession() { } const session = app.state.session; if (session) { + const content = session.getContent(); + content.addLoadedListener(setContentState); session.addStatusListener(setSdkState); const sub = AppState.addEventListener('change', setAppState); return () => { - session.removeStatusListener(); + session.removeStatusListener(setSdkState); + content.removeLoadedListener(setContentState); sub.remove(); } } diff --git a/app/sdk/src/api.ts b/app/sdk/src/api.ts index 6483b6b6..857239b9 100644 --- a/app/sdk/src/api.ts +++ b/app/sdk/src/api.ts @@ -109,6 +109,9 @@ export interface Content { addChannelListener(ev: (arg: { channels: Channel[]; cardId: string | null }) => void): void; removeChannelListener(ev: (arg: { channels: Channel[]; cardId: string | null }) => void): void; + + addLoadedListener(ev: (loaded: boolean) => void): void; + removeLoadedListener(ev: (loaded: boolean) => void): void; } export interface Alias { diff --git a/app/sdk/src/contact.ts b/app/sdk/src/contact.ts index 34e9e1a5..a9f4e265 100644 --- a/app/sdk/src/contact.ts +++ b/app/sdk/src/contact.ts @@ -47,6 +47,7 @@ export class ContactModule implements Contact { private token: string; private node: string; private secure: boolean; + private loaded: boolean; private emitter: EventEmitter; private articleTypes: string[]; private channelTypes: string[]; @@ -93,6 +94,7 @@ export class ContactModule implements Contact { this.articleTypes = articleTypes; this.channelTypes = channelTypes; this.unsealAll = false; + this.loaded = false; this.focus = null; this.seal = null; @@ -172,6 +174,9 @@ export class ContactModule implements Contact { this.unsealAll = true; this.syncing = false; await this.sync(); + + this.loaded = true; + this.emitLoaded(); } public async setRevision(rev: number): Promise { @@ -684,6 +689,19 @@ export class ContactModule implements Contact { this.emitter.emit('channel', { cardId, channels }); } + public addLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.on('loaded', ev); + ev(this.loaded); + } + + public removeLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.off('loaded', ev); + } + + private emitLoaded() { + this.emitter.emit('loaded', this.loaded); + } + public async setFocus(cardId: string, channelId: string): Promise { if (this.focus) { this.focus.close(); diff --git a/app/sdk/src/content.ts b/app/sdk/src/content.ts index 13992491..4bd7569e 100644 --- a/app/sdk/src/content.ts +++ b/app/sdk/src/content.ts @@ -1,3 +1,4 @@ +import { EventEmitter } from 'eventemitter3'; import type { Content } from './api'; import type { Channel } from './types'; import { ContactModule } from './contact'; @@ -8,14 +9,30 @@ import { Crypto } from './crypto'; export class ContentModule implements Content { private crypto: Crypto | null; private log: Logging; + private emitter: EventEmitter; private contact: ContactModule; private stream: StreamModule; + private streamLoaded: boolean; + private contactLoaded: boolean; constructor(log: Logging, crypto: Crypto | null, contact: ContactModule, stream: StreamModule) { this.contact = contact; this.stream = stream; this.log = log; this.crypto = crypto; + this.emitter = new EventEmitter(); + this.streamLoaded = false; + this.contactLoaded = false; + + this.stream.addLoadedListener((loaded: boolean) => { + this.streamLoaded = loaded; + this.emitLoaded(); + }); + + this.contact.addLoadedListener((loaded: boolean) => { + this.contactLoaded = loaded; + this.emitLoaded(); + }); } public async addChannel(sealed: boolean, type: string, subject: any, cardIds: string[]): Promise { @@ -115,4 +132,17 @@ export class ContentModule implements Content { this.stream.removeChannelListener(ev); this.contact.removeChannelListener(ev); } + + public addLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.on('loaded', ev); + ev(this.streamLoaded && this.contactLoaded); + } + + public removeLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.off('loaded', ev); + } + + private emitLoaded() { + this.emitter.emit('loaded', this.streamLoaded && this.contactLoaded); + } } diff --git a/app/sdk/src/stream.ts b/app/sdk/src/stream.ts index 2f380f36..d967810c 100644 --- a/app/sdk/src/stream.ts +++ b/app/sdk/src/stream.ts @@ -41,6 +41,7 @@ export class StreamModule { private nextRevision: number | null; private seal: { privateKey: string; publicKey: string } | null; private unsealAll: boolean; + private loaded: boolean; private blocked: Set; private read: Map private channelTypes: string[]; @@ -61,6 +62,7 @@ export class StreamModule { this.focus = null; this.seal = null; this.unsealAll = false; + this.loaded = false; this.channelTypes = channelTypes; this.emitter = new EventEmitter(); @@ -102,6 +104,9 @@ export class StreamModule { this.unsealAll = true; this.syncing = false; await this.sync(); + + this.loaded = true; + this.emitLoaded(); } private parse(data: string | null): any { @@ -269,6 +274,19 @@ export class StreamModule { this.emitter.emit('channel', { channels, cardId: null }); } + public addLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.on('loaded', ev); + ev(this.loaded); + } + + public removeLoadedListener(ev: (loaded: boolean) => void): void { + this.emitter.off('loaded', ev); + } + + private emitLoaded() { + this.emitter.emit('loaded', this.loaded); + } + public async close(): Promise { this.closing = true; if (this.focus) {