From eabc50d3b18baa10aed579eaa7316ea9d1db9fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?= <60678893+juliajforesti@users.noreply.github.com> Date: Thu, 10 Apr 2025 20:58:31 -0300 Subject: [PATCH] chore: create `LoggedInArea` (#35741) Co-authored-by: Guilherme Gazzo --- .../useNotificationUserCalendar.ts | 9 +++--- .../hooks/notification/useNotifyUser.ts | 15 ++++------ apps/meteor/client/views/root/AppLayout.tsx | 14 --------- .../root/MainLayout/AuthenticationCheck.tsx | 13 +++++--- .../views/root/MainLayout/LoggedInArea.tsx | 30 +++++++++++++++++++ .../client/views/root/hooks/useForceLogout.ts | 9 ++---- .../views/root/hooks/useOTRMessaging.ts | 9 ++---- .../root/hooks/useStoreCookiesOnLogin.ts | 7 ++--- .../root/hooks/useUpdateVideoConfUser.ts | 5 ++-- .../client/views/root/hooks/useWebRTC.ts | 7 ++--- 10 files changed, 59 insertions(+), 59 deletions(-) create mode 100644 apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx diff --git a/apps/meteor/client/hooks/notification/useNotificationUserCalendar.ts b/apps/meteor/client/hooks/notification/useNotificationUserCalendar.ts index bb7d497194d..47af5ae6e06 100644 --- a/apps/meteor/client/hooks/notification/useNotificationUserCalendar.ts +++ b/apps/meteor/client/hooks/notification/useNotificationUserCalendar.ts @@ -1,19 +1,18 @@ -import type { ICalendarNotification } from '@rocket.chat/core-typings'; +import type { ICalendarNotification, IUser } from '@rocket.chat/core-typings'; import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; -import { useSetting, useStream, useUser, useUserPreference } from '@rocket.chat/ui-contexts'; +import { useSetting, useStream, useUserPreference } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; import { imperativeModal } from '../../lib/imperativeModal'; import OutlookCalendarEventModal from '../../views/outlookCalendar/OutlookCalendarEventModal'; -export const useNotificationUserCalendar = () => { - const user = useUser(); +export const useNotificationUserCalendar = (user: IUser) => { const requireInteraction = useUserPreference('desktopNotificationRequireInteraction'); const outLookEnabled = useSetting('Outlook_Calendar_Enabled'); const notifyUserStream = useStream('notify-user'); const notifyUserCalendar = useEffectEvent(async (notification: ICalendarNotification) => { - if (!user || user.status === 'busy') { + if (user.status === 'busy') { return; } diff --git a/apps/meteor/client/hooks/notification/useNotifyUser.ts b/apps/meteor/client/hooks/notification/useNotifyUser.ts index d2762144e94..3ac30732dc8 100644 --- a/apps/meteor/client/hooks/notification/useNotifyUser.ts +++ b/apps/meteor/client/hooks/notification/useNotifyUser.ts @@ -1,6 +1,6 @@ -import type { AtLeast, INotificationDesktop, ISubscription } from '@rocket.chat/core-typings'; +import type { AtLeast, INotificationDesktop, ISubscription, IUser } from '@rocket.chat/core-typings'; import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; -import { useCustomSound, useRouter, useStream, useUser, useUserPreference } from '@rocket.chat/ui-contexts'; +import { useCustomSound, useRouter, useStream, useUserPreference } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; import { useEmbeddedLayout } from '../useEmbeddedLayout'; @@ -9,8 +9,7 @@ import { useNewMessageNotification } from './useNewMessageNotification'; import { RoomManager } from '../../lib/RoomManager'; import { fireGlobalEvent } from '../../lib/utils/fireGlobalEvent'; -export const useNotifyUser = () => { - const user = useUser(); +export const useNotifyUser = (user: IUser) => { const router = useRouter(); const isLayoutEmbedded = useEmbeddedLayout(); const notifyUserStream = useStream('notify-user'); @@ -20,7 +19,7 @@ export const useNotifyUser = () => { const showDesktopNotification = useDesktopNotification(); const notifyNewRoom = useEffectEvent(async (sub: AtLeast): Promise => { - if (!user || user.status === 'busy') { + if (user.status === 'busy') { return; } @@ -57,10 +56,6 @@ export const useNotifyUser = () => { }); useEffect(() => { - if (!user?._id) { - return; - } - const unsubNotification = notifyUserStream(`${user._id}/notification`, notifyNewMessageAudioAndDesktop); const unsubSubs = notifyUserStream(`${user._id}/subscriptions-changed`, (action, sub) => { @@ -75,7 +70,7 @@ export const useNotifyUser = () => { unsubNotification(); unsubSubs(); }; - }, [notifyNewMessageAudioAndDesktop, notifyNewRoom, notifyUserStream, router, user?._id]); + }, [notifyNewMessageAudioAndDesktop, notifyNewRoom, notifyUserStream, router, user._id]); useEffect(() => () => notificationSounds.stopNewRoom(), [notificationSounds]); }; diff --git a/apps/meteor/client/views/root/AppLayout.tsx b/apps/meteor/client/views/root/AppLayout.tsx index 7cad62d46c6..68b46e0e7d9 100644 --- a/apps/meteor/client/views/root/AppLayout.tsx +++ b/apps/meteor/client/views/root/AppLayout.tsx @@ -4,14 +4,9 @@ import DocumentTitleWrapper from './DocumentTitleWrapper'; import PageLoading from './PageLoading'; import { useCodeHighlight } from './hooks/useCodeHighlight'; import { useEscapeKeyStroke } from './hooks/useEscapeKeyStroke'; -import { useForceLogout } from './hooks/useForceLogout'; import { useGoogleTagManager } from './hooks/useGoogleTagManager'; import { useMessageLinkClicks } from './hooks/useMessageLinkClicks'; -import { useOTRMessaging } from './hooks/useOTRMessaging'; import { useSettingsOnLoadSiteUrl } from './hooks/useSettingsOnLoadSiteUrl'; -import { useStoreCookiesOnLogin } from './hooks/useStoreCookiesOnLogin'; -import { useUpdateVideoConfUser } from './hooks/useUpdateVideoConfUser'; -import { useWebRTC } from './hooks/useWebRTC'; import { useWordPressOAuth } from './hooks/useWordPressOAuth'; import { useCorsSSLConfig } from '../../../app/cors/client/useCorsSSLConfig'; import { useDolphin } from '../../../app/dolphin/client/hooks/useDolphin'; @@ -23,8 +18,6 @@ import { useLivechatEnterprise } from '../../../app/livechat-enterprise/hooks/us import { useNextcloud } from '../../../app/nextcloud/client/useNextcloud'; import { useTokenPassAuth } from '../../../app/tokenpass/client/hooks/useTokenPassAuth'; import { useNotificationPermission } from '../../hooks/notification/useNotificationPermission'; -import { useNotificationUserCalendar } from '../../hooks/notification/useNotificationUserCalendar'; -import { useNotifyUser } from '../../hooks/notification/useNotifyUser'; import { useAnalytics } from '../../hooks/useAnalytics'; import { useAnalyticsEventTracking } from '../../hooks/useAnalyticsEventTracking'; import { useAutoupdate } from '../../hooks/useAutoupdate'; @@ -48,7 +41,6 @@ const AppLayout = () => { useEscapeKeyStroke(); useAnalyticsEventTracking(); useLoadRoomForAllowedAnonymousRead(); - useNotifyUser(); useNotificationPermission(); useEmojiOne(); useRedirectToSetupWizard(); @@ -63,14 +55,8 @@ const AppLayout = () => { useWordPressOAuth(); useCustomOAuth(); useCorsSSLConfig(); - useOTRMessaging(); - useUpdateVideoConfUser(); - useWebRTC(); - useStoreCookiesOnLogin(); useAutoupdate(); - useForceLogout(); useCodeHighlight(); - useNotificationUserCalendar(); const layout = useSyncExternalStore(appLayout.subscribe, appLayout.getSnapshot); diff --git a/apps/meteor/client/views/root/MainLayout/AuthenticationCheck.tsx b/apps/meteor/client/views/root/MainLayout/AuthenticationCheck.tsx index a10d59eff67..822acfc2256 100644 --- a/apps/meteor/client/views/root/MainLayout/AuthenticationCheck.tsx +++ b/apps/meteor/client/views/root/MainLayout/AuthenticationCheck.tsx @@ -1,7 +1,8 @@ -import { useSession, useUserId, useSetting } from '@rocket.chat/ui-contexts'; +import { useSession, useUser, useSetting } from '@rocket.chat/ui-contexts'; import RegistrationRoute from '@rocket.chat/web-ui-registration'; import type { ReactElement, ReactNode } from 'react'; +import LoggedInArea from './LoggedInArea'; import LoginPage from './LoginPage'; import UsernameCheck from './UsernameCheck'; @@ -15,12 +16,16 @@ import UsernameCheck from './UsernameCheck'; * renders the page, without creating an user (not even an anonymous user) */ const AuthenticationCheck = ({ children, guest }: { children: ReactNode; guest?: boolean }): ReactElement => { - const uid = useUserId(); + const user = useUser(); const allowAnonymousRead = useSetting('Accounts_AllowAnonymousRead'); const forceLogin = useSession('forceLogin'); - if (uid) { - return {children}; + if (user) { + return ( + + {children} + + ); } if (!forceLogin && guest) { diff --git a/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx b/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx new file mode 100644 index 00000000000..298da34a0f8 --- /dev/null +++ b/apps/meteor/client/views/root/MainLayout/LoggedInArea.tsx @@ -0,0 +1,30 @@ +import { useUser } from '@rocket.chat/ui-contexts'; +import type { ReactNode } from 'react'; + +import { useNotificationUserCalendar } from '../../../hooks/notification/useNotificationUserCalendar'; +import { useNotifyUser } from '../../../hooks/notification/useNotifyUser'; +import { useForceLogout } from '../hooks/useForceLogout'; +import { useOTRMessaging } from '../hooks/useOTRMessaging'; +import { useStoreCookiesOnLogin } from '../hooks/useStoreCookiesOnLogin'; +import { useUpdateVideoConfUser } from '../hooks/useUpdateVideoConfUser'; +import { useWebRTC } from '../hooks/useWebRTC'; + +const LoggedInArea = ({ children }: { children: ReactNode }) => { + const user = useUser(); + + if (!user) { + throw new Error('User not logged'); + } + + useNotifyUser(user); + useUpdateVideoConfUser(user._id); + useWebRTC(user._id); + useOTRMessaging(user._id); + useNotificationUserCalendar(user); + useForceLogout(user._id); + useStoreCookiesOnLogin(user._id); + + return children; +}; + +export default LoggedInArea; diff --git a/apps/meteor/client/views/root/hooks/useForceLogout.ts b/apps/meteor/client/views/root/hooks/useForceLogout.ts index 080dcb9a423..07390ddb0d4 100644 --- a/apps/meteor/client/views/root/hooks/useForceLogout.ts +++ b/apps/meteor/client/views/root/hooks/useForceLogout.ts @@ -1,16 +1,11 @@ -import { useUserId, useStream, useSessionDispatch } from '@rocket.chat/ui-contexts'; +import { useStream, useSessionDispatch } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; -export const useForceLogout = () => { - const userId = useUserId(); +export const useForceLogout = (userId: string) => { const getNotifyUserStream = useStream('notify-user'); const setForceLogout = useSessionDispatch('forceLogout'); useEffect(() => { - if (!userId) { - return; - } - setForceLogout(false); const unsubscribe = getNotifyUserStream(`${userId}/force_logout`, () => { diff --git a/apps/meteor/client/views/root/hooks/useOTRMessaging.ts b/apps/meteor/client/views/root/hooks/useOTRMessaging.ts index 3b09e84b866..b3195326fe8 100644 --- a/apps/meteor/client/views/root/hooks/useOTRMessaging.ts +++ b/apps/meteor/client/views/root/hooks/useOTRMessaging.ts @@ -1,6 +1,6 @@ import type { AtLeast, IMessage } from '@rocket.chat/core-typings'; import { isOTRMessage } from '@rocket.chat/core-typings'; -import { useMethod, useStream, useUserId } from '@rocket.chat/ui-contexts'; +import { useMethod, useStream } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; import OTR from '../../../../app/otr/client/OTR'; @@ -9,16 +9,11 @@ import { t } from '../../../../app/utils/lib/i18n'; import { onClientBeforeSendMessage } from '../../../lib/onClientBeforeSendMessage'; import { onClientMessageReceived } from '../../../lib/onClientMessageReceived'; -export const useOTRMessaging = () => { - const uid = useUserId(); +export const useOTRMessaging = (uid: string) => { const updateOTRAck = useMethod('updateOTRAck'); const notifyUser = useStream('notify-user'); useEffect(() => { - if (!uid) { - return; - } - const handleNotifyUser = (type: 'handshake' | 'acknowledge' | 'deny' | 'end', data: { roomId: string; userId: string }) => { if (!data.roomId || !data.userId || data.userId === uid) { return; diff --git a/apps/meteor/client/views/root/hooks/useStoreCookiesOnLogin.ts b/apps/meteor/client/views/root/hooks/useStoreCookiesOnLogin.ts index 1d43b408b81..712726bd9a0 100644 --- a/apps/meteor/client/views/root/hooks/useStoreCookiesOnLogin.ts +++ b/apps/meteor/client/views/root/hooks/useStoreCookiesOnLogin.ts @@ -1,15 +1,14 @@ -import { useConnectionStatus, useUserId } from '@rocket.chat/ui-contexts'; +import { useConnectionStatus } from '@rocket.chat/ui-contexts'; import { Accounts } from 'meteor/accounts-base'; import { useEffect } from 'react'; -export const useStoreCookiesOnLogin = () => { - const userId = useUserId(); +export const useStoreCookiesOnLogin = (userId: string) => { const { isLoggingIn } = useConnectionStatus(); useEffect(() => { // Check for isLoggingIn to be reactive and ensure it will process only after login finishes // preventing race condition setting the rc_token as null forever - if (userId && isLoggingIn === false) { + if (isLoggingIn === false) { const secure = location.protocol === 'https:' ? '; secure' : ''; document.cookie = `rc_uid=${encodeURI(userId)}; path=/${secure}`; diff --git a/apps/meteor/client/views/root/hooks/useUpdateVideoConfUser.ts b/apps/meteor/client/views/root/hooks/useUpdateVideoConfUser.ts index bc3113eeb7f..67e3e72dd30 100644 --- a/apps/meteor/client/views/root/hooks/useUpdateVideoConfUser.ts +++ b/apps/meteor/client/views/root/hooks/useUpdateVideoConfUser.ts @@ -1,10 +1,9 @@ -import { useConnectionStatus, useUserId } from '@rocket.chat/ui-contexts'; +import { useConnectionStatus } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; import { VideoConfManager } from '../../../lib/VideoConfManager'; -export const useUpdateVideoConfUser = () => { - const userId = useUserId(); +export const useUpdateVideoConfUser = (userId: string) => { const { connected, isLoggingIn } = useConnectionStatus(); useEffect(() => { diff --git a/apps/meteor/client/views/root/hooks/useWebRTC.ts b/apps/meteor/client/views/root/hooks/useWebRTC.ts index bb6e66d4f02..a6182f985d4 100644 --- a/apps/meteor/client/views/root/hooks/useWebRTC.ts +++ b/apps/meteor/client/views/root/hooks/useWebRTC.ts @@ -1,17 +1,14 @@ -import { useStream, useUserId } from '@rocket.chat/ui-contexts'; +import { useStream } from '@rocket.chat/ui-contexts'; import { useEffect } from 'react'; import type { CandidateData, DescriptionData, JoinData } from '../../../../app/webrtc/client/WebRTCClass'; import { WebRTC } from '../../../../app/webrtc/client/WebRTCClass'; import { WEB_RTC_EVENTS } from '../../../../app/webrtc/lib/constants'; -export const useWebRTC = () => { - const uid = useUserId(); +export const useWebRTC = (uid: string) => { const notifyUser = useStream('notify-user'); useEffect(() => { - if (!uid) return; - const handleNotifyUser = (type: 'candidate' | 'description' | 'join', data: CandidateData | DescriptionData | JoinData) => { if (data.room == null) return;