@lobehub/chat 0.161.9 → 0.161.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +5 -2
- package/src/app/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +6 -7
- package/src/app/(main)/settings/llm/components/ProviderModelList/{ModelConfigModal.tsx → ModelConfigModal/Form.tsx} +19 -63
- package/src/app/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +78 -0
- package/src/app/(main)/settings/llm/components/ProviderModelList/Option.tsx +35 -11
- package/src/app/(main)/settings/llm/components/ProviderModelList/index.tsx +15 -18
- package/src/components/ModelProviderIcon/index.tsx +2 -2
- package/src/components/ModelSelect/index.tsx +5 -14
- package/src/features/User/UserPanel/PanelContent.tsx +1 -1
- package/src/hooks/useSyncData.ts +3 -1
- package/src/layout/GlobalProvider/StoreInitialization.tsx +17 -9
- package/src/layout/GlobalProvider/index.tsx +1 -1
- package/src/locales/default/components.ts +1 -0
- package/src/services/message/client.test.ts +0 -24
- package/src/services/message/client.ts +0 -5
- package/src/services/message/type.ts +0 -1
- package/src/services/user/client.test.ts +100 -0
- package/src/services/user/client.ts +16 -14
- package/src/services/user/index.ts +0 -2
- package/src/services/user/type.ts +2 -4
- package/src/store/user/initialState.ts +10 -1
- package/src/store/user/selectors.ts +3 -7
- package/src/store/user/slices/auth/action.test.ts +5 -87
- package/src/store/user/slices/auth/action.ts +3 -58
- package/src/store/user/slices/auth/initialState.ts +2 -1
- package/src/store/user/slices/common/action.test.ts +196 -20
- package/src/store/user/slices/common/action.ts +55 -26
- package/src/store/user/slices/common/initialState.ts +9 -0
- package/src/store/user/slices/modelList/action.test.ts +363 -0
- package/src/store/user/slices/{settings/actions/llm.ts → modelList/action.ts} +66 -60
- package/src/store/user/slices/modelList/initialState.ts +15 -0
- package/src/store/user/slices/modelList/selectors/index.ts +2 -0
- package/src/store/user/slices/{settings → modelList}/selectors/modelConfig.test.ts +3 -2
- package/src/store/user/slices/{settings → modelList}/selectors/modelConfig.ts +1 -1
- package/src/store/user/slices/{settings → modelList}/selectors/modelProvider.test.ts +7 -7
- package/src/store/user/slices/{settings → modelList}/selectors/modelProvider.ts +2 -4
- package/src/store/user/slices/preference/action.test.ts +0 -52
- package/src/store/user/slices/preference/action.ts +1 -17
- package/src/store/user/slices/preference/initialState.ts +0 -5
- package/src/store/user/slices/preference/selectors.test.ts +2 -2
- package/src/store/user/slices/preference/selectors.ts +1 -1
- package/src/store/user/slices/settings/{actions/general.ts → action.ts} +5 -5
- package/src/store/user/slices/settings/initialState.ts +0 -12
- package/src/store/user/slices/settings/selectors/index.ts +0 -3
- package/src/store/user/slices/sync/action.test.ts +19 -5
- package/src/store/user/slices/sync/action.ts +9 -6
- package/src/store/user/slices/{settings/selectors/sync.ts → sync/selectors.ts} +2 -2
- package/src/store/user/store.ts +5 -2
- package/src/types/serverConfig.ts +3 -1
- package/src/types/user/index.ts +13 -0
- package/src/utils/parseModels.test.ts +121 -1
- package/src/utils/parseModels.ts +9 -4
- package/src/store/user/slices/settings/actions/index.ts +0 -18
- package/src/store/user/slices/settings/actions/llm.test.ts +0 -136
- /package/src/app/(main)/settings/llm/components/ProviderModelList/{MaxTokenSlider.tsx → ModelConfigModal/MaxTokenSlider.tsx} +0 -0
- /package/src/store/user/slices/{settings → modelList}/reducers/customModelCard.test.ts +0 -0
- /package/src/store/user/slices/{settings → modelList}/reducers/customModelCard.ts +0 -0
- /package/src/store/user/slices/settings/{actions/general.test.ts → action.test.ts} +0 -0
- /package/src/store/user/slices/settings/selectors/__snapshots__/{selectors.test.ts.snap → settings.test.ts.snap} +0 -0
- /package/src/store/user/slices/settings/selectors/{selectors.test.ts → settings.test.ts} +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { DeepPartial } from 'utility-types';
|
|
2
|
+
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { UserModel } from '@/database/client/models/user';
|
|
5
|
+
import { GlobalSettings } from '@/types/settings';
|
|
6
|
+
import { UserPreference } from '@/types/user';
|
|
7
|
+
import { AsyncLocalStorage } from '@/utils/localStorage';
|
|
8
|
+
|
|
9
|
+
import { ClientService } from './client';
|
|
10
|
+
|
|
11
|
+
vi.mock('@/database/client/models/user', () => ({
|
|
12
|
+
UserModel: {
|
|
13
|
+
getUser: vi.fn(),
|
|
14
|
+
updateSettings: vi.fn(),
|
|
15
|
+
resetSettings: vi.fn(),
|
|
16
|
+
updateAvatar: vi.fn(),
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
const mockUser = {
|
|
21
|
+
avatar: 'avatar.png',
|
|
22
|
+
settings: { themeMode: 'light' } as unknown as GlobalSettings,
|
|
23
|
+
uuid: 'user-id',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const mockPreference = {
|
|
27
|
+
useCmdEnterToSend: true,
|
|
28
|
+
} as UserPreference;
|
|
29
|
+
|
|
30
|
+
describe('ClientService', () => {
|
|
31
|
+
let clientService: ClientService;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
vi.clearAllMocks();
|
|
35
|
+
clientService = new ClientService();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should get user state correctly', async () => {
|
|
39
|
+
(UserModel.getUser as Mock).mockResolvedValue(mockUser);
|
|
40
|
+
const spyOn = vi
|
|
41
|
+
.spyOn(clientService['preferenceStorage'], 'getFromLocalStorage')
|
|
42
|
+
.mockResolvedValue(mockPreference);
|
|
43
|
+
|
|
44
|
+
const userState = await clientService.getUserState();
|
|
45
|
+
|
|
46
|
+
expect(userState).toEqual({
|
|
47
|
+
avatar: mockUser.avatar,
|
|
48
|
+
isOnboard: true,
|
|
49
|
+
canEnableTrace: false,
|
|
50
|
+
preference: mockPreference,
|
|
51
|
+
settings: mockUser.settings,
|
|
52
|
+
userId: mockUser.uuid,
|
|
53
|
+
});
|
|
54
|
+
expect(UserModel.getUser).toHaveBeenCalledTimes(1);
|
|
55
|
+
expect(spyOn).toHaveBeenCalledTimes(1);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should update user settings correctly', async () => {
|
|
59
|
+
const settingsPatch: DeepPartial<GlobalSettings> = { themeMode: 'dark' };
|
|
60
|
+
(UserModel.updateSettings as Mock).mockResolvedValue(undefined);
|
|
61
|
+
|
|
62
|
+
await clientService.updateUserSettings(settingsPatch);
|
|
63
|
+
|
|
64
|
+
expect(UserModel.updateSettings).toHaveBeenCalledWith(settingsPatch);
|
|
65
|
+
expect(UserModel.updateSettings).toHaveBeenCalledTimes(1);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should reset user settings correctly', async () => {
|
|
69
|
+
(UserModel.resetSettings as Mock).mockResolvedValue(undefined);
|
|
70
|
+
|
|
71
|
+
await clientService.resetUserSettings();
|
|
72
|
+
|
|
73
|
+
expect(UserModel.resetSettings).toHaveBeenCalledTimes(1);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should update user avatar correctly', async () => {
|
|
77
|
+
const newAvatar = 'new-avatar.png';
|
|
78
|
+
(UserModel.updateAvatar as Mock).mockResolvedValue(undefined);
|
|
79
|
+
|
|
80
|
+
await clientService.updateAvatar(newAvatar);
|
|
81
|
+
|
|
82
|
+
expect(UserModel.updateAvatar).toHaveBeenCalledWith(newAvatar);
|
|
83
|
+
expect(UserModel.updateAvatar).toHaveBeenCalledTimes(1);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should update user preference correctly', async () => {
|
|
87
|
+
const newPreference = {
|
|
88
|
+
useCmdEnterToSend: false,
|
|
89
|
+
} as UserPreference;
|
|
90
|
+
|
|
91
|
+
const spyOn = vi
|
|
92
|
+
.spyOn(clientService['preferenceStorage'], 'saveToLocalStorage')
|
|
93
|
+
.mockResolvedValue(undefined);
|
|
94
|
+
|
|
95
|
+
await clientService.updatePreference(newPreference);
|
|
96
|
+
|
|
97
|
+
expect(spyOn).toHaveBeenCalledWith(newPreference);
|
|
98
|
+
expect(spyOn).toHaveBeenCalledTimes(1);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import { DeepPartial } from 'utility-types';
|
|
2
2
|
|
|
3
|
+
import { MessageModel } from '@/database/client/models/message';
|
|
3
4
|
import { UserModel } from '@/database/client/models/user';
|
|
4
|
-
import { IUserService } from '@/services/user/type';
|
|
5
5
|
import { GlobalSettings } from '@/types/settings';
|
|
6
|
-
import { UserPreference } from '@/types/user';
|
|
6
|
+
import { UserInitializationState, UserPreference } from '@/types/user';
|
|
7
7
|
import { AsyncLocalStorage } from '@/utils/localStorage';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
avatar?: string;
|
|
11
|
-
settings: DeepPartial<GlobalSettings>;
|
|
12
|
-
uuid: string;
|
|
13
|
-
}
|
|
9
|
+
import { IUserService } from './type';
|
|
14
10
|
|
|
15
11
|
export class ClientService implements IUserService {
|
|
16
12
|
private preferenceStorage: AsyncLocalStorage<UserPreference>;
|
|
13
|
+
|
|
17
14
|
constructor() {
|
|
18
15
|
this.preferenceStorage = new AsyncLocalStorage('LOBE_PREFERENCE');
|
|
19
16
|
}
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
async getUserState(): Promise<UserInitializationState> {
|
|
22
19
|
const user = await UserModel.getUser();
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const messageCount = await MessageModel.count();
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
avatar: user.avatar,
|
|
24
|
+
canEnableTrace: messageCount >= 4,
|
|
25
|
+
isOnboard: true,
|
|
26
|
+
preference: await this.preferenceStorage.getFromLocalStorage(),
|
|
27
|
+
settings: user.settings as GlobalSettings,
|
|
28
|
+
userId: user.uuid,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
25
31
|
|
|
26
32
|
updateUserSettings = async (patch: DeepPartial<GlobalSettings>) => {
|
|
27
33
|
return UserModel.updateSettings(patch);
|
|
@@ -35,10 +41,6 @@ export class ClientService implements IUserService {
|
|
|
35
41
|
return UserModel.updateAvatar(avatar);
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
async getPreference() {
|
|
39
|
-
return this.preferenceStorage.getFromLocalStorage();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
44
|
async updatePreference(preference: UserPreference) {
|
|
43
45
|
await this.preferenceStorage.saveToLocalStorage(preference);
|
|
44
46
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { DeepPartial } from 'utility-types';
|
|
2
2
|
|
|
3
|
-
import { UserConfig } from '@/services/user/client';
|
|
4
3
|
import { GlobalSettings } from '@/types/settings';
|
|
5
|
-
import { UserPreference } from '@/types/user';
|
|
4
|
+
import { UserInitializationState, UserPreference } from '@/types/user';
|
|
6
5
|
|
|
7
6
|
export interface IUserService {
|
|
8
|
-
|
|
9
|
-
getUserConfig: () => Promise<UserConfig>;
|
|
7
|
+
getUserState: () => Promise<UserInitializationState>;
|
|
10
8
|
resetUserSettings: () => Promise<any>;
|
|
11
9
|
updateAvatar: (avatar: string) => Promise<any>;
|
|
12
10
|
updatePreference: (preference: UserPreference) => Promise<any>;
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import { UserAuthState, initialAuthState } from './slices/auth/initialState';
|
|
2
|
+
import { CommonState, initialCommonState } from './slices/common/initialState';
|
|
3
|
+
import { ModelListState, initialModelListState } from './slices/modelList/initialState';
|
|
2
4
|
import { UserPreferenceState, initialPreferenceState } from './slices/preference/initialState';
|
|
3
5
|
import { UserSettingsState, initialSettingsState } from './slices/settings/initialState';
|
|
4
6
|
import { UserSyncState, initialSyncState } from './slices/sync/initialState';
|
|
5
7
|
|
|
6
|
-
export type UserState = UserSyncState &
|
|
8
|
+
export type UserState = UserSyncState &
|
|
9
|
+
UserSettingsState &
|
|
10
|
+
UserPreferenceState &
|
|
11
|
+
UserAuthState &
|
|
12
|
+
ModelListState &
|
|
13
|
+
CommonState;
|
|
7
14
|
|
|
8
15
|
export const initialState: UserState = {
|
|
9
16
|
...initialSyncState,
|
|
10
17
|
...initialSettingsState,
|
|
11
18
|
...initialPreferenceState,
|
|
12
19
|
...initialAuthState,
|
|
20
|
+
...initialCommonState,
|
|
21
|
+
...initialModelListState,
|
|
13
22
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
export { authSelectors, userProfileSelectors } from './slices/auth/selectors';
|
|
2
|
+
export { modelConfigSelectors, modelProviderSelectors } from './slices/modelList/selectors';
|
|
2
3
|
export { preferenceSelectors } from './slices/preference/selectors';
|
|
3
|
-
export {
|
|
4
|
-
|
|
5
|
-
modelProviderSelectors,
|
|
6
|
-
settingsSelectors,
|
|
7
|
-
syncSettingsSelectors,
|
|
8
|
-
systemAgentSelectors,
|
|
9
|
-
} from './slices/settings/selectors';
|
|
4
|
+
export { settingsSelectors, systemAgentSelectors } from './slices/settings/selectors';
|
|
5
|
+
export { syncSettingsSelectors } from './slices/sync/selectors';
|
|
@@ -9,10 +9,6 @@ import { switchLang } from '@/utils/client/switchLang';
|
|
|
9
9
|
|
|
10
10
|
vi.mock('zustand/traditional');
|
|
11
11
|
|
|
12
|
-
vi.mock('@/utils/client/switchLang', () => ({
|
|
13
|
-
switchLang: vi.fn(),
|
|
14
|
-
}));
|
|
15
|
-
|
|
16
12
|
vi.mock('swr', async (importOriginal) => {
|
|
17
13
|
const modules = await importOriginal();
|
|
18
14
|
return {
|
|
@@ -54,93 +50,15 @@ vi.mock('next-auth/react', async () => {
|
|
|
54
50
|
});
|
|
55
51
|
|
|
56
52
|
describe('createAuthSlice', () => {
|
|
57
|
-
describe('
|
|
53
|
+
describe('refreshUserState', () => {
|
|
58
54
|
it('should refresh user config', async () => {
|
|
59
55
|
const { result } = renderHook(() => useUserStore());
|
|
60
56
|
|
|
61
57
|
await act(async () => {
|
|
62
|
-
await result.current.
|
|
58
|
+
await result.current.refreshUserState();
|
|
63
59
|
});
|
|
64
60
|
|
|
65
|
-
expect(mutate).toHaveBeenCalledWith(
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('useFetchUserConfig', () => {
|
|
70
|
-
it('should not fetch user config if initServer is false', async () => {
|
|
71
|
-
const mockUserConfig: any = undefined; // 模拟未初始化服务器的情况
|
|
72
|
-
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);
|
|
73
|
-
|
|
74
|
-
const { result } = renderHook(() => useUserStore().useFetchUserConfig(false), {
|
|
75
|
-
wrapper: withSWR,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// 因为 initServer 为 false,所以不会触发 getUserConfig 的调用
|
|
79
|
-
expect(userService.getUserConfig).not.toHaveBeenCalled();
|
|
80
|
-
// 确保状态未改变
|
|
81
|
-
expect(result.current.data).toBeUndefined();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should fetch user config correctly when initServer is true', async () => {
|
|
85
|
-
const mockUserConfig: any = {
|
|
86
|
-
avatar: 'new-avatar-url',
|
|
87
|
-
settings: {
|
|
88
|
-
language: 'en',
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);
|
|
92
|
-
|
|
93
|
-
const { result } = renderHook(() => useUserStore().useFetchUserConfig(true), {
|
|
94
|
-
wrapper: withSWR,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// 等待 SWR 完成数据获取
|
|
98
|
-
await waitFor(() => expect(result.current.data).toEqual(mockUserConfig));
|
|
99
|
-
|
|
100
|
-
// 验证状态是否正确更新
|
|
101
|
-
expect(useUserStore.getState().avatar).toBe(mockUserConfig.avatar);
|
|
102
|
-
expect(useUserStore.getState().settings).toEqual(mockUserConfig.settings);
|
|
103
|
-
|
|
104
|
-
// 验证是否正确处理了语言设置
|
|
105
|
-
expect(switchLang).not.toHaveBeenCalledWith('auto');
|
|
106
|
-
});
|
|
107
|
-
it('should call switch language when language is auto', async () => {
|
|
108
|
-
const mockUserConfig: any = {
|
|
109
|
-
avatar: 'new-avatar-url',
|
|
110
|
-
settings: {
|
|
111
|
-
language: 'auto',
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(mockUserConfig);
|
|
115
|
-
|
|
116
|
-
const { result } = renderHook(() => useUserStore().useFetchUserConfig(true), {
|
|
117
|
-
wrapper: withSWR,
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// 等待 SWR 完成数据获取
|
|
121
|
-
await waitFor(() => expect(result.current.data).toEqual(mockUserConfig));
|
|
122
|
-
|
|
123
|
-
// 验证状态是否正确更新
|
|
124
|
-
expect(useUserStore.getState().avatar).toBe(mockUserConfig.avatar);
|
|
125
|
-
expect(useUserStore.getState().settings).toEqual(mockUserConfig.settings);
|
|
126
|
-
|
|
127
|
-
// 验证是否正确处理了语言设置
|
|
128
|
-
expect(switchLang).toHaveBeenCalledWith('auto');
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('should handle the case when user config is null', async () => {
|
|
132
|
-
vi.spyOn(userService, 'getUserConfig').mockResolvedValueOnce(null as any);
|
|
133
|
-
|
|
134
|
-
const { result } = renderHook(() => useUserStore().useFetchUserConfig(true), {
|
|
135
|
-
wrapper: withSWR,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// 等待 SWR 完成数据获取
|
|
139
|
-
await waitFor(() => expect(result.current.data).toBeNull());
|
|
140
|
-
|
|
141
|
-
// 验证状态未被错误更新
|
|
142
|
-
expect(useUserStore.getState().avatar).toBeUndefined();
|
|
143
|
-
expect(useUserStore.getState().settings).toEqual({});
|
|
61
|
+
expect(mutate).toHaveBeenCalledWith('initUserState');
|
|
144
62
|
});
|
|
145
63
|
});
|
|
146
64
|
|
|
@@ -174,7 +92,7 @@ describe('createAuthSlice', () => {
|
|
|
174
92
|
});
|
|
175
93
|
|
|
176
94
|
it('should call next-auth signOut when NextAuth is enabled', async () => {
|
|
177
|
-
useUserStore.setState({ enabledNextAuth:
|
|
95
|
+
useUserStore.setState({ enabledNextAuth: true });
|
|
178
96
|
|
|
179
97
|
const { result } = renderHook(() => useUserStore());
|
|
180
98
|
|
|
@@ -228,7 +146,7 @@ describe('createAuthSlice', () => {
|
|
|
228
146
|
});
|
|
229
147
|
|
|
230
148
|
it('should call next-auth signIn when NextAuth is enabled', async () => {
|
|
231
|
-
useUserStore.setState({ enabledNextAuth:
|
|
149
|
+
useUserStore.setState({ enabledNextAuth: true });
|
|
232
150
|
|
|
233
151
|
const { result } = renderHook(() => useUserStore());
|
|
234
152
|
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
-
import useSWR, { SWRResponse, mutate } from 'swr';
|
|
2
1
|
import { StateCreator } from 'zustand/vanilla';
|
|
3
2
|
|
|
4
3
|
import { enableClerk } from '@/const/auth';
|
|
5
|
-
import { UserConfig, userService } from '@/services/user';
|
|
6
|
-
import { switchLang } from '@/utils/client/switchLang';
|
|
7
|
-
import { setNamespace } from '@/utils/storeDebug';
|
|
8
4
|
|
|
9
5
|
import { UserStore } from '../../store';
|
|
10
|
-
import { settingsSelectors } from '../settings/selectors';
|
|
11
|
-
|
|
12
|
-
const n = setNamespace('auth');
|
|
13
|
-
const USER_CONFIG_FETCH_KEY = 'fetchUserConfig';
|
|
14
6
|
|
|
15
7
|
export interface UserAuthAction {
|
|
16
8
|
enableAuth: () => boolean;
|
|
17
|
-
enabledNextAuth: () => boolean;
|
|
18
|
-
getUserConfig: () => void;
|
|
19
9
|
/**
|
|
20
10
|
* universal logout method
|
|
21
11
|
*/
|
|
@@ -25,9 +15,6 @@ export interface UserAuthAction {
|
|
|
25
15
|
*/
|
|
26
16
|
openLogin: () => Promise<void>;
|
|
27
17
|
openUserProfile: () => Promise<void>;
|
|
28
|
-
|
|
29
|
-
refreshUserConfig: () => Promise<void>;
|
|
30
|
-
useFetchUserConfig: (initServer: boolean) => SWRResponse<UserConfig | undefined>;
|
|
31
18
|
}
|
|
32
19
|
|
|
33
20
|
export const createAuthSlice: StateCreator<
|
|
@@ -37,13 +24,7 @@ export const createAuthSlice: StateCreator<
|
|
|
37
24
|
UserAuthAction
|
|
38
25
|
> = (set, get) => ({
|
|
39
26
|
enableAuth: () => {
|
|
40
|
-
return enableClerk || get()?.enabledNextAuth
|
|
41
|
-
},
|
|
42
|
-
enabledNextAuth: () => {
|
|
43
|
-
return !!get()?.serverConfig.enabledOAuthSSO;
|
|
44
|
-
},
|
|
45
|
-
getUserConfig: () => {
|
|
46
|
-
console.log(n('userconfig'));
|
|
27
|
+
return enableClerk || get()?.enabledNextAuth || false;
|
|
47
28
|
},
|
|
48
29
|
logout: async () => {
|
|
49
30
|
if (enableClerk) {
|
|
@@ -52,7 +33,7 @@ export const createAuthSlice: StateCreator<
|
|
|
52
33
|
return;
|
|
53
34
|
}
|
|
54
35
|
|
|
55
|
-
const enableNextAuth = get().enabledNextAuth
|
|
36
|
+
const enableNextAuth = get().enabledNextAuth;
|
|
56
37
|
if (enableNextAuth) {
|
|
57
38
|
const { signOut } = await import('next-auth/react');
|
|
58
39
|
signOut();
|
|
@@ -60,14 +41,12 @@ export const createAuthSlice: StateCreator<
|
|
|
60
41
|
},
|
|
61
42
|
openLogin: async () => {
|
|
62
43
|
if (enableClerk) {
|
|
63
|
-
console.log('fallbackRedirectUrl:', location.toString());
|
|
64
|
-
|
|
65
44
|
get().clerkSignIn?.({ fallbackRedirectUrl: location.toString() });
|
|
66
45
|
|
|
67
46
|
return;
|
|
68
47
|
}
|
|
69
48
|
|
|
70
|
-
const enableNextAuth = get().enabledNextAuth
|
|
49
|
+
const enableNextAuth = get().enabledNextAuth;
|
|
71
50
|
if (enableNextAuth) {
|
|
72
51
|
const { signIn } = await import('next-auth/react');
|
|
73
52
|
signIn();
|
|
@@ -81,38 +60,4 @@ export const createAuthSlice: StateCreator<
|
|
|
81
60
|
return;
|
|
82
61
|
}
|
|
83
62
|
},
|
|
84
|
-
refreshUserConfig: async () => {
|
|
85
|
-
await mutate([USER_CONFIG_FETCH_KEY, true]);
|
|
86
|
-
|
|
87
|
-
// when get the user config ,refresh the model provider list to the latest
|
|
88
|
-
get().refreshModelProviderList();
|
|
89
|
-
},
|
|
90
|
-
useFetchUserConfig: (initServer) =>
|
|
91
|
-
useSWR<UserConfig | undefined>(
|
|
92
|
-
[USER_CONFIG_FETCH_KEY, initServer],
|
|
93
|
-
async () => {
|
|
94
|
-
if (!initServer) return;
|
|
95
|
-
return userService.getUserConfig();
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
onSuccess: (data) => {
|
|
99
|
-
if (!data) return;
|
|
100
|
-
|
|
101
|
-
set(
|
|
102
|
-
{ avatar: data.avatar, settings: data.settings, userId: data.uuid },
|
|
103
|
-
false,
|
|
104
|
-
n('fetchUserConfig', data),
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
// when get the user config ,refresh the model provider list to the latest
|
|
108
|
-
get().refreshDefaultModelProviderList({ trigger: 'fetchUserConfig' });
|
|
109
|
-
|
|
110
|
-
const { language } = settingsSelectors.currentSettings(get());
|
|
111
|
-
if (language === 'auto') {
|
|
112
|
-
switchLang('auto');
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
revalidateOnFocus: false,
|
|
116
|
-
},
|
|
117
|
-
),
|
|
118
63
|
});
|
|
@@ -15,12 +15,13 @@ export interface UserAuthState {
|
|
|
15
15
|
* @deprecated
|
|
16
16
|
*/
|
|
17
17
|
avatar?: string;
|
|
18
|
-
|
|
19
18
|
clerkOpenUserProfile?: (props?: UserProfileProps) => void;
|
|
19
|
+
|
|
20
20
|
clerkSession?: ActiveSessionResource;
|
|
21
21
|
clerkSignIn?: (props?: SignInProps) => void;
|
|
22
22
|
clerkSignOut?: SignOut;
|
|
23
23
|
clerkUser?: UserResource;
|
|
24
|
+
enabledNextAuth?: boolean;
|
|
24
25
|
|
|
25
26
|
isLoaded?: boolean;
|
|
26
27
|
isSignedIn?: boolean;
|