|
1 | | -import { useCallback, useLayoutEffect, useState } from "react"; |
| 1 | +import { useCallback, useMemo, useSyncExternalStore } from "react"; |
2 | 2 |
|
3 | 3 | import { |
4 | 4 | DEFAULT_LOCAL_SETTINGS, |
5 | | - getLocalSettings, |
6 | | - getThreadLocalSettings, |
7 | | - saveLocalSettings, |
8 | | - saveThreadLocalSettings, |
| 5 | + applyThreadModelOverride, |
9 | 6 | type LocalSettings, |
10 | 7 | } from "./local"; |
| 8 | +import { |
| 9 | + getBaseSettingsSnapshot, |
| 10 | + getThreadModelSnapshot, |
| 11 | + subscribe, |
| 12 | + updateLocalSettings, |
| 13 | + updateThreadSettings, |
| 14 | + type LocalSettingsSetter, |
| 15 | +} from "./store"; |
11 | 16 |
|
12 | | -type LocalSettingsSetter = ( |
13 | | - key: keyof LocalSettings, |
14 | | - value: Partial<LocalSettings[keyof LocalSettings]>, |
15 | | -) => void; |
16 | | - |
17 | | -function useSettingsState( |
18 | | - getSettings: () => LocalSettings, |
19 | | - saveSettings: (settings: LocalSettings) => void, |
20 | | -): [LocalSettings, LocalSettingsSetter] { |
21 | | - const [state, setState] = useState<LocalSettings>(DEFAULT_LOCAL_SETTINGS); |
22 | | - |
23 | | - const [mounted, setMounted] = useState(false); |
24 | | - useLayoutEffect(() => { |
25 | | - setState(getSettings()); |
26 | | - setMounted(true); |
27 | | - }, [getSettings]); |
28 | | - |
29 | | - const setter = useCallback<LocalSettingsSetter>( |
30 | | - (key, value) => { |
31 | | - if (!mounted) return; |
32 | | - setState((prev) => { |
33 | | - const newState: LocalSettings = { |
34 | | - ...prev, |
35 | | - [key]: { |
36 | | - ...prev[key], |
37 | | - ...value, |
38 | | - }, |
39 | | - }; |
40 | | - saveSettings(newState); |
41 | | - return newState; |
42 | | - }); |
43 | | - }, |
44 | | - [mounted, saveSettings], |
| 17 | +export function useLocalSettings(): [LocalSettings, LocalSettingsSetter] { |
| 18 | + const settings = useSyncExternalStore( |
| 19 | + subscribe, |
| 20 | + getBaseSettingsSnapshot, |
| 21 | + () => DEFAULT_LOCAL_SETTINGS, |
45 | 22 | ); |
46 | 23 |
|
47 | | - return [state, setter]; |
48 | | -} |
| 24 | + const setSettings = useCallback<LocalSettingsSetter>((key, value) => { |
| 25 | + updateLocalSettings(key, value); |
| 26 | + }, []); |
49 | 27 |
|
50 | | -export function useLocalSettings(): [LocalSettings, LocalSettingsSetter] { |
51 | | - return useSettingsState(getLocalSettings, saveLocalSettings); |
| 28 | + return [settings, setSettings]; |
52 | 29 | } |
53 | 30 |
|
54 | 31 | export function useThreadSettings( |
55 | 32 | threadId: string, |
56 | 33 | ): [LocalSettings, LocalSettingsSetter] { |
57 | | - return useSettingsState( |
58 | | - useCallback(() => getThreadLocalSettings(threadId), [threadId]), |
59 | | - useCallback( |
60 | | - (settings: LocalSettings) => saveThreadLocalSettings(threadId, settings), |
61 | | - [threadId], |
62 | | - ), |
| 34 | + const baseSettings = useSyncExternalStore( |
| 35 | + subscribe, |
| 36 | + getBaseSettingsSnapshot, |
| 37 | + () => DEFAULT_LOCAL_SETTINGS, |
63 | 38 | ); |
| 39 | + |
| 40 | + const threadModelName = useSyncExternalStore( |
| 41 | + subscribe, |
| 42 | + () => getThreadModelSnapshot(threadId), |
| 43 | + () => undefined, |
| 44 | + ); |
| 45 | + |
| 46 | + const settings = useMemo( |
| 47 | + () => applyThreadModelOverride(baseSettings, threadModelName), |
| 48 | + [baseSettings, threadModelName], |
| 49 | + ); |
| 50 | + |
| 51 | + const setSettings = useCallback<LocalSettingsSetter>( |
| 52 | + (key, value) => { |
| 53 | + updateThreadSettings(threadId, key, value); |
| 54 | + }, |
| 55 | + [threadId], |
| 56 | + ); |
| 57 | + |
| 58 | + return [settings, setSettings]; |
64 | 59 | } |
0 commit comments