feat: port TechLog Studio editors

This commit is contained in:
DongHyeonka
2026-08-15 23:41:34 +09:00
parent 887f5e6eb1
commit 5933265975
16 changed files with 879 additions and 3 deletions
@@ -6,7 +6,16 @@ import {
} from "react";
import type { StudioGateway } from "../../application/ports/studio-gateway.ts";
import { StudioContext, type StudioContextValue } from "./use-studio.ts";
import type {
WorkingCopy,
WorkingCopyInput,
} from "../../contracts/studio/contract.ts";
import {
StudioContext,
type StudioContextValue,
type StudioEditorState,
type StudioEditorStatus,
} from "./use-studio.ts";
type StudioProviderProps = Readonly<{
children: ReactNode;
@@ -25,16 +34,41 @@ export function StudioProvider({
navigate = defaultNavigate,
}: StudioProviderProps) {
const [gateway] = useState<StudioGateway>(() => createGateway());
const [editor, setEditor] = useState<StudioEditorState | null>(null);
const [requestAnnouncement, setRequestAnnouncement] = useState("");
const navigateInternal = useCallback((href: string) => navigate(href), [navigate]);
const beginEditor = useCallback((saved: WorkingCopy, draft: WorkingCopyInput) => {
setEditor({ documentId: saved.id, saved, draft, status: "CLEAN" });
}, []);
const updateEditorDraft = useCallback((draft: WorkingCopyInput) => {
setEditor((current) => current ? { ...current, draft, status: "DIRTY" } : current);
}, []);
const setEditorStatus = useCallback((status: StudioEditorStatus) => {
setEditor((current) => current ? { ...current, status } : current);
}, []);
const clearEditor = useCallback(() => setEditor(null), []);
const value = useMemo<StudioContextValue>(
() => ({
gateway,
editor,
requestAnnouncement,
setRequestAnnouncement,
navigateInternal,
beginEditor,
updateEditorDraft,
setEditorStatus,
clearEditor,
}),
[gateway, navigateInternal, requestAnnouncement],
[
beginEditor,
clearEditor,
editor,
gateway,
navigateInternal,
requestAnnouncement,
setEditorStatus,
updateEditorDraft,
],
);
return (