feat: 用户信息修改

头像与昵称
pull/13/head
moonrailgun 4 years ago
parent 7fcbbbd4d8
commit 6d913e0676

@ -77,6 +77,7 @@ export {
registerWithEmail,
searchUserWithUniqueName,
checkTokenValid,
modifyUserField,
} from './model/user';
// redux
@ -84,7 +85,7 @@ export { useAppSelector, useAppDispatch } from './redux/hooks/useAppSelector';
export { useDMConverseList } from './redux/hooks/useConverse';
export { useConverseMessage } from './redux/hooks/useConverseMessage';
export { useGroupInfo, useGroupPanel } from './redux/hooks/useGroup';
export { useUserId } from './redux/hooks/useUserInfo';
export { useUserInfo, useUserId } from './redux/hooks/useUserInfo';
export { userActions } from './redux/slices';
export type { ChatConverseState } from './redux/slices/chat';
export { setupRedux } from './redux/setup';

@ -131,6 +131,24 @@ export async function appendUserDMConverse(
return data;
}
/**
*
* @param fieldName
* @param fieldValue
*/
type AllowedModifyField = 'nickname' | 'avatar';
export async function modifyUserField(
fieldName: AllowedModifyField,
fieldValue: unknown
): Promise<UserBaseInfo> {
const { data } = await request.post('/api/user/updateUserField', {
fieldName,
fieldValue,
});
return data;
}
/**
* Token
*/

@ -1,8 +1,16 @@
import type { UserLoginInfo } from '../../model/user';
import { useAppSelector } from './useAppSelector';
/**
*
*/
export function useUserInfo(): UserLoginInfo | null {
return useAppSelector((state) => state.user.info);
}
/**
* Id
*/
export function useUserId(): string | undefined {
return useAppSelector((state) => state.user.info?._id);
return useUserInfo()?._id;
}

@ -21,6 +21,16 @@ const userSlice = createSlice({
setUserInfo(state, action: PayloadAction<UserLoginInfo>) {
state.info = action.payload;
},
setUserInfoField(
state,
action: PayloadAction<{ fieldName: keyof UserLoginInfo; fieldValue: any }>
) {
const { fieldName, fieldValue } = action.payload;
if (state.info === null) {
return;
}
state.info[fieldName] = fieldValue;
},
setFriendList(state, action: PayloadAction<string[]>) {
state.friends = action.payload;
},

@ -0,0 +1,74 @@
import { Avatar } from '@/components/Avatar';
import { AvatarUploader } from '@/components/AvatarUploader';
import {
DefaultFullModalInputEditorRender,
FullModalField,
} from '@/components/FullModal/Field';
import React from 'react';
import {
modifyUserField,
showToasts,
t,
UploadFileResult,
useAppDispatch,
useAsyncRequest,
userActions,
useUserInfo,
} from 'tailchat-shared';
export const SettingsAccount: React.FC = React.memo(() => {
const userInfo = useUserInfo();
const dispatch = useAppDispatch();
const [, handleUserAvatarChange] = useAsyncRequest(
async (fileInfo: UploadFileResult) => {
await modifyUserField('avatar', fileInfo.url);
dispatch(
userActions.setUserInfoField({
fieldName: 'avatar',
fieldValue: fileInfo.url,
})
);
showToasts(t('修改头像成功'), 'success');
},
[]
);
const [, handleUpdateNickName] = useAsyncRequest(
async (newNickname: string) => {
await modifyUserField('nickname', newNickname);
dispatch(
userActions.setUserInfoField({
fieldName: 'nickname',
fieldValue: newNickname,
})
);
showToasts(t('修改头像成功'), 'success');
},
[]
);
if (!userInfo) {
return null;
}
return (
<div className="flex">
<div className="w-1/3">
<AvatarUploader onUploadSuccess={handleUserAvatarChange}>
<Avatar size={128} src={userInfo.avatar} name={userInfo.nickname} />
</AvatarUploader>
</div>
<div className="w-2/3">
<FullModalField
title={t('用户昵称')}
value={userInfo.nickname}
editable={true}
renderEditor={DefaultFullModalInputEditorRender}
onSave={handleUpdateNickName}
/>
</div>
</div>
);
});
SettingsAccount.displayName = 'SettingsAccount';

@ -3,6 +3,7 @@ import { SidebarView, SidebarViewMenuType } from '@/components/SidebarView';
import React, { useCallback, useMemo } from 'react';
import { t } from 'tailchat-shared';
import { SettingsAbout } from './About';
import { SettingsAccount } from './Account';
import { SettingsStatus } from './Status';
interface SettingsViewProps {
@ -24,6 +25,11 @@ export const SettingsView: React.FC<SettingsViewProps> = React.memo((props) => {
type: 'group',
title: t('通用'),
children: [
{
type: 'item',
title: t('账户信息'),
content: <SettingsAccount />,
},
{
type: 'item',
title: t('服务状态'),

Loading…
Cancel
Save