Skip to content

Commit

Permalink
fix: stop calling useNotifyUser multiple times (#34174)
Browse files Browse the repository at this point in the history
Co-authored-by: Tasso <[email protected]>
Co-authored-by: Guilherme Gazzo <[email protected]>
  • Loading branch information
3 people authored Dec 17, 2024
1 parent 5fff6c2 commit f5c7e98
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 54 deletions.
5 changes: 5 additions & 0 deletions .changeset/seven-owls-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixed an issue that added potencially infinite callbacks to the same event, degrading performance over time.
98 changes: 44 additions & 54 deletions apps/meteor/client/hooks/useNotifyUser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AtLeast, ISubscription } from '@rocket.chat/core-typings';
import type { AtLeast, INotificationDesktop, ISubscription } from '@rocket.chat/core-typings';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useRouter, useStream, useUser, useUserPreference } from '@rocket.chat/ui-contexts';
import { useCallback, useEffect } from 'react';
import { useEffect } from 'react';

import { useEmbeddedLayout } from './useEmbeddedLayout';
import { CachedChatSubscription } from '../../app/models/client';
Expand All @@ -15,79 +16,68 @@ export const useNotifyUser = () => {
const notifyUserStream = useStream('notify-user');
const muteFocusedConversations = useUserPreference('muteFocusedConversations');

const notifyNewRoom = useCallback(
async (sub: AtLeast<ISubscription, 'rid'>): Promise<void> => {
if (!user || user.status === 'busy') {
return;
}
const notifyNewRoom = useEffectEvent(async (sub: AtLeast<ISubscription, 'rid'>): Promise<void> => {
if (!user || user.status === 'busy') {
return;
}

if ((!router.getRouteParameters().name || router.getRouteParameters().name !== sub.name) && !sub.ls && sub.alert === true) {
KonchatNotification.newRoom(sub.rid);
}
},
[router, user],
);
if ((!router.getRouteParameters().name || router.getRouteParameters().name !== sub.name) && !sub.ls && sub.alert === true) {
KonchatNotification.newRoom(sub.rid);
}
});

const notifyNewMessageAudioAndDesktop = useEffectEvent((notification: INotificationDesktop) => {
const hasFocus = document.hasFocus();

const openedRoomId = ['channel', 'group', 'direct'].includes(router.getRouteName() || '') ? RoomManager.opened : undefined;

const { rid } = notification.payload;
const messageIsInOpenedRoom = openedRoomId === rid;

const notifyNewMessageAudio = useCallback(
(rid?: string) => {
const hasFocus = document.hasFocus();
const messageIsInOpenedRoom = RoomManager.opened === rid;
fireGlobalEvent('notification', {
notification,
fromOpenedRoom: messageIsInOpenedRoom,
hasFocus,
});

if (isLayoutEmbedded) {
if (!hasFocus && messageIsInOpenedRoom) {
// Play a notification sound
void KonchatNotification.newMessage(rid);
}
} else if (!hasFocus || !messageIsInOpenedRoom || !muteFocusedConversations) {
if (isLayoutEmbedded) {
if (!hasFocus && messageIsInOpenedRoom) {
// Play a notification sound
void KonchatNotification.newMessage(rid);
void KonchatNotification.showDesktop(notification);
}
},
[isLayoutEmbedded, muteFocusedConversations],
);
} else if (!hasFocus || !messageIsInOpenedRoom || !muteFocusedConversations) {
// Play a notification sound
void KonchatNotification.newMessage(rid);
void KonchatNotification.showDesktop(notification);
}
});

useEffect(() => {
if (!user?._id) {
return;
}

notifyUserStream(`${user?._id}/notification`, (notification) => {
const openedRoomId = ['channel', 'group', 'direct'].includes(router.getRouteName() || '') ? RoomManager.opened : undefined;

const hasFocus = document.hasFocus();
const messageIsInOpenedRoom = openedRoomId === notification.payload.rid;
const unsubNotification = notifyUserStream(`${user._id}/notification`, notifyNewMessageAudioAndDesktop);

fireGlobalEvent('notification', {
notification,
fromOpenedRoom: messageIsInOpenedRoom,
hasFocus,
});

if (isLayoutEmbedded) {
if (!hasFocus && messageIsInOpenedRoom) {
// Show a notification.
KonchatNotification.showDesktop(notification);
}
} else if (!hasFocus || !messageIsInOpenedRoom) {
// Show a notification.
KonchatNotification.showDesktop(notification);
}

notifyNewMessageAudio(notification.payload.rid);
});

notifyUserStream(`${user?._id}/subscriptions-changed`, (action, sub) => {
if (action === 'removed') {
const unsubSubs = notifyUserStream(`${user._id}/subscriptions-changed`, (action, sub) => {
if (action !== 'inserted') {
return;
}

void notifyNewRoom(sub);
});

CachedChatSubscription.collection.find().observe({
const handle = CachedChatSubscription.collection.find().observe({
changed: (sub) => {
void notifyNewRoom(sub);
},
});
}, [isLayoutEmbedded, notifyNewMessageAudio, notifyNewRoom, notifyUserStream, router, user?._id]);

return () => {
unsubNotification();
unsubSubs();
handle.stop();
};
}, [isLayoutEmbedded, notifyNewMessageAudioAndDesktop, notifyNewRoom, notifyUserStream, router, user?._id]);
};

0 comments on commit f5c7e98

Please sign in to comment.