0.4.0 convex及界面修改
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
"use client";
|
||||
|
||||
import { create } from "zustand";
|
||||
|
||||
export type ThemeMode = "system" | "light" | "dark";
|
||||
|
||||
type PersistedPreferences = {
|
||||
theme: ThemeMode;
|
||||
showStructure: boolean;
|
||||
spellCheck: boolean;
|
||||
flightMode: boolean;
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "mnote:preferences:v1";
|
||||
|
||||
const loadPersisted = (): PersistedPreferences | null => {
|
||||
if (typeof window === "undefined") return null;
|
||||
try {
|
||||
const raw = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw) as Partial<PersistedPreferences>;
|
||||
const theme = parsed.theme === "light" || parsed.theme === "dark" || parsed.theme === "system" ? parsed.theme : "system";
|
||||
return {
|
||||
theme,
|
||||
showStructure: typeof parsed.showStructure === "boolean" ? parsed.showStructure : false,
|
||||
spellCheck: typeof parsed.spellCheck === "boolean" ? parsed.spellCheck : false,
|
||||
flightMode: typeof parsed.flightMode === "boolean" ? parsed.flightMode : false,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const persist = (value: PersistedPreferences) => {
|
||||
if (typeof window === "undefined") return;
|
||||
try {
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(value));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
};
|
||||
|
||||
interface AppPreferencesState extends PersistedPreferences {
|
||||
hydrated: boolean;
|
||||
hydrate: () => void;
|
||||
setTheme: (theme: ThemeMode) => void;
|
||||
setShowStructure: (showStructure: boolean) => void;
|
||||
setSpellCheck: (spellCheck: boolean) => void;
|
||||
setFlightMode: (flightMode: boolean) => void;
|
||||
}
|
||||
|
||||
export const useAppPreferencesStore = create<AppPreferencesState>((set, get) => ({
|
||||
hydrated: false,
|
||||
theme: "system",
|
||||
showStructure: false,
|
||||
spellCheck: false,
|
||||
flightMode: false,
|
||||
hydrate: () => {
|
||||
const current = get();
|
||||
if (current.hydrated) return;
|
||||
const persisted = loadPersisted();
|
||||
if (persisted) {
|
||||
set({ ...persisted, hydrated: true });
|
||||
} else {
|
||||
set({ hydrated: true });
|
||||
}
|
||||
},
|
||||
setTheme: (theme) =>
|
||||
set((state) => {
|
||||
const next = { ...state, theme };
|
||||
persist({
|
||||
theme: next.theme,
|
||||
showStructure: next.showStructure,
|
||||
spellCheck: next.spellCheck,
|
||||
flightMode: next.flightMode,
|
||||
});
|
||||
return next;
|
||||
}),
|
||||
setShowStructure: (showStructure) =>
|
||||
set((state) => {
|
||||
const next = { ...state, showStructure };
|
||||
persist({
|
||||
theme: next.theme,
|
||||
showStructure: next.showStructure,
|
||||
spellCheck: next.spellCheck,
|
||||
flightMode: next.flightMode,
|
||||
});
|
||||
return next;
|
||||
}),
|
||||
setSpellCheck: (spellCheck) =>
|
||||
set((state) => {
|
||||
const next = { ...state, spellCheck };
|
||||
persist({
|
||||
theme: next.theme,
|
||||
showStructure: next.showStructure,
|
||||
spellCheck: next.spellCheck,
|
||||
flightMode: next.flightMode,
|
||||
});
|
||||
return next;
|
||||
}),
|
||||
setFlightMode: (flightMode) =>
|
||||
set((state) => {
|
||||
const next = { ...state, flightMode };
|
||||
persist({
|
||||
theme: next.theme,
|
||||
showStructure: next.showStructure,
|
||||
spellCheck: next.spellCheck,
|
||||
flightMode: next.flightMode,
|
||||
});
|
||||
return next;
|
||||
}),
|
||||
}));
|
||||
Reference in New Issue
Block a user