feat: 退出群组

pull/13/head
moonrailgun 4 years ago
parent 1493ade811
commit a9bf936c45

@ -64,6 +64,7 @@ export {
createGroup, createGroup,
createGroupInviteCode, createGroupInviteCode,
getGroupBasicInfo, getGroupBasicInfo,
quitGroup,
applyGroupInvite, applyGroupInvite,
modifyGroupField, modifyGroupField,
createGroupPanel, createGroupPanel,
@ -85,7 +86,11 @@ export {
export { useAppSelector, useAppDispatch } from './redux/hooks/useAppSelector'; export { useAppSelector, useAppDispatch } from './redux/hooks/useAppSelector';
export { useDMConverseList } from './redux/hooks/useConverse'; export { useDMConverseList } from './redux/hooks/useConverse';
export { useConverseMessage } from './redux/hooks/useConverseMessage'; export { useConverseMessage } from './redux/hooks/useConverseMessage';
export { useGroupInfo, useGroupPanel } from './redux/hooks/useGroup'; export {
useGroupInfo,
useGroupPanel,
useIsGroupOwner,
} from './redux/hooks/useGroup';
export { useUserInfo, useUserId } from './redux/hooks/useUserInfo'; export { useUserInfo, useUserId } from './redux/hooks/useUserInfo';
export { userActions } from './redux/slices'; export { userActions } from './redux/slices';
export type { ChatConverseState } from './redux/slices/chat'; export type { ChatConverseState } from './redux/slices/chat';

@ -98,6 +98,17 @@ export async function modifyGroupField(
}); });
} }
/**
* 退()
* socket退
* @param groupId ID
*/
export async function quitGroup(groupId: string) {
await request.post('/api/group/quitGroup', {
groupId,
});
}
/** /**
* *
* 7 * 7

@ -1,6 +1,8 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import type { GroupInfo, GroupPanel } from '../../model/group'; import type { GroupInfo, GroupPanel } from '../../model/group';
import { isValidStr } from '../../utils/string-helper';
import { useAppSelector } from './useAppSelector'; import { useAppSelector } from './useAppSelector';
import { useUserId } from './useUserInfo';
/** /**
* *
@ -23,3 +25,19 @@ export function useGroupPanel(
[groupInfo, panelId] [groupInfo, panelId]
); );
} }
/**
*
* @param userId id
* @param userId id id
*/
export function useIsGroupOwner(groupId: string, userId?: string): boolean {
const groupInfo = useGroupInfo(groupId);
const selfUserId = useUserId();
if (isValidStr(userId)) {
return groupInfo?.owner === userId;
} else {
return typeof selfUserId === 'string' && groupInfo?.owner === selfUserId;
}
}

@ -81,4 +81,8 @@ function listenNotify(socket: AppSocket, store: AppStore) {
socket.listen<GroupInfo>('group.updateInfo', (groupInfo) => { socket.listen<GroupInfo>('group.updateInfo', (groupInfo) => {
store.dispatch(groupActions.updateGroup(groupInfo)); store.dispatch(groupActions.updateGroup(groupInfo));
}); });
socket.listen<{ groupId: string }>('group.remove', ({ groupId }) => {
store.dispatch(groupActions.removeGroup(groupId));
});
} }

@ -26,10 +26,18 @@ const groupSlice = createSlice({
updateGroup(state, action: PayloadAction<GroupInfo>) { updateGroup(state, action: PayloadAction<GroupInfo>) {
const group = action.payload; const group = action.payload;
const groupId = group._id; const groupId = group._id;
state.groups[groupId] = {
...state.groups[groupId], if (state.groups[groupId]) {
...group, // NOTICE: updateGroup 只会去更新,不会去添加新的
}; state.groups[groupId] = {
...state.groups[groupId],
...group,
};
}
},
removeGroup(state, action: PayloadAction<string>) {
const groupId = action.payload;
delete state.groups[groupId];
}, },
}, },
}); });

@ -14,7 +14,7 @@ export const GroupHeader: React.FC<GroupHeaderProps> = React.memo((props) => {
const groupInfo = useGroupInfo(groupId); const groupInfo = useGroupInfo(groupId);
const { t } = useTranslation(); const { t } = useTranslation();
const { handleShowGroupDetail, handleInviteUser } = const { isOwner, handleShowGroupDetail, handleInviteUser, handleQuitGroup } =
useGroupHeaderAction(groupId); useGroupHeaderAction(groupId);
if (_isNil(groupInfo)) { if (_isNil(groupInfo)) {
@ -23,11 +23,20 @@ export const GroupHeader: React.FC<GroupHeaderProps> = React.memo((props) => {
const menu = ( const menu = (
<Menu> <Menu>
<Menu.Item key="0" onClick={handleShowGroupDetail}> {isOwner && (
{t('查看详情')} <Menu.Item key="0" onClick={handleShowGroupDetail}>
</Menu.Item> {t('查看详情')}
<Menu.Item key="1" onClick={handleInviteUser}> </Menu.Item>
{t('邀请用户')} )}
{isOwner && (
<Menu.Item key="1" onClick={handleInviteUser}>
{t('邀请用户')}
</Menu.Item>
)}
<Menu.Item key="2" danger={true} onClick={handleQuitGroup}>
{t('退出群组')}
</Menu.Item> </Menu.Item>
</Menu> </Menu>
); );

@ -3,11 +3,16 @@ import { GroupDetail } from '@/components/modals/GroupDetail';
import { GroupInvite } from '@/components/modals/GroupInvite'; import { GroupInvite } from '@/components/modals/GroupInvite';
import React from 'react'; import React from 'react';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useHistory } from 'react-router';
import { quitGroup, showAlert, t, useIsGroupOwner } from 'tailchat-shared';
/** /**
* Header hooks * Header hooks
*/ */
export function useGroupHeaderAction(groupId: string) { export function useGroupHeaderAction(groupId: string) {
const isOwner = useIsGroupOwner(groupId);
const history = useHistory();
const handleShowGroupDetail = useCallback(() => { const handleShowGroupDetail = useCallback(() => {
const key = openModal( const key = openModal(
<GroupDetail <GroupDetail
@ -23,5 +28,17 @@ export function useGroupHeaderAction(groupId: string) {
openModal(<GroupInvite groupId={groupId} />); openModal(<GroupInvite groupId={groupId} />);
}, [groupId]); }, [groupId]);
return { handleShowGroupDetail, handleInviteUser }; const handleQuitGroup = useCallback(() => {
showAlert({
message: isOwner
? t('您是群组管理者,退出群组会导致解散群组')
: t('确定要退出群组么?'),
async onConfirm() {
await quitGroup(groupId);
history.replace('/main'); // 返回到主页
},
});
}, [groupId, isOwner]);
return { isOwner, handleShowGroupDetail, handleInviteUser, handleQuitGroup };
} }

Loading…
Cancel
Save