feat: 创建群组面板

pull/13/head
moonrailgun 4 years ago
parent 9a3a0868ac
commit dffd9afa9d

@ -2,6 +2,8 @@ import { io, Socket } from 'socket.io-client';
import _isNil from 'lodash/isNil';
import { getServiceUrl } from '../manager/service';
import { isDevelopment } from '../utils/environment';
import { showToasts } from '../manager/ui';
import { t } from '../i18n';
let socket: Socket;
@ -88,7 +90,13 @@ export function createSocket(token: string): Promise<AppSocket> {
socket.once('connect', () => {
// 连接成功
const appSocket = new AppSocket(socket);
appSocket.request('chat.converse.findAndJoinRoom'); // 立即请求加入房间
appSocket.request('chat.converse.findAndJoinRoom').catch((err) => {
console.error(err);
showToasts(
t('无法加入房间, 您将无法获取到最新的信息, 请刷新页面后重试'),
'error'
);
}); // 立即请求加入房间
resolve(appSocket);
});
socket.once('error', () => {

@ -0,0 +1,8 @@
import { useRef, MutableRefObject } from 'react';
export function useUpdateRef<T>(state: T): MutableRefObject<T> {
const ref = useRef<T>(state);
ref.current = state;
return ref;
}

@ -33,6 +33,7 @@ export { useAsyncFn } from './hooks/useAsyncFn';
export { useAsyncRequest } from './hooks/useAsyncRequest';
export { useMountedState } from './hooks/useMountedState';
export { useRafState } from './hooks/useRafState';
export { useUpdateRef } from './hooks/useUpdateRef';
// manager
export { getStorage, setStorage, useStorage } from './manager/storage';

@ -135,3 +135,22 @@ export async function applyGroupInvite(inviteCode: string): Promise<void> {
code: inviteCode,
});
}
/**
*
*/
export async function createGroupPanel(
groupId: string,
options: {
name: string;
type: number;
parentId?: string;
provider?: string;
meta?: Record<string, unknown>;
}
) {
await request.post('/api/group/createGroupPanel', {
...options,
groupId,
});
}

@ -1,13 +1,68 @@
import React from 'react';
import { t } from 'tailchat-shared';
import {
FastFormFieldMeta,
GroupPanelType,
t,
useAsyncRequest,
} from 'tailchat-shared';
import { createGroupPanel } from '../../../../shared/model/group';
import { ModalWrapper } from '../Modal';
import { WebFastForm } from '../WebFastForm';
type Values = {
name: string;
type: string;
};
const baseFields: FastFormFieldMeta[] = [
{ type: 'text', name: 'name', label: t('面板名') },
{
type: 'select',
name: 'type',
label: t('类型'),
options: [
{
label: t('聊天频道'),
value: GroupPanelType.TEXT,
},
{
label: t('面板分组'),
value: GroupPanelType.GROUP,
},
],
},
];
/**
*
*/
export const ModalCreateGroupPanel: React.FC<{
groupId: string;
onCreateSuccess: () => void;
}> = React.memo((props) => {
const [, handleSubmit] = useAsyncRequest(
async (values: Values) => {
const { name, type } = values;
let panelType: number;
if (typeof type === 'string') {
panelType = GroupPanelType.PLUGIN;
} else {
panelType = type;
}
await createGroupPanel(props.groupId, {
name,
type: panelType,
});
props.onCreateSuccess();
},
[props.groupId, props.onCreateSuccess]
);
return (
<ModalWrapper title={t('创建群组面板')}>
: {props.groupId}
<ModalWrapper title={t('创建群组面板')} style={{ width: 440 }}>
<WebFastForm fields={baseFields} onSubmit={handleSubmit} />
</ModalWrapper>
);
});

@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
useGroupInfo,
GroupPanel as GroupPanelInfo,
@ -11,7 +11,7 @@ import { Button } from 'antd';
import _isEqual from 'lodash/isEqual';
import { GroupPanelTree } from './GroupPanelTree';
import { FullModalCommonTitle } from '@/components/FullModal/CommonTitle';
import { openModal } from '@/components/Modal';
import { closeModal, openModal } from '@/components/Modal';
import { ModalCreateGroupPanel } from '../../CreateGroupPanel';
export const GroupPanel: React.FC<{
@ -21,34 +21,50 @@ export const GroupPanel: React.FC<{
const groupInfo = useGroupInfo(groupId);
const groupPanels = groupInfo?.panels ?? [];
const [editingGroupPanels, setEditingGroupPanels] = useState(groupPanels);
const isEditingRef = useRef(false);
useEffect(() => {
// 如果不处于编辑状态, 则一直更新最新的面板
if (isEditingRef.current === true) {
return;
}
setEditingGroupPanels(groupPanels);
}, [groupPanels]);
const handleChange = useCallback((newGroupPanels: GroupPanelInfo[]) => {
isEditingRef.current = true;
setEditingGroupPanels(newGroupPanels);
}, []);
const [{ loading }, handleSave] = useAsyncRequest(async () => {
await modifyGroupField(groupId, 'panels', editingGroupPanels);
isEditingRef.current = false;
showToasts(t('保存成功'), 'success');
}, [editingGroupPanels]);
const [{ loading: createLoading }, handleCreatePanel] =
useAsyncRequest(async () => {
// TODO
}, []);
const handleReset = useCallback(() => {
setEditingGroupPanels(groupPanels);
isEditingRef.current = false;
}, [groupPanels]);
const handleOpenCreatePanelModal = useCallback(() => {
openModal(<ModalCreateGroupPanel groupId={groupId} />);
}, [handleCreatePanel]);
const key = openModal(
<ModalCreateGroupPanel
groupId={groupId}
onCreateSuccess={() => {
closeModal(key);
isEditingRef.current = false;
}}
/>
);
}, []);
return (
<div>
<FullModalCommonTitle
extra={
<Button
type="primary"
loading={createLoading}
onClick={handleOpenCreatePanelModal}
>
<Button type="primary" onClick={handleOpenCreatePanelModal}>
{t('创建面板')}
</Button>
}
@ -62,9 +78,12 @@ export const GroupPanel: React.FC<{
/>
{!_isEqual(groupPanels, editingGroupPanels) && (
<Button className="mt-2" loading={loading} onClick={handleSave}>
{t('保存')}
</Button>
<div className="space-x-1 mt-2">
<Button type="primary" loading={loading} onClick={handleSave}>
{t('保存')}
</Button>
<Button onClick={handleReset}>{t('重置')}</Button>
</div>
)}
</div>
);

Loading…
Cancel
Save