import { useMemo } from 'react'; import { stringify } from 'uuid'; import { CRDTOperation, CRDTOperationData, useLibraryQuery, useLibrarySubscription } from '@sd/client'; import { useRouteTitle } from '~/hooks/useRouteTitle'; type MessageGroup = { model: string; id: string; messages: { data: CRDTOperationData; timestamp: number }[]; }; export const Component = () => { useRouteTitle('Sync'); const messages = useLibraryQuery(['sync.messages']); useLibrarySubscription(['sync.newMessage'], { onData: () => messages.refetch() }); const groups = useMemo( () => (messages.data && calculateGroups(messages.data)) || [], [messages] ); return ( ); }; const OperationGroup = ({ group }: { group: MessageGroup }) => { const [header, contents] = (() => { const header = (
{group.model} {group.id}
); const contents = ( ); return [header, contents]; })(); return (
{header} {contents}
); }; function calculateGroups(messages: CRDTOperation[]) { return messages.reduce((acc, op) => { const { data } = op; const id = stringify((op.record_id as any).pub_id); const latest = (() => { const latest = acc[acc.length - 1]; if (!latest || latest.model !== op.model || latest.id !== id) { const group: MessageGroup = { model: op.model, id, messages: [] }; acc.push(group); return group; } else return latest; })(); latest.messages.push({ data, timestamp: op.timestamp }); return acc; }, []); }