diff --git a/apps/meteor/client/hooks/useUnread.ts b/apps/meteor/client/hooks/useUnread.ts new file mode 100644 index 0000000000000..0259f39f1070f --- /dev/null +++ b/apps/meteor/client/hooks/useUnread.ts @@ -0,0 +1,61 @@ +import { manageFavicon } from '@rocket.chat/favicon'; +import { useSession, useSessionDispatch, useUserPreference, useUserSubscriptions } from '@rocket.chat/ui-contexts'; +import { useEffect } from 'react'; + +import { useFireGlobalEvent } from './useFireGlobalEvent'; +import { Rooms } from '../../app/models/client'; + +const query = { open: { $ne: false }, hideUnreadStatus: { $ne: true }, archived: { $ne: true } }; +const options = { fields: { unread: 1, alert: 1, rid: 1, t: 1, name: 1, ls: 1, unreadAlert: 1, fname: 1, prid: 1 } }; + +export const useUnread = () => { + const unreadAlertEnabled = useUserPreference('unreadAlert'); + const setUnread = useSessionDispatch('unread'); + const unread = useSession('unread') as string | number | null | undefined; + + const { mutate: fireEventUnreadChangedBySubscription } = useFireGlobalEvent('unread-changed-by-subscription'); + const { mutate: fireEventUnreadChanged } = useFireGlobalEvent('unread-changed'); + + const subscriptions = useUserSubscriptions(query, options); + + useEffect(() => { + let unreadAlert: false | '•' = false; + + const unreadCount = subscriptions.reduce((ret, subscription) => { + const room = Rooms.findOne({ _id: subscription.rid }, { fields: { usersCount: 1 } }); + fireEventUnreadChangedBySubscription({ + ...subscription, + usersCount: room?.usersCount, + }); + + if (subscription.alert || subscription.unread > 0) { + // Increment the total unread count. + if (subscription.alert === true && subscription.unreadAlert !== 'nothing') { + if (subscription.unreadAlert === 'all' || unreadAlertEnabled !== false) { + unreadAlert = '•'; + } + } + return ret + subscription.unread; + } + return ret; + }, 0); + + if (unreadCount > 0) { + if (unreadCount > 999) { + setUnread('999+'); + } else { + setUnread(unreadCount); + } + } else if (unreadAlert !== false) { + setUnread(unreadAlert); + } else { + setUnread(''); + } + fireEventUnreadChanged(unreadCount); + }, [setUnread, unread, subscriptions, unreadAlertEnabled, fireEventUnreadChangedBySubscription, fireEventUnreadChanged]); + + useEffect(() => { + const updateFavicon = manageFavicon(); + updateFavicon(unread); + }, [unread]); +}; diff --git a/apps/meteor/client/startup/index.ts b/apps/meteor/client/startup/index.ts index dc217a109b80c..061ba00111d70 100644 --- a/apps/meteor/client/startup/index.ts +++ b/apps/meteor/client/startup/index.ts @@ -17,4 +17,3 @@ import './routes'; import './slashCommands'; import './startup'; import './streamMessage'; -import './unread'; diff --git a/apps/meteor/client/startup/unread.ts b/apps/meteor/client/startup/unread.ts deleted file mode 100644 index edc48fbf894b0..0000000000000 --- a/apps/meteor/client/startup/unread.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { ISubscription } from '@rocket.chat/core-typings'; -import { manageFavicon } from '@rocket.chat/favicon'; -import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; -import { Tracker } from 'meteor/tracker'; - -import { Subscriptions, Rooms } from '../../app/models/client'; -import { getUserPreference } from '../../app/utils/client'; -import { fireGlobalEvent } from '../lib/utils/fireGlobalEvent'; - -const fetchSubscriptions = (): ISubscription[] => - Subscriptions.find( - { - open: true, - hideUnreadStatus: { $ne: true }, - archived: { $ne: true }, - }, - { - fields: { - unread: 1, - alert: 1, - rid: 1, - t: 1, - name: 1, - ls: 1, - unreadAlert: 1, - fname: 1, - prid: 1, - }, - }, - ).fetch(); - -Meteor.startup(() => { - Tracker.autorun(() => { - const userUnreadAlert = getUserPreference(Meteor.userId(), 'unreadAlert'); - - let unreadAlert: false | '•' = false; - - const unreadCount = fetchSubscriptions().reduce( - (ret, subscription) => - Tracker.nonreactive(() => { - const room = Rooms.findOne({ _id: subscription.rid }, { fields: { usersCount: 1 } }); - fireGlobalEvent('unread-changed-by-subscription', { - ...subscription, - usersCount: room?.usersCount, - }); - - if (subscription.alert || subscription.unread > 0) { - // Increment the total unread count. - if (subscription.alert === true && subscription.unreadAlert !== 'nothing') { - if (subscription.unreadAlert === 'all' || userUnreadAlert !== false) { - unreadAlert = '•'; - } - } - return ret + subscription.unread; - } - return ret; - }), - 0, - ); - - if (unreadCount > 0) { - if (unreadCount > 999) { - Session.set('unread', '999+'); - } else { - Session.set('unread', unreadCount); - } - } else if (unreadAlert !== false) { - Session.set('unread', unreadAlert); - } else { - Session.set('unread', ''); - } - }); -}); - -Meteor.startup(() => { - const updateFavicon = manageFavicon(); - - Tracker.autorun(() => { - const unread = Session.get('unread'); - fireGlobalEvent('unread-changed', unread); - - updateFavicon(unread); - }); -}); diff --git a/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx b/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx index 0b7cdcbae983e..16b64aa892da0 100644 --- a/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx +++ b/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx @@ -5,6 +5,7 @@ import { useCustomEmoji } from '../../../hooks/customEmoji/useCustomEmoji'; import { useNotificationUserCalendar } from '../../../hooks/notification/useNotificationUserCalendar'; import { useNotifyUser } from '../../../hooks/notification/useNotifyUser'; import { useRestrictedRoles } from '../../../hooks/useRestrictedRoles'; +import { useUnread } from '../../../hooks/useUnread'; import { useForceLogout } from '../hooks/useForceLogout'; import { useOTRMessaging } from '../hooks/useOTRMessaging'; import { useStoreCookiesOnLogin } from '../hooks/useStoreCookiesOnLogin'; @@ -18,6 +19,7 @@ const LoggedInArea = ({ children }: { children: ReactNode }) => { throw new Error('User not logged'); } + useUnread(); useNotifyUser(user); useUpdateVideoConfUser(user._id); useWebRTC(user._id);