import React, { createContext, useContext } from "react"; import { Hotspot } from "../../types/annotations"; import { ClickEvent, SessionMetadata, SessionStep, SessionStepRecord, TimelineMarker, Transcript, } from "../../lib/api"; export type MediaTab = "video" | "terminal" | "both"; export type ExportKind = "markdown" | "mp4"; export type EditorMode = "edit" | "preview"; export interface ExportFeedback { status: "success" | "error"; kind: ExportKind; path: string | null; message: string; } export interface AutoStepsFeedback { status: "success" | "error"; message: string; } interface EditorContextType { sessionId: string | undefined; metadata: SessionMetadata | null; videoUrl: string | null; terminalUrl: string | null; playing: boolean; setPlaying: (playing: boolean) => void; activeTab: MediaTab; setActiveTab: (tab: MediaTab) => void; hasTerminal: boolean; fps: number; markers: TimelineMarker[]; allHotspots: Hotspot[]; hotspots: Hotspot[]; selectedHotspotId: string | null; setSelectedHotspotId: (id: string | null) => void; editingHotspots: boolean; setEditingHotspots: React.Dispatch>; placingHotspot: boolean; setPlacingHotspot: React.Dispatch>; placingHotspotStyle: Hotspot["style"]; setPlacingHotspotStyle: React.Dispatch>; walkthroughMode: boolean; setWalkthroughMode: (mode: boolean) => void; walkthroughSteps: SessionStep[]; walkthroughLoading: boolean; exporting: boolean; lastExportPath: string | null; exportFeedback: ExportFeedback | null; autoStepsFeedback: AutoStepsFeedback | null; isProcessing: boolean; isAnalyzing: boolean; transcript: Transcript | null; transcribing: boolean; transcriptError: string | null; steps: SessionStepRecord[]; selectedStepId: string | null; selectedStep: SessionStepRecord | null; // Actions togglePlay: () => void; undo: () => void; redo: () => void; canUndo: boolean; canRedo: boolean; startWalkthrough: () => Promise; handleAnalyzeSession: () => Promise; handleGenerateStepsFromActivity: () => void; handleMarkStep: () => Promise; handleTranscribe: () => Promise; handleExportMarkdown: () => Promise; handleExportMp4: (includeChapterCards: boolean) => Promise; clearExportFeedback: () => void; clearAutoStepsFeedback: () => void; handleVideoLoadError: () => void | Promise; handleStageClick: (position: { x: number; y: number }) => void; handleAddHotspot: (hotspot: Hotspot, stepId?: string | null) => void; handleUpdateHotspot: (id: string, updater: (hotspot: Hotspot) => Hotspot) => void; handleDeleteHotspot: (id: string) => void; handleSelectStep: (stepId: string) => void; handleRenameStep: (stepId: string, title: string) => void; updateStepConfig: ( stepId: string, updater: (step: SessionStepRecord) => SessionStepRecord ) => void; moveStepUp: (stepId: string) => void; moveStepDown: (stepId: string) => void; duplicateStep: (stepId: string) => void; deleteStep: (stepId: string) => void; splitSelectedStepAtCurrentFrame: () => void; mergeSelectedStepWithNext: () => void; applyHotspotStylePreset: ( scope: "step" | "session", target: "hotspot" | "callout", patch: { backgroundColor?: string; textColor?: string } ) => void; // Video Hooks State currentFrame: number; currentTime: number; duration: number; totalFrames: number; seekToFrame: (frame: number) => void; seekToTimestamp: (time: number) => void; stepFrames: (frames: number) => void; // UI state editorMode: EditorMode; setEditorMode: (mode: EditorMode) => void; setSharing: (sharing: boolean) => void; // Click highlights clicks: ClickEvent[]; showClickRipples: boolean; setShowClickRipples: (show: boolean) => void; } const EditorContext = createContext(undefined); export const EditorProvider: React.FC<{ value: EditorContextType; children: React.ReactNode }> = ({ value, children, }) => { return {children}; }; export const useEditor = () => { const context = useContext(EditorContext); if (!context) { throw new Error("useEditor must be used within an EditorProvider"); } return context; };