From f9f7c6ac9aefd842657b982e4685cda839b67971 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Thu, 21 Apr 2022 21:45:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=9E=E5=A4=8D=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=97=B6=E8=81=9A=E7=84=A6=E6=B6=88=E6=81=AF=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=A1=86=E5=B9=B6=E8=87=AA=E5=8A=A8=E5=9C=A8=E5=89=8D=E9=9D=A2?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E8=A2=AB=E8=89=BE=E7=89=B9=E7=9A=84=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/event/index.ts | 30 ++++++++++++++++++- shared/index.tsx | 2 +- .../components/ChatBox/ChatInputBox/index.tsx | 23 +++++++++++++- .../useChatMessageItemAction.tsx | 3 +- web/src/components/ChatBox/ChatReply.tsx | 12 ++++++-- 5 files changed, 64 insertions(+), 6 deletions(-) diff --git a/shared/event/index.ts b/shared/event/index.ts index 3e755012..a1b0387a 100644 --- a/shared/event/index.ts +++ b/shared/event/index.ts @@ -1,5 +1,7 @@ import { EventEmitter } from 'events'; -import type { SendMessagePayload } from '../model/message'; +import { useEffect } from 'react'; +import { useUpdateRef } from '../hooks/useUpdateRef'; +import type { ChatMessage, SendMessagePayload } from '../model/message'; /** * 共享事件类型 @@ -21,6 +23,13 @@ export interface SharedEventMap { * 发送消息 */ sendMessage: (payload: SendMessagePayload) => void; + + /** + * 回复消息事件 + * + * 如果为null则是清空 + */ + replyMessage: (payload: ChatMessage | null) => void; } export type SharedEventType = keyof SharedEventMap; @@ -43,3 +52,22 @@ export const sharedEvent = { 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); + }; + }, []); +} diff --git a/shared/index.tsx b/shared/index.tsx index 8a26eaa1..86cadedc 100644 --- a/shared/index.tsx +++ b/shared/index.tsx @@ -30,7 +30,7 @@ export { } from './contexts/GroupInfoContext'; // event -export { sharedEvent } from './event/index'; +export { sharedEvent, useSharedEventHandler } from './event/index'; // helper export { getDMConverseName } from './helper/converse-helper'; diff --git a/web/src/components/ChatBox/ChatInputBox/index.tsx b/web/src/components/ChatBox/ChatInputBox/index.tsx index 0fc58d5d..0480a3c7 100644 --- a/web/src/components/ChatBox/ChatInputBox/index.tsx +++ b/web/src/components/ChatBox/ChatInputBox/index.tsx @@ -6,7 +6,12 @@ import { ClipboardHelper } from './clipboard-helper'; import { ChatInputActionContext } from './context'; import { uploadMessageImage } from './utils'; import { ChatInputBoxInput } from './input'; -import type { SendMessagePayloadMeta } from 'tailchat-shared'; +import { + getCachedUserInfo, + isValidStr, + SendMessagePayloadMeta, + useSharedEventHandler, +} from 'tailchat-shared'; interface ChatInputBoxProps { onSendMsg: (msg: string, meta?: SendMessagePayloadMeta) => void; @@ -50,6 +55,22 @@ export const ChatInputBox: React.FC = React.memo((props) => { [props.onSendMsg] ); + useSharedEventHandler('replyMessage', async (payload) => { + if (inputRef.current) { + inputRef.current.focus(); + console.log(payload); + if (payload && isValidStr(payload?.author)) { + const userInfo = await getCachedUserInfo(payload.author); + setMessage( + `${getMessageTextDecorators().mention( + payload.author, + userInfo.nickname + )} ${message}` + ); + } + } + }); + return (
diff --git a/web/src/components/ChatBox/ChatMessageList/useChatMessageItemAction.tsx b/web/src/components/ChatBox/ChatMessageList/useChatMessageItemAction.tsx index 4b047730..af76af54 100644 --- a/web/src/components/ChatBox/ChatMessageList/useChatMessageItemAction.tsx +++ b/web/src/components/ChatBox/ChatMessageList/useChatMessageItemAction.tsx @@ -5,6 +5,7 @@ import { ChatMessage, deleteMessage, recallMessage, + sharedEvent, t, useAsyncRequest, useChatBoxContext, @@ -45,7 +46,7 @@ export function useChatMessageItemAction( } - onClick={() => context.setReplyMsg(payload)} + onClick={() => sharedEvent.emit('replyMessage', payload)} > {t('回复')} diff --git a/web/src/components/ChatBox/ChatReply.tsx b/web/src/components/ChatBox/ChatReply.tsx index 11605faa..2af03400 100644 --- a/web/src/components/ChatBox/ChatReply.tsx +++ b/web/src/components/ChatBox/ChatReply.tsx @@ -1,12 +1,20 @@ import React from 'react'; -import { t, useChatBoxContext } from 'tailchat-shared'; +import { t, useChatBoxContext, useSharedEventHandler } from 'tailchat-shared'; import _isNil from 'lodash/isNil'; import { getMessageRender } from '@/plugin/common'; import { UserName } from '../UserName'; import { Icon } from '@/components/Icon'; export const ChatReply: React.FC = React.memo(() => { - const { replyMsg, clearReplyMsg } = useChatBoxContext(); + const { replyMsg, setReplyMsg, clearReplyMsg } = useChatBoxContext(); + + useSharedEventHandler('replyMessage', (payload) => { + /** + * 这里故意在本组件设置回复消息体而不是在事件发起方设置是为了确保当本组件不存在时 + * 不会出现回复消息的值呗设置的情况 + */ + setReplyMsg(payload); + }); if (_isNil(replyMsg)) { return null;