myagent10101's picture
feat: Complete CodeSync collaborative coding platform
8f9c4ef verified
import { create } from 'zustand';
import type { RoomFile, ProgrammingLanguage, EditorTab } from '../types';
interface EditorState {
files: RoomFile[];
activeFileId: string | null;
tabs: EditorTab[];
theme: 'vs-dark' | 'light' | 'hc-black';
fontSize: number;
wordWrap: 'on' | 'off' | 'bounded';
minimap: boolean;
lineNumbers: 'on' | 'off' | 'relative';
isExecuting: boolean;
output: string;
executionLanguage: ProgrammingLanguage;
setFiles: (files: RoomFile[]) => void;
setActiveFile: (fileId: string) => void;
openTab: (file: RoomFile) => void;
closeTab: (fileId: string) => void;
markTabDirty: (fileId: string, isDirty: boolean) => void;
setTheme: (theme: 'vs-dark' | 'light' | 'hc-black') => void;
setFontSize: (size: number) => void;
setWordWrap: (wrap: 'on' | 'off' | 'bounded') => void;
setMinimap: (enabled: boolean) => void;
setExecuting: (executing: boolean) => void;
setOutput: (output: string) => void;
appendOutput: (chunk: string) => void;
clearOutput: () => void;
setExecutionLanguage: (lang: ProgrammingLanguage) => void;
}
export const useEditorStore = create<EditorState>((set) => ({
files: [], activeFileId: null, tabs: [],
theme: 'vs-dark', fontSize: 14, wordWrap: 'on', minimap: true, lineNumbers: 'on',
isExecuting: false, output: '', executionLanguage: 'javascript',
setFiles: (files) => set({ files }),
setActiveFile: (fileId) => set((s) => ({ activeFileId: fileId, tabs: s.tabs.map((t) => ({ ...t, isActive: t.fileId === fileId })) })),
openTab: (file) => set((s) => {
if (s.tabs.find((t) => t.fileId === file.id)) {
return { activeFileId: file.id, tabs: s.tabs.map((t) => ({ ...t, isActive: t.fileId === file.id })) };
}
return {
activeFileId: file.id,
tabs: [...s.tabs.map((t) => ({ ...t, isActive: false })), { id: file.id, fileId: file.id, name: file.name, path: file.path, language: file.language, isDirty: false, isActive: true }],
};
}),
closeTab: (fileId) => set((s) => {
const filtered = s.tabs.filter((t) => t.fileId !== fileId);
return { tabs: filtered, activeFileId: s.activeFileId === fileId ? (filtered[filtered.length - 1]?.fileId || null) : s.activeFileId };
}),
markTabDirty: (fileId, isDirty) => set((s) => ({ tabs: s.tabs.map((t) => t.fileId === fileId ? { ...t, isDirty } : t) })),
setTheme: (theme) => set({ theme }),
setFontSize: (fontSize) => set({ fontSize }),
setWordWrap: (wordWrap) => set({ wordWrap }),
setMinimap: (minimap) => set({ minimap }),
setExecuting: (isExecuting) => set({ isExecuting }),
setOutput: (output) => set({ output }),
appendOutput: (chunk) => set((s) => ({ output: s.output + chunk })),
clearOutput: () => set({ output: '' }),
setExecutionLanguage: (executionLanguage) => set({ executionLanguage }),
}));