You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/client/shared/event/index.ts

90 lines
2.0 KiB
TypeScript

import { useEffect } from 'react';
import { useUpdateRef } from '../hooks/useUpdateRef';
import type { ChatMessage, SendMessagePayload } from '../model/message';
import { EventEmitter } from 'eventemitter-strict';
import type { UserBaseInfo } from '../model/user';
/**
* 共享事件类型
*/
export interface SharedEventMap {
/**
* 登录成功
*/
loginSuccess: (userInfo: UserBaseInfo) => void;
/**
* 修改配色方案
*/
loadColorScheme: (schemeName: string) => void;
/**
* 网络状态更新
*/
updateNetworkStatus: (
status: 'connected' | 'reconnecting' | 'disconnected'
) => void;
/**
* 发送消息
*/
sendMessage: (payload: SendMessagePayload) => void;
/**
* 回复消息事件
*
* 如果为null则是清空
*/
replyMessage: (payload: ChatMessage | null) => void;
/**
* 消息已读(消息出现在界面上)
*/
readMessage: (payload: ChatMessage | null) => void;
/**
* 群组面板状态更新
*/
groupPanelBadgeUpdate: () => void;
}
export type SharedEventType = keyof SharedEventMap;
const bus = new EventEmitter<SharedEventMap>();
/**
* 事件中心
*/
export const sharedEvent = {
on<T extends SharedEventType>(eventName: T, listener: SharedEventMap[T]) {
bus.on(eventName, listener);
},
off<T extends SharedEventType>(eventName: T, listener: SharedEventMap[T]) {
bus.off(eventName, listener);
},
emit<T extends SharedEventType>(
eventName: T,
...args: Parameters<SharedEventMap[T]>
) {
bus.emit(eventName, ...args);
},
};
export function useSharedEventHandler<
T extends SharedEventType,
H extends SharedEventMap[T]
>(eventName: T, handler: H) {
const handlerRef = useUpdateRef(handler);
useEffect(() => {
const _handler: SharedEventMap[T] = (...args: any[]) => {
(handlerRef.current as any)(...args);
};
sharedEvent.on(eventName, _handler);
return () => {
sharedEvent.off(eventName, _handler);
};
}, []);
}