import { useCallback, useMemo, useState } from "react"; import { MonacoEditor } from "../components/editor/MonacoEditor"; import { EditorTabs } from "../components/editor/EditorTabs"; import { GffEditor } from "../components/gff/GffEditor"; import { ItemEditor } from "../components/gff/ItemEditor"; import { CreatureEditor } from "../components/gff/CreatureEditor"; import { AreaEditor } from "../components/gff/AreaEditor"; import { DialogEditor } from "../components/gff/DialogEditor"; import { FileCode, Code2, Eye } from "lucide-react"; const GFF_EXTENSIONS = [".uti.json", ".utc.json", ".are.json", ".dlg.json", ".utp.json", ".utm.json"]; type GffEditorType = "uti" | "utc" | "are" | "dlg" | "generic" | null; function isGffFile(tabKey: string): boolean { return GFF_EXTENSIONS.some((ext) => tabKey.endsWith(ext)); } function getGffEditorType(tabKey: string): GffEditorType { if (tabKey.endsWith(".uti.json")) return "uti"; if (tabKey.endsWith(".utc.json")) return "utc"; if (tabKey.endsWith(".are.json")) return "are"; if (tabKey.endsWith(".dlg.json")) return "dlg"; if (tabKey.endsWith(".utp.json") || tabKey.endsWith(".utm.json")) return "generic"; return null; } function repoFromTabKey(tabKey: string): string { const idx = tabKey.indexOf(":"); return idx > 0 ? tabKey.slice(0, idx) : ""; } function filePathFromTabKey(tabKey: string): string { const idx = tabKey.indexOf(":"); return idx > 0 ? tabKey.slice(idx + 1) : tabKey; } interface EditorProps { editorState: ReturnType; workspacePath?: string; } export function Editor({ editorState, workspacePath }: EditorProps) { const { openTabs, activeTab, dirtyFiles, selectTab, closeFile, updateContent, getContent, markClean, } = editorState; const [editorModes, setEditorModes] = useState>({}); const tabs = useMemo( () => openTabs.map((path: string) => ({ path, dirty: dirtyFiles.has(path), })), [openTabs, dirtyFiles], ); const activeContent = activeTab ? (getContent(activeTab) ?? "") : ""; const activeFilePath = activeTab ? filePathFromTabKey(activeTab) : ""; const activeRepo = activeTab ? repoFromTabKey(activeTab) : ""; const isActiveGff = activeTab ? isGffFile(activeTab) : false; const activeMode = activeTab ? editorModes[activeTab] ?? (isActiveGff ? "visual" : "raw") : "raw"; const handleChange = useCallback( (value: string) => { if (activeTab) { updateContent(activeTab, value); } }, [activeTab, updateContent], ); const handleSwitchToRaw = useCallback(() => { if (activeTab) { setEditorModes((prev) => ({ ...prev, [activeTab]: "raw" })); } }, [activeTab]); const handleSwitchToVisual = useCallback(() => { if (activeTab) { setEditorModes((prev) => ({ ...prev, [activeTab]: "visual" })); } }, [activeTab]); const handleGffSave = useCallback( (newContent: string) => { if (activeTab) { updateContent(activeTab, newContent); markClean(activeTab); } }, [activeTab, updateContent, markClean], ); const renderEditor = () => { if (!activeTab) { return (

Open a file from the File Explorer to start editing

); } if (isActiveGff && activeMode === "visual") { const editorType = getGffEditorType(activeTab); const commonProps = { key: activeTab, repo: activeRepo, filePath: activeFilePath, content: activeContent, onSave: handleGffSave, onSwitchToRaw: handleSwitchToRaw, }; switch (editorType) { case "uti": return ; case "utc": return ; case "are": return ; case "dlg": return ; default: return ; } } return (
{isActiveGff && activeMode === "raw" && (
)}
); }; return (
{renderEditor()}
); }