From d7e8b305f9b282eb16ecd45fe139b660e8e5c1c2 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Mon, 12 Jul 2021 23:07:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A5=BD=E5=8F=8B=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E6=84=8F=E6=8B=92=E7=BB=9D=E5=8F=96=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/hooks/useAsyncFn.ts | 2 +- shared/hooks/useAsyncRequest.ts | 19 ++++++++++ shared/index.tsx | 8 +++- shared/model/friend.ts | 31 +++++++++++++++ .../Personal/Friends/RequestReceived.tsx | 38 +++++++++++++++++-- .../Content/Personal/Friends/RequestSend.tsx | 19 ++++++++-- 6 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 shared/hooks/useAsyncRequest.ts diff --git a/shared/hooks/useAsyncFn.ts b/shared/hooks/useAsyncFn.ts index 6abda2ed..0cd63224 100644 --- a/shared/hooks/useAsyncFn.ts +++ b/shared/hooks/useAsyncFn.ts @@ -1,5 +1,5 @@ import { DependencyList, useCallback, useRef, useState } from 'react'; -import { FunctionReturningPromise, PromiseType } from '../types'; +import type { FunctionReturningPromise, PromiseType } from '../types'; import { useMountedState } from './useMountedState'; // Reference: https://github.com/streamich/react-use/blob/master/src/useAsyncFn.ts diff --git a/shared/hooks/useAsyncRequest.ts b/shared/hooks/useAsyncRequest.ts new file mode 100644 index 00000000..68cb71d0 --- /dev/null +++ b/shared/hooks/useAsyncRequest.ts @@ -0,0 +1,19 @@ +import type { DependencyList } from 'react'; +import { showErrorToasts } from '../manager/ui'; +import type { FunctionReturningPromise } from '../types'; +import { useAsyncFn } from './useAsyncFn'; + +export function useAsyncRequest( + fn: T, + deps: DependencyList = [] +) { + const [{ loading }, call] = useAsyncFn(async (...args) => { + try { + await fn(...args); + } catch (err) { + showErrorToasts(err); + } + }, deps); + + return [{ loading }, call] as const; +} diff --git a/shared/index.tsx b/shared/index.tsx index db3dfde8..092d3966 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -21,6 +21,7 @@ export { t, setLanguage, useTranslation } from './i18n'; // hooks export { useAsync } from './hooks/useAsync'; export { useAsyncFn } from './hooks/useAsyncFn'; +export { useAsyncRequest } from './hooks/useAsyncRequest'; export { useMountedState } from './hooks/useMountedState'; export { useRafState } from './hooks/useRafState'; @@ -37,7 +38,12 @@ export { } from './manager/ui'; // model -export { addFriendRequest } from './model/friend'; +export { + addFriendRequest, + cancelFriendRequest, + acceptFriendRequest, + denyFriendRequest, +} from './model/friend'; export type { FriendRequest } from './model/friend'; export type { UserBaseInfo, UserLoginInfo } from './model/user'; export { diff --git a/shared/model/friend.ts b/shared/model/friend.ts index 604b8d25..78c59e63 100644 --- a/shared/model/friend.ts +++ b/shared/model/friend.ts @@ -1,6 +1,7 @@ import { request } from '../api/request'; export interface FriendRequest { + _id: string; from: string; to: string; message: string; @@ -19,3 +20,33 @@ export async function addFriendRequest( return data; } + +/** + * 同意好友请求 + * @param requestId 好友请求ID + */ +export async function acceptFriendRequest(requestId: string): Promise { + request.post('/api/friend/request/accept', { + requestId, + }); +} + +/** + * 拒绝好友请求 + * @param requestId 好友请求ID + */ +export async function denyFriendRequest(requestId: string): Promise { + request.post('/api/friend/request/deny', { + requestId, + }); +} + +/** + * 取消好友请求 + * @param requestId 好友请求ID + */ +export async function cancelFriendRequest(requestId: string): Promise { + request.post('/api/friend/request/cancel', { + requestId, + }); +} diff --git a/web/src/routes/Main/Content/Personal/Friends/RequestReceived.tsx b/web/src/routes/Main/Content/Personal/Friends/RequestReceived.tsx index 035a514c..7d7d79e9 100644 --- a/web/src/routes/Main/Content/Personal/Friends/RequestReceived.tsx +++ b/web/src/routes/Main/Content/Personal/Friends/RequestReceived.tsx @@ -1,29 +1,59 @@ import { IconBtn } from '@/components/IconBtn'; import { UserListItem } from '@/components/UserListItem'; import { Tooltip } from 'antd'; -import { FriendRequest, t } from 'pawchat-shared'; +import { + FriendRequest, + t, + acceptFriendRequest, + denyFriendRequest, + useAsyncRequest, +} from 'pawchat-shared'; import React from 'react'; export const RequestReceived: React.FC<{ requests: FriendRequest[]; }> = React.memo((props) => { + const [{ loading: acceptLoading }, handleAccept] = useAsyncRequest( + async (requestId) => { + await acceptFriendRequest(requestId); + }, + [] + ); + + const [{ loading: denyLoading }, handleDeny] = useAsyncRequest( + async (requestId) => { + await denyFriendRequest(requestId); + }, + [] + ); + + const loading = acceptLoading || denyLoading; + return (
等待处理的好友请求
- {props.requests.map(({ from }) => ( + {props.requests.map(({ _id, from }) => (
- + handleAccept(_id)} + />
,
- + handleDeny(_id)} + />
, ]} diff --git a/web/src/routes/Main/Content/Personal/Friends/RequestSend.tsx b/web/src/routes/Main/Content/Personal/Friends/RequestSend.tsx index 3888699b..32e5589e 100644 --- a/web/src/routes/Main/Content/Personal/Friends/RequestSend.tsx +++ b/web/src/routes/Main/Content/Personal/Friends/RequestSend.tsx @@ -1,24 +1,37 @@ import { IconBtn } from '@/components/IconBtn'; import { UserListItem } from '@/components/UserListItem'; import { Tooltip } from 'antd'; -import { FriendRequest, t } from 'pawchat-shared'; +import { + cancelFriendRequest, + FriendRequest, + t, + useAsyncFn, +} from 'pawchat-shared'; import React from 'react'; export const RequestSend: React.FC<{ requests: FriendRequest[]; }> = React.memo((props) => { + const [{ loading }, handleCancel] = useAsyncFn(async (requestId) => { + await cancelFriendRequest(requestId); + }, []); + return (
等待对方处理的好友请求
- {props.requests.map(({ to }) => ( + {props.requests.map(({ _id, to }) => (
- + handleCancel(_id)} + />
, ]}