diff --git a/apps/meteor/app/threads/client/index.ts b/apps/meteor/app/threads/client/index.ts index 98c219a8837fad3308cdc21576888b607bec5516..5809a93f01d48c0595de1c142db8614e9fbbd4f8 100644 --- a/apps/meteor/app/threads/client/index.ts +++ b/apps/meteor/app/threads/client/index.ts @@ -1,3 +1,2 @@ -import './messageAction/follow'; import './messageAction/replyInThread'; import './threads.css'; diff --git a/apps/meteor/app/threads/client/messageAction/follow.ts b/apps/meteor/app/threads/client/messageAction/follow.ts deleted file mode 100644 index b4ca1e63e9f9790d0bf440e2fcf9ceee7fdaee6d..0000000000000000000000000000000000000000 --- a/apps/meteor/app/threads/client/messageAction/follow.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Tracker } from 'meteor/tracker'; - -import { roomCoordinator } from '../../../../client/lib/rooms/roomCoordinator'; -import { dispatchToastMessage } from '../../../../client/lib/toast'; -import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; -import { Messages } from '../../../models/client'; -import { settings } from '../../../settings/client'; -import { MessageAction } from '../../../ui-utils/client'; -import { t } from '../../../utils/lib/i18n'; - -Meteor.startup(() => { - Tracker.autorun(() => { - if (!settings.get('Threads_enabled')) { - return MessageAction.removeButton('follow-message'); - } - MessageAction.addButton({ - id: 'follow-message', - icon: 'bell', - label: 'Follow_message', - type: 'interaction', - context: ['message', 'message-mobile', 'threads', 'federated', 'videoconf', 'videoconf-threads'], - async action(_, { message }) { - if (!message) { - return; - } - - await callWithErrorHandling('followMessage', { mid: message._id }).then(() => - dispatchToastMessage({ - type: 'success', - message: t('You_followed_this_message'), - }), - ); - }, - condition({ message: { _id, tmid, replies = [] }, room, user, context }) { - if (tmid || context) { - const parentMessage = Messages.findOne({ _id: tmid || _id }, { fields: { replies: 1 } }); - if (parentMessage) { - replies = parentMessage.replies || []; - } - } - const isLivechatRoom = roomCoordinator.isLivechatRoom(room.t); - if (isLivechatRoom) { - return false; - } - return user?._id ? !replies.includes(user._id) : false; - }, - order: 1, - group: 'menu', - }); - }); -}); diff --git a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx index 3d0fb11bfebbb49624beff7c048c96d04b24bdfd..4697b3f5ad3c6c29d1add48064a8aca0f9098b1f 100644 --- a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx +++ b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx @@ -10,6 +10,7 @@ import React, { memo, useMemo, useRef } from 'react'; import MessageActionMenu from './MessageActionMenu'; import MessageToolbarStarsActionMenu from './MessageToolbarStarsActionMenu'; +import { useFollowMessageAction } from './useFollowMessageAction'; import { useJumpToMessageContextAction } from './useJumpToMessageContextAction'; import { useNewDiscussionMessageAction } from './useNewDiscussionMessageAction'; import { usePermalinkStar } from './usePermalinkStar'; @@ -99,14 +100,13 @@ const MessageToolbar = ({ useStarMessageAction(message, { room, user }); useUnstarMessageAction(message, { room, user }); usePermalinkStar(message, { subscription, user }); + useFollowMessageAction(message, { room, user, context }); useUnFollowMessageAction(message, { room, user, context }); - useJumpToMessageContextAction(message, { id: 'jump-to-message', order: 100, context: ['mentions', 'threads', 'videoconf-threads', 'message-mobile', 'search'], }); - useJumpToMessageContextAction(message, { id: 'jump-to-pin-message', order: 100, diff --git a/apps/meteor/client/components/message/toolbar/useFollowMessageAction.ts b/apps/meteor/client/components/message/toolbar/useFollowMessageAction.ts new file mode 100644 index 0000000000000000000000000000000000000000..7fdde7c97b5e79fbce687cf04ab55ad7dc47d8bd --- /dev/null +++ b/apps/meteor/client/components/message/toolbar/useFollowMessageAction.ts @@ -0,0 +1,75 @@ +import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; +import { isOmnichannelRoom } from '@rocket.chat/core-typings'; +import { useSetting, useToastMessageDispatch } from '@rocket.chat/ui-contexts'; +import { useQueryClient } from '@tanstack/react-query'; +import { useEffect } from 'react'; + +import { Messages } from '../../../../app/models/client'; +import { MessageAction } from '../../../../app/ui-utils/client'; +import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction'; +import { t } from '../../../../app/utils/lib/i18n'; +import { useReactiveQuery } from '../../../hooks/useReactiveQuery'; +import { roomsQueryKeys } from '../../../lib/queryKeys'; +import { useToggleFollowingThreadMutation } from '../../../views/room/contextualBar/Threads/hooks/useToggleFollowingThreadMutation'; + +export const useFollowMessageAction = ( + message: IMessage, + { room, user, context }: { room: IRoom; user: IUser | undefined; context: MessageActionContext }, +) => { + const threadsEnabled = useSetting('Threads_enabled'); + + const dispatchToastMessage = useToastMessageDispatch(); + + const queryClient = useQueryClient(); + + const { mutate: toggleFollowingThread } = useToggleFollowingThreadMutation({ + onSuccess: () => { + dispatchToastMessage({ + type: 'success', + message: t('You_followed_this_message'), + }); + }, + }); + + const { tmid, _id } = message; + const messageQuery = useReactiveQuery(roomsQueryKeys.message(message.rid, message._id), () => + Messages.findOne({ _id: tmid || _id }, { fields: { replies: 1 } }), + ); + + useEffect(() => { + if (!message || !threadsEnabled || isOmnichannelRoom(room)) { + return; + } + + let { replies = [] } = message; + if (tmid || context) { + const parentMessage = messageQuery.data; + if (parentMessage) { + replies = parentMessage.replies || []; + } + } + + if (!user?._id) { + return; + } + + if ((replies as string[]).includes(user._id)) { + return; + } + + MessageAction.addButton({ + id: 'follow-message', + icon: 'bell', + label: 'Follow_message', + type: 'interaction', + context: ['message', 'message-mobile', 'threads', 'federated', 'videoconf', 'videoconf-threads'], + action() { + toggleFollowingThread({ tmid: tmid || _id, follow: true, rid: room._id }); + }, + order: 1, + group: 'menu', + }); + + return () => MessageAction.removeButton('follow-message'); + }, [_id, context, message, messageQuery, messageQuery.data, queryClient, room, threadsEnabled, tmid, toggleFollowingThread, user]); +};