Something went wrong. Try again.
A local-first note taking app
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384import { useCallback, useEffect, useRef, useState } from 'react';
import type { FileSystemProvider } from '../filesystem/types';import type { OpenDocRequest } from '../workspaces/workspace';import { startDocumentOpen } from './documentSlotOpen';import type { DocumentHandle } from './types';
export type DocumentSlotState = | { kind: 'empty' } | { kind: 'loading'; request: OpenDocRequest } | { kind: 'open'; request: OpenDocRequest; handle: DocumentHandle } | { kind: 'error'; request: OpenDocRequest; message: string };
export const emptyDocumentSlot = (): DocumentSlotState => ({ kind: 'empty' });
export type UseDocumentSlotInput = { openRequestId: number; openRequest: OpenDocRequest | null; resolveProvider: (providerId: string) => FileSystemProvider | undefined; /** When false, open intents are ignored (e.g. inactive tiling tiles). */ accepts?: boolean;};
/** * Owns one document slot: open on shell intent, track loading/error/open, * and release handles on close or unmount. */export function useDocumentSlot({ openRequestId, openRequest, resolveProvider, accepts = true,}: UseDocumentSlotInput): { state: DocumentSlotState; close: () => void;} { const [state, setState] = useState<DocumentSlotState>(emptyDocumentSlot); // Seed with the current id so new slots do not replay stale opens. const lastSeenIdRef = useRef(openRequestId); const handleRef = useRef<DocumentHandle | null>(null);
useEffect(() => { if (openRequestId === lastSeenIdRef.current) return; lastSeenIdRef.current = openRequestId;
if (!accepts || !openRequest) return;
const request = openRequest;
return startDocumentOpen(request, resolveProvider, { onLoading: () => setState({ kind: 'loading', request }), onOpen: (handle) => { handleRef.current = handle; setState({ kind: 'open', request, handle }); }, onError: (message) => { handleRef.current = null; setState({ kind: 'error', request, message }); }, takePreviousHandle: () => { const prev = handleRef.current; handleRef.current = null; return prev; }, isStaleHandle: (handle) => handleRef.current !== handle, }); }, [openRequestId, openRequest, resolveProvider, accepts]);
useEffect(() => { return () => { handleRef.current?.release(); handleRef.current = null; }; }, []);
const close = useCallback(() => { handleRef.current?.release(); handleRef.current = null; setState(emptyDocumentSlot()); }, []);
return { state, close };}