feat: add friend nickname set model and api

pull/90/head
moonrailgun 2 years ago
parent e0a22e01be
commit 7029e67f0c

@ -59,3 +59,16 @@ export async function removeFriend(friendUserId: string): Promise<void> {
friendUserId,
});
}
/**
*
*/
export async function setFriendNickname(
targetId: string,
nickname: string
): Promise<void> {
await request.post('/api/friend/setFriendNickname', {
targetId,
nickname,
});
}

@ -84,6 +84,16 @@ const userSlice = createSlice({
state.friendRequests.splice(index, 1);
}
},
setFriendNickname(
state,
action: PayloadAction<{ friendId: string; nickname: string }>
) {
const { friendId, nickname } = action.payload;
const target = state.friends.find((f) => f.id === friendId);
if (target) {
target.nickname = nickname;
}
},
},
});

@ -0,0 +1,28 @@
import { Button, ButtonProps } from 'antd';
import React, { useState } from 'react';
interface SubmitButtonProps extends ButtonProps {
onClick: (event: React.MouseEvent) => void | Promise<void>;
}
/**
* Submit Button, use for submit somthing to server
* auto add loading state in onClick
*/
export const SubmitButton: React.FC<SubmitButtonProps> = React.memo((props) => {
const [loading, setLoading] = useState(false);
return (
<Button
loading={loading}
{...props}
onClick={async (e) => {
if (props.onClick) {
setLoading(true);
await props.onClick(e);
setLoading(false);
}
}}
/>
);
});
SubmitButton.displayName = 'SubmitButton';

@ -0,0 +1,73 @@
import React, { useState } from 'react';
import {
isValidStr,
model,
t,
useAppDispatch,
useAppSelector,
useAsyncRequest,
useCachedUserInfo,
userActions,
} from 'tailchat-shared';
import { ModalWrapper } from '../Modal';
import { Button, Input, Space } from 'antd';
import { Problem } from '../Problem';
import { SubmitButton } from '../SubmitButton';
export const SetFriendNickname: React.FC<{
userId: string;
onSuccess?: () => void;
}> = React.memo((props) => {
const userInfo = useCachedUserInfo(props.userId);
const friendInfo = useAppSelector((state) =>
state.user.friends.find((item) => item.id === props.userId)
);
const dispatch = useAppDispatch();
const [nickname, setNickname] = useState(friendInfo?.nickname ?? '');
const [, handleSetFriendNickname] = useAsyncRequest(async () => {
await model.friend.setFriendNickname(props.userId, nickname);
dispatch(
userActions.setFriendNickname({
friendId: props.userId,
nickname,
})
);
props.onSuccess?.();
}, [props.userId, props.onSuccess, nickname]);
if (!friendInfo) {
return <Problem text={t('没有找到该用户信息, 可能出现了一些异常')} />;
}
return (
<ModalWrapper
title={
isValidStr(friendInfo.nickname) ? t('更改好友昵称') : t('添加好友昵称')
}
>
<Space direction="vertical" style={{ width: '100%' }}>
<p>{t('使用个人昵称更快地找到好友。仅您自己可见。')}</p>
<Input
placeholder={userInfo.nickname}
value={nickname}
onChange={(e) => setNickname(e.target.value)}
/>
<Button type="text" onClick={() => setNickname('')}>
{t('重置好友昵称')}
</Button>
<SubmitButton
type="primary"
block={true}
size="large"
onClick={handleSetFriendNickname}
>
{t('确认')}
</SubmitButton>
</Space>
</ModalWrapper>
);
});
SetFriendNickname.displayName = 'SetFriendNickname';

@ -1,6 +1,7 @@
import React, { useCallback } from 'react';
import {
createDMConverse,
isValidStr,
removeFriend,
showAlert,
showErrorToasts,
@ -9,6 +10,7 @@ import {
useAppDispatch,
useAppSelector,
useAsyncRequest,
useEvent,
userActions,
} from 'tailchat-shared';
import { UserListItem } from '@/components/UserListItem';
@ -16,6 +18,8 @@ import { IconBtn } from '@/components/IconBtn';
import { Button, Dropdown, Menu, Tooltip } from 'antd';
import { useNavigate } from 'react-router';
import { Problem } from '@/components/Problem';
import { closeModal, openModal } from '@/components/Modal';
import { SetFriendNickname } from '@/components/modals/SetFriendNickname';
/**
*
@ -35,7 +39,18 @@ export const FriendList: React.FC<{
[navigate]
);
const handleRemoveFriend = useCallback(async (targetId: string) => {
const handleSetFriendNickname = useEvent(async (userId: string) => {
const key = openModal(
<SetFriendNickname
userId={userId}
onSuccess={() => {
closeModal(key);
}}
/>
);
});
const handleRemoveFriend = useEvent(async (targetId: string) => {
showAlert({
message: t(
'是否要从自己的好友列表中删除对方? 注意:你不会从对方的好友列表消失'
@ -50,7 +65,7 @@ export const FriendList: React.FC<{
}
},
});
}, []);
});
if (friends.length === 0) {
return (
@ -88,6 +103,13 @@ export const FriendList: React.FC<{
<Dropdown
menu={{
items: [
{
key: 'setNickname',
onClick: () => handleSetFriendNickname(item.id),
label: isValidStr(item.nickname)
? t('更改好友昵称')
: t('添加好友昵称'),
},
{
key: 'delete',
danger: true,

@ -4,6 +4,7 @@ import type {
FriendModel,
} from '../../../models/user/friend';
import { TcService, TcDbService, TcContext } from 'tailchat-server-sdk';
import { isNil } from 'lodash';
interface FriendService
extends TcService,
@ -33,6 +34,12 @@ class FriendService extends TcService {
targetId: 'string',
},
});
this.registerAction('setFriendNickname', this.setFriendNickname, {
params: {
targetId: 'string',
nickname: 'string',
},
});
}
/**
@ -98,5 +105,32 @@ class FriendService extends TcService {
return isFriend;
}
/**
*
*/
async setFriendNickname(
ctx: TcContext<{ targetId: string; nickname: string }>
) {
const { targetId, nickname } = ctx.params;
const userId = ctx.meta.userId;
const t = ctx.meta.t;
const res = await this.adapter.model.findOneAndUpdate(
{
from: userId,
to: targetId,
},
{
nickname: nickname,
}
);
if (isNil(res)) {
throw new Error(t('设置昵称失败, 没有找到好友关系信息'));
}
return true;
}
}
export default FriendService;

Loading…
Cancel
Save