diff --git a/src/hooks/use-problem-editor.ts b/src/hooks/use-problem-editor.ts new file mode 100644 index 0000000..34b4e2b --- /dev/null +++ b/src/hooks/use-problem-editor.ts @@ -0,0 +1,106 @@ +import { getPath } from "@/lib/utils"; +import { EditorLanguage } from "@prisma/client"; +import { useCallback, useEffect, useMemo } from "react"; +import { useProblemEditorStoreInstance } from "@/providers/problem-editor-provider"; + +/** + * Generates a unique localStorage key for storing the editor language of a problem. + */ +const getProblemLangStorageKey = (problemId: string) => `lang_${problemId}`; + +/** + * Generates a unique localStorage key for storing the editor content of a problem. + */ +const getProblemValueStorageKey = (problemId: string) => `value_${problemId}`; + +/** + * Retrieves the stored editor language for a specific problem. + * If no value is found, it falls back to the global editor language. + */ +const getStoredProblemLang = (problemId: string, globalLang: EditorLanguage) => + (localStorage.getItem(getProblemLangStorageKey(problemId)) as EditorLanguage) ?? globalLang; + +/** + * Retrieves the stored editor content for a specific problem. + * If no value is found, it falls back to the default template. + */ +const getStoredProblemValue = (problemId: string, defaultValue: string) => + localStorage.getItem(getProblemValueStorageKey(problemId)) ?? defaultValue; + +export const useProblemEditor = () => { + const { + globalLang, + currentLang, + currentValue, + setGlobalLang, + setCurrentLang, + setCurrentValue, + problemId, + templates, + editorLanguageConfigs, + languageServerConfigs, + } = useProblemEditorStoreInstance().getState(); + + const currentTemplate = useMemo(() => { + return templates.find((t) => t.language === currentLang)?.template || ""; + }, [templates, currentLang]); + + const currentEditorLanguageConfig = useMemo( + () => editorLanguageConfigs.find((c) => c.language === currentLang), + [editorLanguageConfigs, currentLang] + ); + + const currentLanguageServerConfig = useMemo( + () => languageServerConfigs.find((c) => c.language === currentLang), + [languageServerConfigs, currentLang] + ); + + const currentPath = useMemo(() => { + return currentEditorLanguageConfig ? getPath(currentEditorLanguageConfig) : ""; + }, [currentEditorLanguageConfig]); + + useEffect(() => { + const storedLang = getStoredProblemLang(problemId, globalLang); + setCurrentLang(storedLang); + + const storedValue = getStoredProblemValue(problemId, currentTemplate); + setCurrentValue(storedValue); + }, [problemId, globalLang, currentTemplate, setCurrentLang, setCurrentValue]); + + const changeLang = useCallback( + (newLang: EditorLanguage) => { + if (!problemId || newLang === currentLang) return; + + localStorage.setItem(getProblemLangStorageKey(problemId), newLang); + setCurrentLang(newLang); + setGlobalLang(newLang); + }, + [problemId, currentLang, setCurrentLang, setGlobalLang] + ); + + const changeValue = useCallback( + (newValue: string) => { + if (!problemId || newValue === currentValue) return; + + localStorage.setItem(getProblemValueStorageKey(problemId), newValue); + setCurrentValue(newValue); + }, + [problemId, currentValue, setCurrentValue] + ); + + return { + globalLang, + currentLang, + currentValue, + problemId, + templates, + editorLanguageConfigs, + languageServerConfigs, + currentTemplate, + currentEditorLanguageConfig, + currentLanguageServerConfig, + currentPath, + changeLang, + changeValue, + }; +}; diff --git a/src/hooks/useProblemEditor.ts b/src/hooks/useProblemEditor.ts deleted file mode 100644 index ce8a78c..0000000 --- a/src/hooks/useProblemEditor.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { EditorLanguage } from "@prisma/client"; -import { useEffect, useState, useCallback } from "react"; -import { useProblemEditorStore } from "@/store/useProblemEditorStore"; - -/** - * Generates a unique localStorage key for storing the editor language of a problem. - */ -const getProblemLangStorageKey = (problemId: string) => `${problemId}_lang`; - -/** - * Retrieves the stored editor language for a specific problem. - * If no value is found, it falls back to the global editor language. - */ -const getStoredProblemLang = (problemId: string, globalEditorLanguage: EditorLanguage): EditorLanguage => { - return (localStorage.getItem(getProblemLangStorageKey(problemId)) as EditorLanguage) ?? globalEditorLanguage; -}; - -/** - * Hook for managing the editor language of a specific problem. - */ -export const useProblemEditor = (problemId: string) => { - const { globalEditorLanguage, setGlobalEditorLanguage } = useProblemEditorStore(); - - // Local state to track the current editor language for the problem - const [currentLang, setCurrentLang] = useState(() => - getStoredProblemLang(problemId, globalEditorLanguage) - ); - - // Update local state when the problemId or global editor language changes - useEffect(() => { - setCurrentLang(getStoredProblemLang(problemId, globalEditorLanguage)); - }, [problemId, globalEditorLanguage]); - - /** - * Changes the editor language for the current problem. - * Updates both global state and local storage. - */ - const changeProblemLang = useCallback( - (language: EditorLanguage) => { - // Update global editor language state - setGlobalEditorLanguage(language); - - // Persist the selected language in localStorage - localStorage.setItem(getProblemLangStorageKey(problemId), language); - - // Update local state - setCurrentLang(language); - }, - [setGlobalEditorLanguage] - ); - - return { currentLang, changeProblemLang }; -};