Files
lobe-chat/src/store/user/slices/common/action.ts
T

152 lines
4.9 KiB
TypeScript
Raw Normal View History

import { getSingletonAnalyticsOptional } from '@lobehub/analytics';
import useSWR, { SWRResponse, mutate } from 'swr';
import type { PartialDeep } from 'type-fest';
import type { StateCreator } from 'zustand/vanilla';
import { DEFAULT_PREFERENCE } from '@/const/user';
import { useOnlyFetchOnceSWR } from '@/libs/swr';
2024-05-03 09:52:15 +08:00
import { userService } from '@/services/user';
2024-04-28 23:28:17 +08:00
import type { UserStore } from '@/store/user';
2024-04-10 00:02:22 +08:00
import type { GlobalServerConfig } from '@/types/serverConfig';
import { LobeUser, UserInitializationState } from '@/types/user';
2024-05-26 23:33:01 +08:00
import type { UserSettings } from '@/types/user/settings';
2023-10-06 15:15:14 +08:00
import { merge } from '@/utils/merge';
2023-07-31 22:18:04 +08:00
import { setNamespace } from '@/utils/storeDebug';
2024-02-15 09:42:58 +08:00
2024-03-05 14:15:49 +08:00
import { preferenceSelectors } from '../preference/selectors';
const n = setNamespace('common');
2023-07-31 22:18:04 +08:00
const GET_USER_STATE_KEY = 'initUserState';
2023-07-22 17:19:44 +08:00
/**
* 设置操作
*/
2023-08-10 23:20:15 +08:00
export interface CommonAction {
refreshUserState: () => Promise<void>;
updateAvatar: (avatar: string) => Promise<void>;
2025-11-27 20:10:40 +08:00
updateFullName: (fullName: string) => Promise<void>;
2025-11-03 13:14:35 +08:00
updateKeyVaultConfig: (provider: string, config: any) => Promise<void>;
2025-12-05 01:35:20 +08:00
updateUsername: (username: string) => Promise<void>;
2024-03-05 14:15:49 +08:00
useCheckTrace: (shouldFetch: boolean) => SWRResponse;
useInitUserState: (
isLogin: boolean | undefined,
serverConfig: GlobalServerConfig,
options?: {
onError?: (error: any) => void;
onSuccess: (data: UserInitializationState) => void;
},
) => SWRResponse;
}
2023-08-10 23:20:15 +08:00
export const createCommonSlice: StateCreator<
2024-04-28 23:28:17 +08:00
UserStore,
[['zustand/devtools', never]],
[],
2023-08-10 23:20:15 +08:00
CommonAction
> = (set, get) => ({
refreshUserState: async () => {
await mutate(GET_USER_STATE_KEY);
},
updateAvatar: async (avatar) => {
await userService.updateAvatar(avatar);
2025-11-27 20:10:40 +08:00
await get().refreshUserState();
},
2025-11-27 20:10:40 +08:00
updateFullName: async (fullName) => {
await userService.updateFullName(fullName);
await get().refreshUserState();
},
2024-05-03 09:52:15 +08:00
2025-11-03 13:14:35 +08:00
updateKeyVaultConfig: async (provider, config) => {
await get().setSettings({ keyVaults: { [provider]: config } });
},
2025-12-05 01:35:20 +08:00
updateUsername: async (username) => {
await userService.updateUsername(username);
await get().refreshUserState();
},
2024-03-05 14:15:49 +08:00
useCheckTrace: (shouldFetch) =>
useSWR<boolean>(
shouldFetch ? 'checkTrace' : null,
2024-03-05 14:15:49 +08:00
() => {
const userAllowTrace = preferenceSelectors.userAllowTrace(get());
// if user have set the trace, return false
if (typeof userAllowTrace === 'boolean') return Promise.resolve(false);
return Promise.resolve(get().isUserCanEnableTrace);
2024-03-05 14:15:49 +08:00
},
{
revalidateOnFocus: false,
},
),
useInitUserState: (isLogin, serverConfig, options) =>
useOnlyFetchOnceSWR<UserInitializationState>(
!!isLogin ? GET_USER_STATE_KEY : null,
() => userService.getUserState(),
2024-05-18 22:30:48 +08:00
{
onError: (error) => {
options?.onError?.(error);
},
2024-05-18 22:30:48 +08:00
onSuccess: (data) => {
options?.onSuccess?.(data);
2024-05-18 22:30:48 +08:00
if (data) {
// merge settings
const serverSettings: PartialDeep<UserSettings> = {
defaultAgent: serverConfig.defaultAgent,
image: serverConfig.image,
2024-05-28 19:20:36 +08:00
systemAgent: serverConfig.systemAgent,
2024-05-18 22:30:48 +08:00
};
2024-05-28 19:20:36 +08:00
2024-05-18 22:30:48 +08:00
const defaultSettings = merge(get().defaultSettings, serverSettings);
// merge preference
const isEmpty = Object.keys(data.preference || {}).length === 0;
const preference = isEmpty ? DEFAULT_PREFERENCE : data.preference;
// if there is avatar or userId (from client DB), update it into user
const user =
data.avatar || data.userId
? merge(get().user, {
avatar: data.avatar,
2025-05-23 14:20:45 +08:00
email: data.email,
firstName: data.firstName,
fullName: data.fullName,
id: data.userId,
latestName: data.lastName,
username: data.username,
} as LobeUser)
: get().user;
set(
{
defaultSettings,
isOnboard: data.isOnboard,
isShowPWAGuide: data.canEnablePWAGuide,
isUserCanEnableTrace: data.canEnableTrace,
isUserHasConversation: data.hasConversation,
isUserStateInit: true,
preference,
settings: data.settings || {},
2025-07-29 17:41:42 +08:00
subscriptionPlan: data.subscriptionPlan,
user,
},
false,
n('initUserState'),
);
//analytics
const analytics = getSingletonAnalyticsOptional();
analytics?.identify(data.userId || '', {
email: data.email,
firstName: data.firstName,
lastName: data.lastName,
username: data.username,
});
2024-05-18 22:30:48 +08:00
}
},
},
2024-05-18 22:30:48 +08:00
),
});