feat: 好友请求的同意拒绝取消

pull/13/head
moonrailgun 4 years ago
parent cde2d81c5f
commit d7e8b305f9

@ -1,5 +1,5 @@
import { DependencyList, useCallback, useRef, useState } from 'react'; import { DependencyList, useCallback, useRef, useState } from 'react';
import { FunctionReturningPromise, PromiseType } from '../types'; import type { FunctionReturningPromise, PromiseType } from '../types';
import { useMountedState } from './useMountedState'; import { useMountedState } from './useMountedState';
// Reference: https://github.com/streamich/react-use/blob/master/src/useAsyncFn.ts // Reference: https://github.com/streamich/react-use/blob/master/src/useAsyncFn.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<T extends FunctionReturningPromise>(
fn: T,
deps: DependencyList = []
) {
const [{ loading }, call] = useAsyncFn(async (...args) => {
try {
await fn(...args);
} catch (err) {
showErrorToasts(err);
}
}, deps);
return [{ loading }, call] as const;
}

@ -21,6 +21,7 @@ export { t, setLanguage, useTranslation } from './i18n';
// hooks // hooks
export { useAsync } from './hooks/useAsync'; export { useAsync } from './hooks/useAsync';
export { useAsyncFn } from './hooks/useAsyncFn'; export { useAsyncFn } from './hooks/useAsyncFn';
export { useAsyncRequest } from './hooks/useAsyncRequest';
export { useMountedState } from './hooks/useMountedState'; export { useMountedState } from './hooks/useMountedState';
export { useRafState } from './hooks/useRafState'; export { useRafState } from './hooks/useRafState';
@ -37,7 +38,12 @@ export {
} from './manager/ui'; } from './manager/ui';
// model // model
export { addFriendRequest } from './model/friend'; export {
addFriendRequest,
cancelFriendRequest,
acceptFriendRequest,
denyFriendRequest,
} from './model/friend';
export type { FriendRequest } from './model/friend'; export type { FriendRequest } from './model/friend';
export type { UserBaseInfo, UserLoginInfo } from './model/user'; export type { UserBaseInfo, UserLoginInfo } from './model/user';
export { export {

@ -1,6 +1,7 @@
import { request } from '../api/request'; import { request } from '../api/request';
export interface FriendRequest { export interface FriendRequest {
_id: string;
from: string; from: string;
to: string; to: string;
message: string; message: string;
@ -19,3 +20,33 @@ export async function addFriendRequest(
return data; return data;
} }
/**
*
* @param requestId ID
*/
export async function acceptFriendRequest(requestId: string): Promise<void> {
request.post('/api/friend/request/accept', {
requestId,
});
}
/**
*
* @param requestId ID
*/
export async function denyFriendRequest(requestId: string): Promise<void> {
request.post('/api/friend/request/deny', {
requestId,
});
}
/**
*
* @param requestId ID
*/
export async function cancelFriendRequest(requestId: string): Promise<void> {
request.post('/api/friend/request/cancel', {
requestId,
});
}

@ -1,29 +1,59 @@
import { IconBtn } from '@/components/IconBtn'; import { IconBtn } from '@/components/IconBtn';
import { UserListItem } from '@/components/UserListItem'; import { UserListItem } from '@/components/UserListItem';
import { Tooltip } from 'antd'; import { Tooltip } from 'antd';
import { FriendRequest, t } from 'pawchat-shared'; import {
FriendRequest,
t,
acceptFriendRequest,
denyFriendRequest,
useAsyncRequest,
} from 'pawchat-shared';
import React from 'react'; import React from 'react';
export const RequestReceived: React.FC<{ export const RequestReceived: React.FC<{
requests: FriendRequest[]; requests: FriendRequest[];
}> = React.memo((props) => { }> = 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 ( return (
<div className="py-2.5 px-5"> <div className="py-2.5 px-5">
<div></div> <div></div>
<div> <div>
{props.requests.map(({ from }) => ( {props.requests.map(({ _id, from }) => (
<UserListItem <UserListItem
key={from} key={from}
userId={from} userId={from}
actions={[ actions={[
<Tooltip key="accept" title={t('接受')}> <Tooltip key="accept" title={t('接受')}>
<div> <div>
<IconBtn icon="mdi-check" /> <IconBtn
icon="mdi-check"
disabled={loading}
onClick={() => handleAccept(_id)}
/>
</div> </div>
</Tooltip>, </Tooltip>,
<Tooltip key="deny" title={t('拒绝')}> <Tooltip key="deny" title={t('拒绝')}>
<div> <div>
<IconBtn icon="mdi-close" /> <IconBtn
icon="mdi-close"
disabled={loading}
onClick={() => handleDeny(_id)}
/>
</div> </div>
</Tooltip>, </Tooltip>,
]} ]}

@ -1,24 +1,37 @@
import { IconBtn } from '@/components/IconBtn'; import { IconBtn } from '@/components/IconBtn';
import { UserListItem } from '@/components/UserListItem'; import { UserListItem } from '@/components/UserListItem';
import { Tooltip } from 'antd'; import { Tooltip } from 'antd';
import { FriendRequest, t } from 'pawchat-shared'; import {
cancelFriendRequest,
FriendRequest,
t,
useAsyncFn,
} from 'pawchat-shared';
import React from 'react'; import React from 'react';
export const RequestSend: React.FC<{ export const RequestSend: React.FC<{
requests: FriendRequest[]; requests: FriendRequest[];
}> = React.memo((props) => { }> = React.memo((props) => {
const [{ loading }, handleCancel] = useAsyncFn(async (requestId) => {
await cancelFriendRequest(requestId);
}, []);
return ( return (
<div className="py-2.5 px-5"> <div className="py-2.5 px-5">
<div></div> <div></div>
<div> <div>
{props.requests.map(({ to }) => ( {props.requests.map(({ _id, to }) => (
<UserListItem <UserListItem
key={to} key={to}
userId={to} userId={to}
actions={[ actions={[
<Tooltip key="cancel" title={t('取消')}> <Tooltip key="cancel" title={t('取消')}>
<div> <div>
<IconBtn icon="mdi-close" /> <IconBtn
icon="mdi-close"
disabled={loading}
onClick={() => handleCancel(_id)}
/>
</div> </div>
</Tooltip>, </Tooltip>,
]} ]}

Loading…
Cancel
Save