| 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 }), |
| })); |
|
|