feat: 回复消息时聚焦消息输入框并自动在前面追加被艾特的人

release/desktop
moonrailgun 3 years ago
parent a868c2abb7
commit f9f7c6ac9a

@ -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);
};
}, []);
}

@ -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';

@ -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<ChatInputBoxProps> = 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 (
<ChatInputActionContext.Provider value={{ sendMsg: props.onSendMsg }}>
<div className="px-4 py-2">

@ -5,6 +5,7 @@ import {
ChatMessage,
deleteMessage,
recallMessage,
sharedEvent,
t,
useAsyncRequest,
useChatBoxContext,
@ -45,7 +46,7 @@ export function useChatMessageItemAction(
<Menu.Item
key="reply"
icon={<Icon icon="mdi:reply" />}
onClick={() => context.setReplyMsg(payload)}
onClick={() => sharedEvent.emit('replyMessage', payload)}
>
{t('回复')}
</Menu.Item>

@ -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;

Loading…
Cancel
Save