88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import React from 'react';
|
|
import { useKeyboardShortcuts } from '@/hooks/useKeyboardShortcuts';
|
|
import { usePwaManifestSync } from '@/hooks/usePwaManifestSync';
|
|
import { useQueuedMessageAutoSend } from '@/hooks/useQueuedMessageAutoSend';
|
|
import { useSessionAutoCleanup } from '@/hooks/useSessionAutoCleanup';
|
|
import { useWindowControlsOverlayLayout } from '@/hooks/useWindowControlsOverlayLayout';
|
|
import { setOptimisticRefs } from '@/sync/session-actions';
|
|
import { markSessionViewed } from '@/sync/notification-store';
|
|
import { setExternallyViewedSession } from '@/sync/sync-context';
|
|
import { useSync } from '@/sync/use-sync';
|
|
|
|
const MINI_CHAT_PRESENCE_CHANNEL = 'openchamber:mini-chat-presence';
|
|
|
|
type MiniChatPresenceMessage = {
|
|
type?: string;
|
|
sessionId?: string;
|
|
directory?: string;
|
|
viewed?: boolean;
|
|
};
|
|
|
|
const SyncOptimisticBridge: React.FC = () => {
|
|
const sync = useSync();
|
|
const addRef = React.useRef(sync.optimistic.add);
|
|
const removeRef = React.useRef(sync.optimistic.remove);
|
|
const confirmRef = React.useRef(sync.optimistic.confirm);
|
|
addRef.current = sync.optimistic.add;
|
|
removeRef.current = sync.optimistic.remove;
|
|
confirmRef.current = sync.optimistic.confirm;
|
|
|
|
React.useEffect(() => {
|
|
setOptimisticRefs(
|
|
(input) => addRef.current(input),
|
|
(input) => removeRef.current(input),
|
|
(input) => confirmRef.current(input),
|
|
);
|
|
}, []);
|
|
|
|
return null;
|
|
};
|
|
|
|
const MiniChatPresenceBridge: React.FC = () => {
|
|
React.useEffect(() => {
|
|
if (typeof BroadcastChannel === 'undefined') return;
|
|
|
|
const channel = new BroadcastChannel(MINI_CHAT_PRESENCE_CHANNEL);
|
|
channel.onmessage = (event) => {
|
|
const data = event.data as MiniChatPresenceMessage | null;
|
|
if (data?.type !== 'mini-chat-session-presence' || !data.sessionId || !data.directory) {
|
|
return;
|
|
}
|
|
|
|
const viewed = data.viewed !== false;
|
|
setExternallyViewedSession(data.directory, data.sessionId, viewed);
|
|
if (viewed) {
|
|
markSessionViewed(data.sessionId);
|
|
}
|
|
};
|
|
|
|
return () => channel.close();
|
|
}, []);
|
|
|
|
return null;
|
|
};
|
|
|
|
export function SyncRuntimeEffects({ embeddedBackgroundWorkEnabled }: {
|
|
embeddedBackgroundWorkEnabled: boolean;
|
|
}) {
|
|
useSessionAutoCleanup(embeddedBackgroundWorkEnabled);
|
|
useQueuedMessageAutoSend(embeddedBackgroundWorkEnabled);
|
|
|
|
return <SyncOptimisticBridge />;
|
|
}
|
|
|
|
export function SyncAppEffects({ embeddedBackgroundWorkEnabled }: {
|
|
embeddedBackgroundWorkEnabled: boolean;
|
|
}) {
|
|
usePwaManifestSync();
|
|
useWindowControlsOverlayLayout();
|
|
useKeyboardShortcuts();
|
|
|
|
return (
|
|
<>
|
|
<SyncRuntimeEffects embeddedBackgroundWorkEnabled={embeddedBackgroundWorkEnabled} />
|
|
<MiniChatPresenceBridge />
|
|
</>
|
|
);
|
|
}
|