feat: 增加取消reaction的操作

pull/81/head
moonrailgun 4 years ago
parent a76f52228d
commit 55e13f7851

@ -115,7 +115,12 @@ export {
deleteGroupPanel,
} from './model/group';
export type { GroupPanel, GroupInfo, GroupBasicInfo } from './model/group';
export { recallMessage, deleteMessage, addReaction } from './model/message';
export {
recallMessage,
deleteMessage,
addReaction,
removeReaction,
} from './model/message';
export type { ChatMessageReaction, ChatMessage } from './model/message';
export type { PluginManifest } from './model/plugin';
export type { UserBaseInfo, UserLoginInfo } from './model/user';

@ -118,3 +118,18 @@ export async function addReaction(
return data;
}
/**
*
*/
export async function removeReaction(
messageId: string,
emoji: string
): Promise<boolean> {
const { data } = await request.post('/api/chat/message/removeReaction', {
messageId,
emoji,
});
return data;
}

@ -199,6 +199,20 @@ function listenNotify(socket: AppSocket, store: AppStore) {
);
});
socket.listen<{
converseId: string;
messageId: string;
reaction: ChatMessageReaction;
}>('chat.message.removeReaction', ({ converseId, messageId, reaction }) => {
store.dispatch(
chatActions.removeMessageReaction({
converseId,
messageId,
reaction,
})
);
});
socket.listen<ChatConverseInfo>(
'chat.converse.updateDMConverse',
(converse) => {

@ -261,6 +261,40 @@ const chatSlice = createSlice({
message.reactions.push(reaction);
},
/**
*
*/
removeMessageReaction(
state,
action: PayloadAction<{
converseId: string;
messageId: string;
reaction: ChatMessageReaction;
}>
) {
const { converseId, messageId, reaction } = action.payload;
const converse = state.converses[converseId];
if (!converse) {
console.warn('Not found converse,', converseId);
return;
}
const message = converse.messages.find((m) => m._id === messageId);
if (!message) {
console.warn('Not found message,', messageId);
return;
}
if (!Array.isArray(message.reactions)) {
message.reactions = [];
}
const reactionIndex = message.reactions.findIndex(
(r) => r.name === reaction.name && r.author === reaction.author
);
message.reactions.splice(reactionIndex, 1);
},
},
});

@ -19,7 +19,7 @@ import { Divider, Dropdown } from 'antd';
import { UserName } from '@/components/UserName';
import clsx from 'clsx';
import { useChatMessageItemAction } from './useChatMessageItemAction';
import { useChatMessageReaction } from './useChatMessageReaction';
import { useChatMessageReactionAction } from './useChatMessageReaction';
import { DevContainer } from '@/components/DevContainer';
import { TcPopover } from '@/components/TcPopover';
import { useMessageReactions } from './useMessageReactions';
@ -65,7 +65,7 @@ const NormalMessage: React.FC<ChatMessageItemProps> = React.memo((props) => {
const reactions = useMessageReactions(payload);
const emojiAction = useChatMessageReaction(payload);
const emojiAction = useChatMessageReactionAction(payload);
const moreActions = useChatMessageItemAction(payload, {
onClick: () => {
setIsActionBtnActive(false);

@ -12,7 +12,9 @@ import {
/**
*
*/
export function useChatMessageReaction(payload: ChatMessage): RenderFunction {
export function useChatMessageReactionAction(
payload: ChatMessage
): RenderFunction {
const payloadRef = useUpdateRef(payload);
const Component = useMemo(
() =>

@ -1,7 +1,7 @@
import { ChatMessage, useUsernames } from 'tailchat-shared';
import { ChatMessage, removeReaction, useUsernames } from 'tailchat-shared';
import _groupBy from 'lodash/groupBy';
import _uniqBy from 'lodash/uniqBy';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { Emoji } from '@/components/Emoji';
import React from 'react';
import { Tooltip } from 'antd';
@ -15,29 +15,31 @@ interface GroupedReaction {
/**
*
*/
const ReactionItem: React.FC<{ reaction: GroupedReaction }> = React.memo(
(props) => {
const { reaction } = props;
return (
<div className="py-0.5 px-1 bg-black bg-opacity-20 rounded flex">
<Tooltip title={useUsernames(reaction.users)}>
<div>
<Emoji emoji={reaction.name} />
{reaction.length > 1 && <span>{reaction.length}</span>}
</div>
</Tooltip>
</div>
);
}
);
const ReactionItem: React.FC<{
reaction: GroupedReaction;
onClick: () => void;
}> = React.memo((props) => {
const { reaction, onClick } = props;
return (
<div className="py-0.5 px-1 bg-black bg-opacity-20 hover:bg-opacity-40 rounded flex cursor-pointer">
<Tooltip title={useUsernames(reaction.users)}>
<div onClick={onClick}>
<Emoji emoji={reaction.name} />
{reaction.length > 1 && <span>{reaction.length}</span>}
</div>
</Tooltip>
</div>
);
});
ReactionItem.displayName = 'ReactionItem';
/**
*
*/
export function useMessageReactions(payload: ChatMessage) {
const messageId = payload._id;
const reactions = payload.reactions ?? [];
const groupedReactions: GroupedReaction[] = useMemo(() => {
@ -53,10 +55,21 @@ export function useMessageReactions(payload: ChatMessage) {
});
}, [reactions]);
const handleClick = useCallback(
(reactionName: string) => {
removeReaction(messageId, reactionName);
},
[messageId]
);
return (
<div className="flex chat-message-reactions gap-1 py-0.5">
{groupedReactions.map((reaction) => (
<ReactionItem key={reaction.name} reaction={reaction} />
<ReactionItem
key={reaction.name}
reaction={reaction}
onClick={() => handleClick(reaction.name)}
/>
))}
</div>
);

Loading…
Cancel
Save