refactor(useProblemEditor): update hooks to support language-specific localStorage keys

This commit is contained in:
cfngc4594 2025-03-20 15:11:23 +08:00
parent 458bdfbf42
commit cc76648437

View File

@ -1,33 +1,43 @@
import { getPath } from "@/lib/utils"; import { getPath } from "@/lib/utils";
import { EditorLanguage } from "@prisma/client"; import { EditorLanguage } from "@prisma/client";
import { useCallback, useEffect, useMemo } from "react"; import { useCallback, useEffect, useMemo } from "react";
import { useMonacoTheme } from "@/hooks/use-monaco-theme";
import { useProblemEditorStore } from "@/providers/problem-editor-provider"; import { useProblemEditorStore } from "@/providers/problem-editor-provider";
/** /**
* Generates a unique localStorage key for storing the editor language of a problem. * Generates a localStorage key for storing the editor language of a problem.
* Format: "lang_{problemId}"
*/ */
const getProblemLangStorageKey = (problemId: string) => `lang_${problemId}`; const getProblemLangStorageKey = (problemId: string) => `lang_${problemId}`;
/** /**
* Generates a unique localStorage key for storing the editor content of a problem. * Generates a localStorage key for storing the editor content of a problem for a specific language.
* Format: "{language}_{problemId}"
*/ */
const getProblemValueStorageKey = (problemId: string) => `value_${problemId}`; const getProblemValueStorageKey = (problemId: string, language: EditorLanguage) =>
`${language}_${problemId}`;
/** /**
* Retrieves the stored editor language for a specific problem. * Retrieves the stored editor language for a specific problem.
* If no value is found, it falls back to the global editor language. * Falls back to the global language if no stored value is found.
*/ */
const getStoredProblemLang = (problemId: string, globalLang: EditorLanguage) => const getStoredProblemLang = (problemId: string, globalLang: EditorLanguage) =>
(localStorage.getItem(getProblemLangStorageKey(problemId)) as EditorLanguage) ?? globalLang; (localStorage.getItem(getProblemLangStorageKey(problemId)) as EditorLanguage) ?? globalLang;
/** /**
* Retrieves the stored editor content for a specific problem. * Retrieves the stored editor content for a specific problem and language.
* If no value is found, it falls back to the default template. * Falls back to the default template if no stored value is found.
*/ */
const getStoredProblemValue = (problemId: string, defaultValue: string) => const getStoredProblemValue = (
localStorage.getItem(getProblemValueStorageKey(problemId)) ?? defaultValue; problemId: string,
defaultValue: string,
language: EditorLanguage
) => localStorage.getItem(getProblemValueStorageKey(problemId, language)) ?? defaultValue;
export const useProblemEditor = () => { export const useProblemEditor = () => {
const { currentTheme } = useMonacoTheme();
const hydrated = useProblemEditorStore((state) => state.hydrated);
const editor = useProblemEditorStore((state) => state.editor); const editor = useProblemEditorStore((state) => state.editor);
const globalLang = useProblemEditorStore((state) => state.globalLang); const globalLang = useProblemEditorStore((state) => state.globalLang);
const currentLang = useProblemEditorStore((state) => state.currentLang); const currentLang = useProblemEditorStore((state) => state.currentLang);
@ -41,6 +51,7 @@ export const useProblemEditor = () => {
const editorLanguageConfigs = useProblemEditorStore((state) => state.editorLanguageConfigs); const editorLanguageConfigs = useProblemEditorStore((state) => state.editorLanguageConfigs);
const languageServerConfigs = useProblemEditorStore((state) => state.languageServerConfigs); const languageServerConfigs = useProblemEditorStore((state) => state.languageServerConfigs);
// Get the default template for the current language from the templates list
const currentTemplate = useMemo(() => { const currentTemplate = useMemo(() => {
return templates.find((t) => t.language === currentLang)?.template || ""; return templates.find((t) => t.language === currentLang)?.template || "";
}, [templates, currentLang]); }, [templates, currentLang]);
@ -59,18 +70,21 @@ export const useProblemEditor = () => {
return currentEditorLanguageConfig ? getPath(currentEditorLanguageConfig) : ""; return currentEditorLanguageConfig ? getPath(currentEditorLanguageConfig) : "";
}, [currentEditorLanguageConfig]); }, [currentEditorLanguageConfig]);
// On initialization, load the stored language and corresponding code content
useEffect(() => { useEffect(() => {
const storedLang = getStoredProblemLang(problemId, globalLang); const storedLang = getStoredProblemLang(problemId, globalLang);
setCurrentLang(storedLang); setCurrentLang(storedLang);
const storedValue = getStoredProblemValue(problemId, currentTemplate); const storedValue = getStoredProblemValue(problemId, currentTemplate, storedLang);
setCurrentValue(storedValue); setCurrentValue(storedValue);
}, [problemId, globalLang, currentTemplate, setCurrentLang, setCurrentValue]); }, [problemId, globalLang, currentTemplate, setCurrentLang, setCurrentValue]);
// Change the language and update localStorage and state accordingly
const changeLang = useCallback( const changeLang = useCallback(
(newLang: EditorLanguage) => { (newLang: EditorLanguage) => {
if (!problemId || newLang === currentLang) return; if (!problemId || newLang === currentLang) return;
// Update the stored language in localStorage
localStorage.setItem(getProblemLangStorageKey(problemId), newLang); localStorage.setItem(getProblemLangStorageKey(problemId), newLang);
setCurrentLang(newLang); setCurrentLang(newLang);
setGlobalLang(newLang); setGlobalLang(newLang);
@ -78,17 +92,19 @@ export const useProblemEditor = () => {
[problemId, currentLang, setCurrentLang, setGlobalLang] [problemId, currentLang, setCurrentLang, setGlobalLang]
); );
// Update the stored code content when the editor value changes, specific to the current language
const changeValue = useCallback( const changeValue = useCallback(
(newValue: string) => { (newValue: string) => {
if (!problemId || newValue === currentValue) return; if (!problemId || newValue === currentValue) return;
localStorage.setItem(getProblemValueStorageKey(problemId), newValue); localStorage.setItem(getProblemValueStorageKey(problemId, currentLang), newValue);
setCurrentValue(newValue); setCurrentValue(newValue);
}, },
[problemId, currentValue, setCurrentValue] [problemId, currentValue, currentLang, setCurrentValue]
); );
return { return {
hydrated,
editor, editor,
setEditor, setEditor,
globalLang, globalLang,
@ -102,6 +118,7 @@ export const useProblemEditor = () => {
currentEditorLanguageConfig, currentEditorLanguageConfig,
currentLanguageServerConfig, currentLanguageServerConfig,
currentPath, currentPath,
currentTheme,
changeLang, changeLang,
changeValue, changeValue,
}; };