mirror of https://github.com/fantasticit/think.git
feat: add global event center
This commit is contained in:
parent
a8d9f41734
commit
11ce42dbe3
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -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';
|
||||
|
|
|
@ -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 }) => {
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -39,5 +39,3 @@ export class EventEmitter {
|
|||
this.callbacks = {};
|
||||
}
|
||||
}
|
||||
|
||||
export const event = new EventEmitter();
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"layout/*": ["layout/*"],
|
||||
"constants/*": ["constants/*"],
|
||||
"helpers/*": ["helpers/*"],
|
||||
"tiptap/*": ["tiptap/*"]
|
||||
"tiptap/*": ["tiptap/*"],
|
||||
"event/*": ["event/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
|
|
Loading…
Reference in New Issue