From bcdd72317cce2dc8082cb7e307ad49d75ed445a9 Mon Sep 17 00:00:00 2001 From: cfngc4594 Date: Tue, 13 May 2025 16:31:38 +0800 Subject: [PATCH] feat(store): add problem editor state management - Create problem-editor store with Zustand - Manage editor state including problem, language, value and path - Implement localStorage persistence for editor content - Provide utility functions for language and value retrieval --- src/stores/problem-editor.ts | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/stores/problem-editor.ts diff --git a/src/stores/problem-editor.ts b/src/stores/problem-editor.ts new file mode 100644 index 0000000..0c54e71 --- /dev/null +++ b/src/stores/problem-editor.ts @@ -0,0 +1,91 @@ +import { create } from "zustand"; +import type { editor } from "monaco-editor"; +import { LANGUAGES } from "@/config/language"; +import { Language, type Template } from "@/generated/client"; + +type Problem = { + problemId: string; + templates: Template[]; +}; + +type ProblemEditorState = { + problem: Problem | null; + language: Language; + value: string; + path: string; + editor: editor.IStandaloneCodeEditor | null; +}; + +type ProblemEditorAction = { + setProblem: (problemId: string, templates: Template[]) => void; + setLanguage: (language: Language) => void; + setValue: (value: string) => void; + setPath: (path: string) => void; + setEditor: (editor: editor.IStandaloneCodeEditor) => void; +}; + +type ProblemEditorStore = ProblemEditorState & ProblemEditorAction; + +export const useProblemEditorStore = create((set, get) => ({ + problem: null, + language: Language.c, + value: "", + path: "", + editor: null, + setProblem: (problemId, templates) => { + const language = getLanguage(problemId); + const value = getValue(problemId, language, templates); + const path = getPath(problemId, language); + set({ problem: { problemId, templates }, language, value, path }); + }, + setLanguage: (newLanguage) => { + const { problem, language, value } = get(); + if (problem) { + localStorage.setItem(`${problem.problemId}_${language}`, value); + localStorage.setItem(`${problem.problemId}_language`, newLanguage); + } + localStorage.setItem("global_language", newLanguage); + const newValue = problem + ? getValue(problem.problemId, newLanguage, problem.templates) + : ""; + const newPath = problem ? getPath(problem.problemId, newLanguage) : ""; + set({ language: newLanguage, value: newValue, path: newPath }); + }, + setValue: (value) => { + const { problem, language } = get(); + if (problem) { + localStorage.setItem(`${problem.problemId}_${language}`, value); + } + set({ value }); + }, + setPath: (path) => set({ path }), + setEditor: (editor) => set({ editor }), +})); + +const getStoredItem = ( + key: string, + validValues?: T[] +): T | null => { + const stored = localStorage.getItem(key); + return stored && (!validValues || validValues.includes(stored as T)) + ? (stored as T) + : null; +}; + +const getLanguage = (problemId: string): Language => + getStoredItem(`${problemId}_language`, LANGUAGES) ?? + getStoredItem("global_language", LANGUAGES) ?? + Language.c; + +const getValue = ( + problemId: string, + language: Language, + templates: Template[] +): string => + getStoredItem(`${problemId}_${language}`) ?? + templates.find((t) => t.language === language)?.content ?? + ""; + +export const getPath = (problemId: string, language: Language) => { + return `file:///${problemId}/main.${language}`; +};