feat: add global event center

pull/25/head
fantasticit 2022-04-03 11:06:21 +08:00
parent a8d9f41734
commit 11ce42dbe3
11 changed files with 72 additions and 65 deletions

View File

@ -17,11 +17,11 @@ import {
} from '@douyinfe/semi-ui';
import { IconUserAdd, IconDelete } from '@douyinfe/semi-icons';
import { useUser } from 'data/user';
import { EventEmitter } from 'helpers/event-emitter';
import { useToggle } from 'hooks/use-toggle';
import { useCollaborationDocument } from 'data/document';
import { DataRender } from 'components/data-render';
import { DocumentLinkCopyer } from 'components/document/link';
import { event, JOIN_USER } from 'event';
interface IProps {
wikiId: string;
@ -31,13 +31,6 @@ interface IProps {
const { Paragraph } = Typography;
const { Column } = Table;
const CollaborationEventEmitter = new EventEmitter();
const KEY = 'JOIN_USER';
export const joinUser = (users) => {
CollaborationEventEmitter.emit(KEY, users);
};
const renderChecked = (onChange, authKey: 'readable' | 'editable') => (checked, docAuth) => {
const handle = (evt) => {
const data = {
@ -56,7 +49,6 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
const [visible, toggleVisible] = useToggle(false);
const { users, loading, error, addUser, updateUser, deleteUser } = useCollaborationDocument(documentId);
const [inviteUser, setInviteUser] = useState('');
const [collaborationUsers, setCollaborationUsers] = useState([]);
const handleOk = () => {
@ -75,7 +67,7 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
};
useEffect(() => {
CollaborationEventEmitter.on(KEY, ({ states: users }) => {
const handler = (users) => {
const newCollaborationUsers = users
.filter(Boolean)
.filter((state) => state.user)
@ -97,10 +89,11 @@ export const DocumentCollaboration: React.FC<IProps> = ({ wikiId, documentId })
});
setCollaborationUsers(newCollaborationUsers);
});
};
event.on(JOIN_USER, handler);
return () => {
CollaborationEventEmitter.destroy();
event.off(JOIN_USER, handler);
};
}, [collaborationUsers, currentUser]);

View File

@ -3,7 +3,7 @@ import Router from 'next/router';
import { Typography, Space, Modal } from '@douyinfe/semi-ui';
import { IconDelete } from '@douyinfe/semi-icons';
import { useDeleteDocument } from 'data/document';
import { triggerRefreshTocs } from 'components/wiki/tocs/event';
import { triggerRefreshTocs } from 'event';
interface IProps {
wikiId: string;

View File

@ -18,10 +18,9 @@ import {
destoryIndexdbProvider,
} from 'tiptap';
import { DataRender } from 'components/data-render';
import { joinUser } from 'components/document/collaboration';
import { Banner } from 'components/banner';
import { debounce } from 'helpers/debounce';
import { em, changeTitle, USE_DATA_VERSION } from './index';
import { event, triggerChangeDocumentTitle, triggerJoinUser, USE_DOCUMENT_VERSION } from 'event';
import styles from './index.module.scss';
interface IProps {
@ -45,7 +44,7 @@ export const Editor: React.FC<IProps> = ({ user, documentId, authority, classNam
docType: 'document',
events: {
onAwarenessUpdate({ states }) {
joinUser({ states });
triggerJoinUser(states);
},
},
});
@ -62,7 +61,7 @@ export const Editor: React.FC<IProps> = ({ user, documentId, authority, classNam
onTransaction: debounce(({ transaction }) => {
try {
const title = transaction.doc.content.firstChild.content.firstChild.textContent;
changeTitle(title);
triggerChangeDocumentTitle(title);
} catch (e) {}
}, 50),
});
@ -92,10 +91,9 @@ export const Editor: React.FC<IProps> = ({ user, documentId, authority, classNam
useEffect(() => {
if (!editor) return;
const handler = (data) => editor.commands.setContent(data);
em.on(USE_DATA_VERSION, handler);
event.on(USE_DOCUMENT_VERSION, handler);
return () => {
em.off(USE_DATA_VERSION, handler);
event.off(USE_DOCUMENT_VERSION, handler);
};
}, [editor]);

View File

@ -16,24 +16,12 @@ import { DocumentVersion } from 'components/document/version';
import { User } from 'components/user';
import { Divider } from 'components/divider';
import { useDocumentStyle } from 'hooks/use-document-style';
import { EventEmitter } from 'helpers/event-emitter';
import { event, CHANGE_DOCUMENT_TITLE, triggerUseDocumentVersion } from 'event';
import { Editor } from './editor';
import styles from './index.module.scss';
const { Text } = Typography;
export const em = new EventEmitter();
const TITLE_CHANGE_EVENT = 'TITLE_CHANGE_EVENT';
export const USE_DATA_VERSION = 'USE_DATA_VERSION';
export const changeTitle = (title) => {
em.emit(TITLE_CHANGE_EVENT, title);
};
const useVersion = (data) => {
em.emit(USE_DATA_VERSION, data);
};
interface IProps {
documentId: string;
}
@ -77,10 +65,10 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
);
useEffect(() => {
em.on(TITLE_CHANGE_EVENT, setTitle);
event.on(CHANGE_DOCUMENT_TITLE, setTitle);
return () => {
em.destroy();
event.off(CHANGE_DOCUMENT_TITLE, setTitle);
};
}, []);
@ -97,7 +85,7 @@ export const DocumentEditor: React.FC<IProps> = ({ documentId }) => {
<DocumentCollaboration key="collaboration" wikiId={document.wikiId} documentId={documentId} />
)}
<DocumentShare key="share" documentId={documentId} />
<DocumentVersion key="version" documentId={documentId} onSelect={useVersion} />
<DocumentVersion key="version" documentId={documentId} onSelect={triggerUseDocumentVersion} />
<DocumentStar key="star" documentId={documentId} />
<Popover key="style" zIndex={1061} position="bottomLeft" content={<DocumentStyle />}>
<Button icon={<IconArticle />} theme="borderless" type="tertiary" />

View File

@ -14,7 +14,7 @@ import {
} from 'tiptap';
import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer';
import { joinUser } from 'components/document/collaboration';
import { triggerJoinUser } from 'event';
import { CreateUser } from './user';
import styles from './index.module.scss';
@ -36,7 +36,7 @@ export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
docType: 'document',
events: {
onAwarenessUpdate({ states }) {
joinUser({ states });
triggerJoinUser(states);
},
},
});

View File

@ -1,20 +0,0 @@
import { IDocument, IWiki } from '@think/domains';
import { event } from 'helpers/event-emitter';
export const REFRESH_TOCS = `REFRESH_TOCS`; // 刷新知识库目录
export const CREATE_DOCUMENT = `CREATE_DOCUMENT`;
/**
*
*/
export const triggerRefreshTocs = () => {
event.emit(REFRESH_TOCS);
};
/**
*
* @param data
*/
export const triggerCreateDocument = (data: { wikiId: IWiki['id']; documentId: IDocument['id'] | null }) => {
event.emit(CREATE_DOCUMENT, data);
};

View File

@ -9,8 +9,7 @@ import { Seo } from 'components/seo';
import { findParents } from 'components/wiki/tocs/utils';
import { IconDocument, IconSetting, IconOverview, IconGlobe } from 'components/icons';
import { DataRender } from 'components/data-render';
import { event } from 'helpers/event-emitter';
import { REFRESH_TOCS, triggerCreateDocument } from './event';
import { event, REFRESH_TOCS, triggerCreateDocument } from 'event';
import { NavItem } from './nav-item';
import { Tree } from './tree';
import styles from './index.module.scss';

View File

@ -5,8 +5,7 @@ import { IconMore, IconPlus } from '@douyinfe/semi-icons';
import { useToggle } from 'hooks/use-toggle';
import { DocumentActions } from 'components/document/actions';
import { DocumentCreator as DocumenCreatorForm } from 'components/document/create';
import { event } from 'helpers/event-emitter';
import { CREATE_DOCUMENT, triggerCreateDocument } from './event';
import { event, CREATE_DOCUMENT, triggerCreateDocument } from 'event';
import styles from './index.module.scss';
const Actions = ({ node }) => {

View File

@ -0,0 +1,51 @@
import { IUser, IDocument, IWiki } from '@think/domains';
import { EventEmitter } from 'helpers/event-emitter';
export const event = new EventEmitter();
export const REFRESH_TOCS = `REFRESH_TOCS`; // 刷新知识库目录
export const CREATE_DOCUMENT = `CREATE_DOCUMENT`;
/**
*
*/
export const triggerRefreshTocs = () => {
event.emit(REFRESH_TOCS);
};
/**
*
* @param data
*/
export const triggerCreateDocument = (data: { wikiId: IWiki['id']; documentId: IDocument['id'] | null }) => {
event.emit(CREATE_DOCUMENT, data);
};
export const CHANGE_DOCUMENT_TITLE = `CHANGE_DOCUMENT_TITLE`;
/**
*
* @param title
*/
export const triggerChangeDocumentTitle = (title: string) => {
event.emit(CHANGE_DOCUMENT_TITLE, title);
};
export const USE_DOCUMENT_VERSION = `USE_DOCUMENT_VERSION`;
/**
* 使
* @param data
*/
export const triggerUseDocumentVersion = (data: Record<string, unknown>) => {
event.emit(USE_DOCUMENT_VERSION, data);
};
export const JOIN_USER = `JOIN_USER`;
type CollaborationUser = {
clientId: number;
user: IUser;
};
/**
*
* @param users
*/
export const triggerJoinUser = (users: Array<CollaborationUser>) => {
event.emit(JOIN_USER, users);
};

View File

@ -39,5 +39,3 @@ export class EventEmitter {
this.callbacks = {};
}
}
export const event = new EventEmitter();

View File

@ -26,7 +26,8 @@
"layout/*": ["layout/*"],
"constants/*": ["constants/*"],
"helpers/*": ["helpers/*"],
"tiptap/*": ["tiptap/*"]
"tiptap/*": ["tiptap/*"],
"event/*": ["event/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],