From 6c550744c65e9fdf78c56e3c69f5627f57432b36 Mon Sep 17 00:00:00 2001
From: Martin Schoeler <martin.schoeler@rocket.chat>
Date: Wed, 4 Dec 2024 18:10:58 -0300
Subject: [PATCH] chore: remove meteor.startup from unpin-message (#34020)

Co-authored-by: Tasso Evangelista <2263066+tassoevan@users.noreply.github.com>
---
 .../message/hooks/usePinMessageMutation.ts    |  9 ++---
 .../message/hooks/useUnpinMessageMutation.ts  | 32 +++++++++++++++
 .../message/toolbar/MessageToolbar.tsx        |  2 +
 .../message/toolbar/useUnpinMessageAction.tsx | 40 +++++++++++++++++++
 apps/meteor/client/methods/unpinMessage.ts    |  1 -
 .../client/startup/actionButtons/index.ts     |  1 -
 .../startup/actionButtons/unpinMessage.ts     | 36 -----------------
 7 files changed, 78 insertions(+), 43 deletions(-)
 create mode 100644 apps/meteor/client/components/message/hooks/useUnpinMessageMutation.ts
 create mode 100644 apps/meteor/client/components/message/toolbar/useUnpinMessageAction.tsx
 delete mode 100644 apps/meteor/client/startup/actionButtons/unpinMessage.ts

diff --git a/apps/meteor/client/components/message/hooks/usePinMessageMutation.ts b/apps/meteor/client/components/message/hooks/usePinMessageMutation.ts
index 647df5b324d..6ac601f44a1 100644
--- a/apps/meteor/client/components/message/hooks/usePinMessageMutation.ts
+++ b/apps/meteor/client/components/message/hooks/usePinMessageMutation.ts
@@ -8,22 +8,21 @@ import { roomsQueryKeys } from '../../../lib/queryKeys';
 
 export const usePinMessageMutation = () => {
 	const { t } = useTranslation();
-	const pinMessageEndpoint = useEndpoint('POST', '/v1/chat.pinMessage');
+	const pinMessage = useEndpoint('POST', '/v1/chat.pinMessage');
 	const dispatchToastMessage = useToastMessageDispatch();
 
 	const queryClient = useQueryClient();
 
 	return useMutation({
-		mutationFn: async (message: IMessage) => pinMessageEndpoint({ messageId: message._id }),
+		mutationFn: async (message: IMessage) => pinMessage({ messageId: message._id }),
 		onMutate: (message) => {
 			updatePinMessage(message, { pinned: true });
 		},
-		onSuccess: (_data) => {
+		onSuccess: () => {
 			dispatchToastMessage({ type: 'success', message: t('Message_has_been_pinned') });
 		},
-		onError: (error, message) => {
+		onError: (error) => {
 			dispatchToastMessage({ type: 'error', message: error });
-			updatePinMessage(message, { pinned: false });
 		},
 		onSettled: (_data, _error, message) => {
 			queryClient.invalidateQueries(roomsQueryKeys.pinnedMessages(message.rid));
diff --git a/apps/meteor/client/components/message/hooks/useUnpinMessageMutation.ts b/apps/meteor/client/components/message/hooks/useUnpinMessageMutation.ts
new file mode 100644
index 00000000000..5c2c716e63f
--- /dev/null
+++ b/apps/meteor/client/components/message/hooks/useUnpinMessageMutation.ts
@@ -0,0 +1,32 @@
+import type { IMessage } from '@rocket.chat/core-typings';
+import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
+import { useQueryClient, useMutation } from '@tanstack/react-query';
+import { useTranslation } from 'react-i18next';
+
+import { updatePinMessage } from '../../../lib/mutationEffects/updatePinMessage';
+import { roomsQueryKeys } from '../../../lib/queryKeys';
+
+export const useUnpinMessageMutation = () => {
+	const { t } = useTranslation();
+	const unpinMessage = useEndpoint('POST', '/v1/chat.unPinMessage');
+	const dispatchToastMessage = useToastMessageDispatch();
+
+	const queryClient = useQueryClient();
+
+	return useMutation({
+		mutationFn: async (message: IMessage) => unpinMessage({ messageId: message._id }),
+		onMutate: (message) => {
+			updatePinMessage(message, { pinned: false });
+		},
+		onSuccess: () => {
+			dispatchToastMessage({ type: 'success', message: t('Message_has_been_unpinned') });
+		},
+		onError: (error) => {
+			dispatchToastMessage({ type: 'error', message: error });
+		},
+		onSettled: (_data, _error, message) => {
+			queryClient.invalidateQueries(roomsQueryKeys.pinnedMessages(message.rid));
+			queryClient.invalidateQueries(roomsQueryKeys.messageActions(message.rid, message._id));
+		},
+	});
+};
diff --git a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx
index 4697b3f5ad3..5af0529e5d6 100644
--- a/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx
+++ b/apps/meteor/client/components/message/toolbar/MessageToolbar.tsx
@@ -17,6 +17,7 @@ import { usePermalinkStar } from './usePermalinkStar';
 import { usePinMessageAction } from './usePinMessageAction';
 import { useStarMessageAction } from './useStarMessageAction';
 import { useUnFollowMessageAction } from './useUnFollowMessageAction';
+import { useUnpinMessageAction } from './useUnpinMessageAction';
 import { useUnstarMessageAction } from './useUnstarMessageAction';
 import { useWebDAVMessageAction } from './useWebDAVMessageAction';
 import type { MessageActionContext } from '../../../../app/ui-utils/client/lib/MessageAction';
@@ -96,6 +97,7 @@ const MessageToolbar = ({
 	// TODO: move this to another place
 	useWebDAVMessageAction();
 	useNewDiscussionMessageAction();
+	useUnpinMessageAction(message, { room, subscription });
 	usePinMessageAction(message, { room, subscription });
 	useStarMessageAction(message, { room, user });
 	useUnstarMessageAction(message, { room, user });
diff --git a/apps/meteor/client/components/message/toolbar/useUnpinMessageAction.tsx b/apps/meteor/client/components/message/toolbar/useUnpinMessageAction.tsx
new file mode 100644
index 00000000000..06daaaa45dc
--- /dev/null
+++ b/apps/meteor/client/components/message/toolbar/useUnpinMessageAction.tsx
@@ -0,0 +1,40 @@
+import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
+import { isOmnichannelRoom } from '@rocket.chat/core-typings';
+import { useSetting, usePermission } from '@rocket.chat/ui-contexts';
+import { useEffect } from 'react';
+
+import { MessageAction } from '../../../../app/ui-utils/client/lib/MessageAction';
+import { useUnpinMessageMutation } from '../hooks/useUnpinMessageMutation';
+
+export const useUnpinMessageAction = (
+	message: IMessage,
+	{ room, subscription }: { room: IRoom; subscription: ISubscription | undefined },
+) => {
+	const allowPinning = useSetting('Message_AllowPinning');
+	const hasPermission = usePermission('pin-message', room._id);
+
+	const { mutate: unpinMessage } = useUnpinMessageMutation();
+
+	useEffect(() => {
+		if (!allowPinning || isOmnichannelRoom(room) || !hasPermission || !message.pinned || !subscription) {
+			return;
+		}
+
+		MessageAction.addButton({
+			id: 'unpin-message',
+			icon: 'pin',
+			label: 'Unpin',
+			type: 'interaction',
+			context: ['pinned', 'message', 'message-mobile', 'threads', 'direct', 'videoconf', 'videoconf-threads'],
+			action() {
+				unpinMessage(message);
+			},
+			order: 2,
+			group: 'menu',
+		});
+
+		return () => {
+			MessageAction.removeButton('unpin-message');
+		};
+	}, [allowPinning, hasPermission, message, room, subscription, unpinMessage]);
+};
diff --git a/apps/meteor/client/methods/unpinMessage.ts b/apps/meteor/client/methods/unpinMessage.ts
index deee1f51f5f..0c9ca690956 100644
--- a/apps/meteor/client/methods/unpinMessage.ts
+++ b/apps/meteor/client/methods/unpinMessage.ts
@@ -25,7 +25,6 @@ Meteor.methods<ServerMethods>({
 			dispatchToastMessage({ type: 'error', message: t('error-unpinning-message') });
 			return false;
 		}
-		dispatchToastMessage({ type: 'success', message: t('Message_has_been_unpinned') });
 		Messages.update(
 			{
 				_id: message._id,
diff --git a/apps/meteor/client/startup/actionButtons/index.ts b/apps/meteor/client/startup/actionButtons/index.ts
index 73de6373809..d1e6724638c 100644
--- a/apps/meteor/client/startup/actionButtons/index.ts
+++ b/apps/meteor/client/startup/actionButtons/index.ts
@@ -1,2 +1 @@
 import './permalinkPinned';
-import './unpinMessage';
diff --git a/apps/meteor/client/startup/actionButtons/unpinMessage.ts b/apps/meteor/client/startup/actionButtons/unpinMessage.ts
deleted file mode 100644
index aa5fa49bb48..00000000000
--- a/apps/meteor/client/startup/actionButtons/unpinMessage.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Meteor } from 'meteor/meteor';
-
-import { hasAtLeastOnePermission } from '../../../app/authorization/client';
-import { settings } from '../../../app/settings/client';
-import { MessageAction } from '../../../app/ui-utils/client';
-import { sdk } from '../../../app/utils/client/lib/SDKClient';
-import { queryClient } from '../../lib/queryClient';
-import { dispatchToastMessage } from '../../lib/toast';
-
-Meteor.startup(() => {
-	MessageAction.addButton({
-		id: 'unpin-message',
-		icon: 'pin',
-		label: 'Unpin',
-		type: 'interaction',
-		context: ['pinned', 'message', 'message-mobile', 'threads', 'direct', 'videoconf', 'videoconf-threads'],
-		async action(_, { message }) {
-			message.pinned = false;
-			try {
-				await sdk.call('unpinMessage', message);
-				queryClient.invalidateQueries(['rooms', message.rid, 'pinned-messages']);
-			} catch (error) {
-				dispatchToastMessage({ type: 'error', message: error });
-			}
-		},
-		condition({ message, subscription }) {
-			if (!subscription || !settings.get('Message_AllowPinning') || !message.pinned) {
-				return false;
-			}
-
-			return hasAtLeastOnePermission('pin-message', message.rid);
-		},
-		order: 2,
-		group: 'menu',
-	});
-});
-- 
GitLab