Skip to content

Commit e3a3610

Browse files
committed
fix: save bug when setting
1 parent 542aaad commit e3a3610

3 files changed

Lines changed: 95 additions & 90 deletions

File tree

src/layouts/default.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import Sidebar from "@/components/sidebar/Sidebar.tsx";
1616
import { items, SidebarKeys } from "@/components/sidebar/Items.tsx";
1717
import { ThemeSwitch } from "@/components/button/ThemeSwitch.tsx";
1818
import { useSidebarStore } from "@/store/useSidebarStore";
19-
import { SettingsState, useSettingsStore } from "@/store/useSettingsStore";
20-
import { storage } from "@/lib/indexedDBStore";
19+
import { useSettingsStore } from "@/store/useSettingsStore";
2120
import { useTabStore } from "@/store/useTabStore";
2221
import { getFontSizeConfig } from "@/styles/fontSize";
2322

@@ -27,7 +26,6 @@ function RootLayout({
2726
children: React.ReactNode;
2827
}) {
2928
const sidebarStore = useSidebarStore();
30-
const { setSettings } = useSettingsStore();
3129
const { initTab } = useTabStore();
3230
const navigate = useNavigate();
3331
const location = useLocation();
@@ -64,18 +62,19 @@ function RootLayout({
6462

6563
useEffect(() => {
6664
const init = async () => {
67-
const settings = await storage.getItem<SettingsState>("settings");
65+
// 先同步设置数据到 store(如果有的话)
66+
await useSettingsStore.getState().syncSettingsStore();
6867

69-
if (!settings) {
70-
initTab();
68+
// 获取同步后的设置状态
69+
const editDataSaveLocal = useSettingsStore.getState().editDataSaveLocal;
70+
const expandSidebar = useSettingsStore.getState().expandSidebar;
7171

72-
return;
73-
}
74-
setSettings(settings);
75-
if (settings.editDataSaveLocal) {
76-
setIsCollapsed(!settings.expandSidebar);
72+
if (editDataSaveLocal) {
73+
// 如果启用了本地存储,同步侧边栏状态
74+
setIsCollapsed(!expandSidebar);
7775
await sidebarStore.syncSidebarStore();
7876
} else {
77+
// 如果未启用本地存储,初始化默认标签页
7978
initTab();
8079
}
8180
};

src/pages/indexPage.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import MonacoJsonEditor, {
1111
MonacoJsonEditorRef,
1212
} from "@/components/monacoEditor/MonacoJsonEditor.tsx";
1313
import { useSidebarStore } from "@/store/useSidebarStore";
14+
import { useSettingsStore } from "@/store/useSettingsStore";
1415
// eslint-disable-next-line import/order
1516
import VanillaJsonEditor, {
1617
VanillaJsonEditorRef,
@@ -24,9 +25,6 @@ import MonacoDiffOperationBar, {
2425
MonacoDiffOperationBarRef,
2526
} from "@/components/monacoEditor/operationBar/MonacoDiffOperationBar.tsx";
2627
import MonacoOperationBar from "@/components/monacoEditor/operationBar/MonacoOperationBar.tsx";
27-
import { SettingsState } from "@/store/useSettingsStore";
28-
import { storage } from "@/lib/indexedDBStore";
29-
3028
import "@/styles/index.css";
3129
import { SidebarKeys } from "@/components/sidebar/Items.tsx";
3230
import JsonTableView, {
@@ -503,9 +501,12 @@ export default function IndexPage() {
503501

504502
useLayoutEffect(() => {
505503
const init = async () => {
506-
const settings = await storage.getItem<SettingsState>("settings");
504+
// 先同步设置数据到 store
505+
await useSettingsStore.getState().syncSettingsStore();
507506

508-
if (settings?.editDataSaveLocal) {
507+
// 然后检查是否需要同步标签页数据
508+
// 使用 getState() 获取最新状态,确保使用同步后的值
509+
if (useSettingsStore.getState().editDataSaveLocal) {
509510
await syncTabStore();
510511
}
511512
};

src/store/useSettingsStore.ts

Lines changed: 79 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// src/store/settingsStore.ts
1+
// useSettingsStore.ts
22
import { create } from "zustand";
3-
import { devtools } from "zustand/middleware";
3+
import { devtools, subscribeWithSelector } from "zustand/middleware";
44

55
import { storage } from "@/lib/indexedDBStore";
66

@@ -10,11 +10,18 @@ export type ChatStyle = "bubble" | "document";
1010
// 定义字体大小类型
1111
export type FontSize = "small" | "medium" | "large";
1212

13-
// 全局设置状态接口,包含解码器配置
13+
// 定义 Monaco 编辑器 CDN 类型
14+
export type MonacoEditorCDN = "local" | "cdn";
15+
16+
// 全局设置状态接口
1417
export interface SettingsState {
18+
// 数据持久化设置
1519
editDataSaveLocal: boolean;
20+
// 侧边栏展开状态
1621
expandSidebar: boolean;
17-
monacoEditorCDN: "local" | "cdn";
22+
// Monaco 编辑器 CDN 配置
23+
monacoEditorCDN: MonacoEditorCDN;
24+
// 聊天窗口样式
1825
chatStyle: ChatStyle;
1926
// 字体大小设置
2027
fontSize: FontSize;
@@ -28,92 +35,90 @@ export interface SettingsState {
2835
// 快捷键设置
2936
newTabShortcut: string;
3037
closeTabShortcut: string;
38+
39+
// Actions
3140
setEditDataSaveLocal: (value: boolean) => void;
3241
setExpandSidebar: (value: boolean) => void;
33-
setMonacoEditorCDN: (value: "local" | "cdn") => void;
42+
setMonacoEditorCDN: (value: MonacoEditorCDN) => void;
3443
setChatStyle: (value: ChatStyle) => void;
35-
// 字体大小setter方法
3644
setFontSize: (value: FontSize) => void;
37-
// 解码器setter方法
3845
setTimestampDecoderEnabled: (value: boolean) => void;
3946
setBase64DecoderEnabled: (value: boolean) => void;
4047
setUnicodeDecoderEnabled: (value: boolean) => void;
4148
setUrlDecoderEnabled: (value: boolean) => void;
42-
// 编辑器默认设置setter方法
4349
setDefaultIndentSize: (value: number) => void;
44-
// 快捷键setter方法
4550
setNewTabShortcut: (value: string) => void;
4651
setCloseTabShortcut: (value: string) => void;
47-
setSettings: (settings: SettingsState) => void;
52+
setSettings: (settings: Partial<SettingsState>) => void;
53+
syncSettingsStore: () => Promise<void>;
4854
}
4955

5056
export const useSettingsStore = create<SettingsState>()(
51-
devtools(
52-
(set) => ({
53-
// 初始状态
54-
editDataSaveLocal: true,
55-
expandSidebar: false,
56-
monacoEditorCDN: "local",
57-
chatStyle: "bubble",
58-
// 字体大小设置
59-
fontSize: "medium",
60-
// 解码器默认启用
61-
timestampDecoderEnabled: true,
62-
base64DecoderEnabled: true,
63-
unicodeDecoderEnabled: true,
64-
urlDecoderEnabled: true,
65-
// 编辑器默认设置
66-
defaultIndentSize: 4,
67-
// 快捷键默认设置
68-
newTabShortcut: "Ctrl+Shift+T",
69-
closeTabShortcut: "Ctrl+Shift+W",
57+
subscribeWithSelector(
58+
devtools(
59+
(set) => ({
60+
// 初始状态
61+
editDataSaveLocal: true,
62+
expandSidebar: false,
63+
monacoEditorCDN: "local",
64+
chatStyle: "bubble",
65+
fontSize: "medium",
66+
timestampDecoderEnabled: true,
67+
base64DecoderEnabled: true,
68+
unicodeDecoderEnabled: true,
69+
urlDecoderEnabled: true,
70+
defaultIndentSize: 4,
71+
newTabShortcut: "Ctrl+Shift+T",
72+
closeTabShortcut: "Ctrl+Shift+W",
73+
74+
// Actions 实现
75+
setEditDataSaveLocal: (value: boolean) =>
76+
set({ editDataSaveLocal: value }),
77+
setExpandSidebar: (value: boolean) => set({ expandSidebar: value }),
78+
setMonacoEditorCDN: (value: MonacoEditorCDN) =>
79+
set({ monacoEditorCDN: value }),
80+
setChatStyle: (value: ChatStyle) => set({ chatStyle: value }),
81+
setFontSize: (value: FontSize) => set({ fontSize: value }),
82+
setTimestampDecoderEnabled: (value: boolean) =>
83+
set({ timestampDecoderEnabled: value }),
84+
setBase64DecoderEnabled: (value: boolean) =>
85+
set({ base64DecoderEnabled: value }),
86+
setUnicodeDecoderEnabled: (value: boolean) =>
87+
set({ unicodeDecoderEnabled: value }),
88+
setUrlDecoderEnabled: (value: boolean) =>
89+
set({ urlDecoderEnabled: value }),
90+
setDefaultIndentSize: (value: number) =>
91+
set({ defaultIndentSize: value }),
92+
setNewTabShortcut: (value: string) => set({ newTabShortcut: value }),
93+
setCloseTabShortcut: (value: string) =>
94+
set({ closeTabShortcut: value }),
95+
setSettings: (settings: Partial<SettingsState>) => set(settings),
96+
// 从 IndexedDB 同步设置数据
97+
syncSettingsStore: async () => {
98+
const settings = await storage.getItem<SettingsState>(DB_SETTINGS);
7099

71-
// actions
72-
setEditDataSaveLocal: (value) => set({ editDataSaveLocal: value }),
73-
setExpandSidebar: (value) => set({ expandSidebar: value }),
74-
setMonacoEditorCDN: (value) => set({ monacoEditorCDN: value }),
75-
setChatStyle: (value) => set({ chatStyle: value }),
76-
// 字体大小setter实现
77-
setFontSize: (value) => set({ fontSize: value }),
78-
// 解码器setter实现
79-
setTimestampDecoderEnabled: (value) => set({ timestampDecoderEnabled: value }),
80-
setBase64DecoderEnabled: (value) => set({ base64DecoderEnabled: value }),
81-
setUnicodeDecoderEnabled: (value) => set({ unicodeDecoderEnabled: value }),
82-
setUrlDecoderEnabled: (value) => set({ urlDecoderEnabled: value }),
83-
// 编辑器默认设置setter实现
84-
setDefaultIndentSize: (value) => set({ defaultIndentSize: value }),
85-
// 快捷键setter实现
86-
setNewTabShortcut: (value) => set({ newTabShortcut: value }),
87-
setCloseTabShortcut: (value) => set({ closeTabShortcut: value }),
88-
setSettings: (settings) => {
89-
set(settings);
90-
},
91-
}),
92-
{
93-
name: "settingsStore", // 调试工具的key名
94-
},
100+
if (settings) {
101+
set(settings);
102+
}
103+
},
104+
}),
105+
{ name: "settingsStore", enabled: true },
106+
),
95107
),
96108
);
97109

98-
useSettingsStore.subscribe((state) => {
99-
const data = {
100-
editDataSaveLocal: state.editDataSaveLocal,
101-
expandSidebar: state.expandSidebar,
102-
monacoEditorCDN: state.monacoEditorCDN,
103-
chatStyle: state.chatStyle,
104-
// 保存字体大小设置
105-
fontSize: state.fontSize,
106-
// 保存解码器设置
107-
timestampDecoderEnabled: state.timestampDecoderEnabled,
108-
base64DecoderEnabled: state.base64DecoderEnabled,
109-
unicodeDecoderEnabled: state.unicodeDecoderEnabled,
110-
urlDecoderEnabled: state.urlDecoderEnabled,
111-
// 保存编辑器默认设置
112-
defaultIndentSize: state.defaultIndentSize,
113-
// 保存快捷键设置
114-
newTabShortcut: state.newTabShortcut,
115-
closeTabShortcut: state.closeTabShortcut,
116-
};
110+
const DB_SETTINGS = "settings";
117111

118-
storage.setItem("settings", data);
119-
});
112+
// 防抖保存设置到 IndexedDB
113+
let settingsSaveTimeout: NodeJS.Timeout;
114+
const timeout = 1000;
115+
116+
useSettingsStore.subscribe(
117+
(state) => state,
118+
(settings) => {
119+
clearTimeout(settingsSaveTimeout);
120+
settingsSaveTimeout = setTimeout(() => {
121+
storage.setItem(DB_SETTINGS, settings);
122+
}, timeout);
123+
},
124+
);

0 commit comments

Comments
 (0)