You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import useSWR, { SWRResponse, mutate } from 'swr';
|
|
import { DeepPartial } from 'utility-types';
|
|
import type { StateCreator } from 'zustand/vanilla';
|
|
|
|
import { DEFAULT_PREFERENCE } from '@/const/user';
|
|
import { useOnlyFetchOnceSWR } from '@/libs/swr';
|
|
import { userService } from '@/services/user';
|
|
import { ClientService } from '@/services/user/client';
|
|
import type { UserStore } from '@/store/user';
|
|
import type { GlobalServerConfig } from '@/types/serverConfig';
|
|
import { UserInitializationState } from '@/types/user';
|
|
import type { UserSettings } from '@/types/user/settings';
|
|
import { switchLang } from '@/utils/client/switchLang';
|
|
import { merge } from '@/utils/merge';
|
|
import { setNamespace } from '@/utils/storeDebug';
|
|
|
|
import { preferenceSelectors } from '../preference/selectors';
|
|
import { userGeneralSettingsSelectors } from '../settings/selectors';
|
|
|
|
const n = setNamespace('common');
|
|
|
|
const GET_USER_STATE_KEY = 'initUserState';
|
|
/**
|
|
* 设置操作
|
|
*/
|
|
export interface CommonAction {
|
|
refreshUserState: () => Promise<void>;
|
|
|
|
updateAvatar: (avatar: string) => Promise<void>;
|
|
useCheckTrace: (shouldFetch: boolean) => SWRResponse;
|
|
useInitUserState: (
|
|
isLogin: boolean | undefined,
|
|
serverConfig: GlobalServerConfig,
|
|
options?: {
|
|
onSuccess: (data: UserInitializationState) => void;
|
|
},
|
|
) => SWRResponse;
|
|
}
|
|
|
|
export const createCommonSlice: StateCreator<
|
|
UserStore,
|
|
[['zustand/devtools', never]],
|
|
[],
|
|
CommonAction
|
|
> = (set, get) => ({
|
|
refreshUserState: async () => {
|
|
await mutate(GET_USER_STATE_KEY);
|
|
},
|
|
updateAvatar: async (avatar) => {
|
|
const clientService = new ClientService();
|
|
|
|
await clientService.updateAvatar(avatar);
|
|
await get().refreshUserState();
|
|
},
|
|
|
|
useCheckTrace: (shouldFetch) =>
|
|
useSWR<boolean>(
|
|
shouldFetch ? 'checkTrace' : null,
|
|
() => {
|
|
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);
|
|
},
|
|
{
|
|
revalidateOnFocus: false,
|
|
},
|
|
),
|
|
|
|
useInitUserState: (isLogin, serverConfig, options) =>
|
|
useOnlyFetchOnceSWR<UserInitializationState>(
|
|
!!isLogin ? GET_USER_STATE_KEY : null,
|
|
() => userService.getUserState(),
|
|
{
|
|
onSuccess: (data) => {
|
|
options?.onSuccess?.(data);
|
|
|
|
if (data) {
|
|
// merge settings
|
|
const serverSettings: DeepPartial<UserSettings> = {
|
|
defaultAgent: serverConfig.defaultAgent,
|
|
languageModel: serverConfig.languageModel,
|
|
systemAgent: serverConfig.systemAgent,
|
|
};
|
|
|
|
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, id: data.userId })
|
|
: get().user;
|
|
|
|
set(
|
|
{
|
|
defaultSettings,
|
|
enabledNextAuth: serverConfig.enabledOAuthSSO,
|
|
isOnboard: data.isOnboard,
|
|
isShowPWAGuide: data.canEnablePWAGuide,
|
|
isUserCanEnableTrace: data.canEnableTrace,
|
|
isUserHasConversation: data.hasConversation,
|
|
isUserStateInit: true,
|
|
preference,
|
|
serverLanguageModel: serverConfig.languageModel,
|
|
settings: data.settings || {},
|
|
user,
|
|
},
|
|
false,
|
|
n('initUserState'),
|
|
);
|
|
|
|
get().refreshDefaultModelProviderList({ trigger: 'fetchUserState' });
|
|
|
|
// auto switch language
|
|
const language = userGeneralSettingsSelectors.config(get()).language;
|
|
if (language === 'auto') {
|
|
switchLang('auto');
|
|
}
|
|
}
|
|
},
|
|
},
|
|
),
|
|
});
|