UNPKG

@amityco/ts-sdk-react-native

Version:

Amity Social Cloud Typescript SDK

139 lines (109 loc) 3.21 kB
import { onOffline } from '~/client/utils/onOffline'; import { onOnline } from '~/client/utils/onOnline'; import { SECOND } from '~/utils/constants'; import { createLiveReaction as _createLiveReaction } from '../internalApi/createLiveReaction'; class LiveReactionSyncEngine { private readonly TIMER_INTERVAL_MS = 1 * SECOND; private buffer: (Amity.CreateLiveReactionRequest & { streamId: string })[] = []; private timer: NodeJS.Timer | undefined; private isSyncing = false; private connectionListener: (() => void)[] = []; private isConnected = true; constructor() { this.addConnectionListener(); } startReactionsSync() { if (!this.timer) { this.timer = setInterval(() => { if (this.isConnected) this.syncLiveReactions(); }, this.TIMER_INTERVAL_MS); } } stopReactionsSync() { if (this.timer) { clearInterval(this.timer); this.timer = undefined; } } createLiveReaction(liveReaction: Amity.CreateLiveReactionRequest & { streamId: string }) { this.buffer.push(liveReaction); } private addConnectionListener() { if (this.connectionListener.length > 0) return; this.connectionListener.push( onOnline(() => { this.isConnected = true; }), ); this.connectionListener.push( onOffline(() => { this.isConnected = false; }), ); } private removeConnectionListener() { if (this.connectionListener.length > 0) { this.connectionListener.forEach(listener => listener()); this.connectionListener = []; } } private syncLiveReactions() { if (this.isSyncing) { return; } this.isSyncing = true; const reactions = this.buffer; // Clear buffer this.clearBuffer(); const payloads: Record<string, Amity.CreateLiveReactionRequest[]> = reactions.reduce( (prev: Record<string, Amity.CreateLiveReactionRequest[]>, curr) => { const { streamId, ...rest } = curr; if (!prev[streamId]) { // eslint-disable-next-line no-param-reassign prev[streamId] = [rest]; } else prev[streamId].push(rest); return prev; }, {} as Record<string, Amity.CreateLiveReactionRequest[]>, ); // Call server api `POST /api/v1/reactions/live` to sync live reactions Object.entries(payloads).forEach(([streamId, reactions]) => { _createLiveReaction({ liveStreamId: streamId, reactions, }); }); // After sending request this.isSyncing = false; } private clearBuffer() { this.buffer = []; } // Session Management : SessionComponent onSessionEstablished() { this.startReactionsSync(); this.addConnectionListener(); } onSessionDestroyed() { // Stop timer this.stopReactionsSync(); // Clear buffer this.clearBuffer(); // Reset state this.isSyncing = false; // remove connection listener this.removeConnectionListener(); } onTokenExpired() { this.stopReactionsSync(); } } let instance: LiveReactionSyncEngine; export default { getInstance: () => { if (!instance) { instance = new LiveReactionSyncEngine(); } return instance; }, };