Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions apps/meteor/app/lib/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import '../lib/MessageTypes';
import './OAuthProxy';
import './methods/sendMessage';

export * from './lib';
67 changes: 0 additions & 67 deletions apps/meteor/app/lib/client/lib/LoginPresence.ts

This file was deleted.

1 change: 0 additions & 1 deletion apps/meteor/app/lib/client/lib/index.ts

This file was deleted.

11 changes: 4 additions & 7 deletions apps/meteor/client/components/AutoupdateToastMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import { css } from '@rocket.chat/css-in-js';
import { Box, Button } from '@rocket.chat/fuselage';
import { useTranslation } from 'react-i18next';

import { useIdleDetection } from '../hooks/useIdleDetection';
import { useIdleActiveEvents } from '../hooks/useIdleActiveEvents';

export const AutoupdateToastMessage = () => {
const { t } = useTranslation();
useIdleDetection(
() => {
window.location.reload();
},
{ awayOnWindowBlur: true },
);
useIdleActiveEvents({ id: 'autoupdate', awayOnWindowBlur: true }, () => {
window.location.reload();
});

return (
<Box
Expand Down
47 changes: 47 additions & 0 deletions apps/meteor/client/hooks/useIdleActiveEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useEffect } from 'react';

import { useIdleDetection } from './useIdleDetection';

/**
* useIdleActiveEvents is a custom hook that triggers a callback function when the user is detected to be idle, and another callback function when the user is detected to be active.
* The idle state is determined based on the absence of certain user interactions for a specified time period.
*
* @param options - A configuration object.
* @param options.id - A unique identifier for the idle detection mechanism.
* @param options.time - The time in milliseconds to consider the user idle. Optional. Defaults to 600000 ms (10 minutes).
* @param options.awayOnWindowBlur - A boolean flag to trigger the callback when the window loses focus. Optional. Defaults to false.
* @param onIdleCallback - The callback function to be called when the user is detected to be idle.
* @param onActiveCallback - The callback function to be called when the user is detected to be active.
*
*/

export const useIdleActiveEvents = (
{
id,
time,
awayOnWindowBlur,
}: {
id: string;
time?: number;
awayOnWindowBlur?: boolean;
},
onIdleCallback: () => void,
onActiveCallback?: () => void,
) => {
const stableIdleCallback = useEffectEvent(onIdleCallback);
const stableActiveCallback = useEffectEvent(onActiveCallback || (() => undefined));

useEffect(() => {
document.addEventListener(`${id}_idle`, stableIdleCallback);

onActiveCallback && document.addEventListener(`${id}_active`, stableActiveCallback);

return () => {
document.removeEventListener(`${id}_idle`, stableIdleCallback);
document.removeEventListener(`${id}_active`, stableActiveCallback);
};
}, [id, onActiveCallback, stableActiveCallback, stableIdleCallback]);

return useIdleDetection({ id, time, awayOnWindowBlur });
};
28 changes: 28 additions & 0 deletions apps/meteor/client/hooks/useIdleConnection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { ServerContext, useConnectionStatus, useSetting, useUserId } from '@rocket.chat/ui-contexts';
import { useContext } from 'react';

import { useIdleActiveEvents } from './useIdleActiveEvents';

export const useIdleConnection = () => {
const uid = useUserId();
const { status } = useConnectionStatus();
const allowAnonymousRead = useSetting('Accounts_AllowAnonymousRead');
const { disconnect: disconnectServer, reconnect: reconnectServer } = useContext(ServerContext);

const disconnect = useEffectEvent(() => {
if (status === 'offline') {
if (!uid && allowAnonymousRead !== true) {
disconnectServer();
}
}
});

const reconnect = useEffectEvent(() => {
if (status === 'offline') {
reconnectServer();
}
});

useIdleActiveEvents({ id: 'useLoginPresence', time: 3000, awayOnWindowBlur: true }, disconnect, reconnect);
};
69 changes: 47 additions & 22 deletions apps/meteor/client/hooks/useIdleDetection.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,58 @@
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useEffect } from 'react';
import { useEffect, useReducer } from 'react';

const events = ['mousemove', 'mousedown', 'touchend', 'touchstart', 'keypress'];

type UseIdleDetectionOptions = {
id?: string;
time?: number;
awayOnWindowBlur?: boolean;
};

/**
* useIdleDetection is a custom hook that triggers a callback function when the user is detected to be idle.
* The idle state is determined based on the absence of certain user interactions for a specified time period.
* A hook that detects when the user is idle.
*
* @param callback - The callback function to be called when the user is detected to be idle.
* @param options - An optional configuration object.
* @param options.time - The time in milliseconds to consider the user idle. Defaults to 600000 ms (10 minutes).
* @param options.awayOnWindowBlur - A boolean flag to trigger the callback when the window loses focus. Defaults to false.
* This hook listens for mousemove, mousedown, touchend, touchstart, and keypress events.
* When any of these events are triggered, the user is considered active.
* If no events are triggered for a specified period of time, the user is considered idle.
*
* @param {object} options - An object with the following properties:
* @param {string} options.id - A unique identifier for the idle detection mechanism. Defaults to 'useIdleDetection'.
* @param {number} options.time - The time in milliseconds to consider the user idle. Defaults to 600000 ms (10 minutes).
* @param {boolean} options.awayOnWindowBlur - A boolean flag to trigger the idle state when the window loses focus. Defaults to false.
*
* @returns {boolean} A boolean indicating whether the user is idle or not.
*/

export const useIdleDetection = (callback: () => void, { time = 600000, awayOnWindowBlur = false } = {}) => {
const stableCallback = useEffectEvent(callback);
export const useIdleDetection = ({ id = 'useIdleDetection', time = 600000, awayOnWindowBlur = false }: UseIdleDetectionOptions = {}) => {
const [isIdle, dispatch] = useReducer((state: boolean, action: boolean) => {
if (state === action) {
return state;
}

if (action) {
document.dispatchEvent(new Event(`${id}_idle`));
}

if (!action) {
document.dispatchEvent(new Event(`${id}_active`));
}

document.dispatchEvent(
new CustomEvent(`${id}_change`, {
detail: { isIdle: action },
}),
);

return action;
}, false);

useEffect(() => {
let interval: ReturnType<typeof setTimeout>;
const handleIdle = () => {
dispatch(false);
clearTimeout(interval);
interval = setTimeout(() => {
document.dispatchEvent(new Event('idle'));
dispatch(true);
}, time);
};

Expand All @@ -33,24 +63,19 @@ export const useIdleDetection = (callback: () => void, { time = 600000, awayOnWi
clearTimeout(interval);
events.forEach((key) => document.removeEventListener(key, handleIdle));
};
}, [stableCallback, time]);
}, [time]);

useEffect(() => {
if (!awayOnWindowBlur) {
return;
}

window.addEventListener('blur', stableCallback);
const dispatchIdle = () => dispatch(true);
window.addEventListener('blur', dispatchIdle);
return () => {
window.removeEventListener('blur', stableCallback);
window.removeEventListener('blur', dispatchIdle);
};
}, [awayOnWindowBlur, stableCallback]);
}, [awayOnWindowBlur]);

useEffect(() => {
document.addEventListener('idle', stableCallback);

return () => {
document.removeEventListener('idle', stableCallback);
};
}, [stableCallback]);
return isIdle;
};
2 changes: 2 additions & 0 deletions apps/meteor/client/providers/UserProvider/UserProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Subscriptions, Rooms } from '../../../app/models/client';
import { getUserPreference } from '../../../app/utils/client';
import { sdk } from '../../../app/utils/client/lib/SDKClient';
import { afterLogoutCleanUpCallback } from '../../../lib/callbacks/afterLogoutCleanUpCallback';
import { useIdleConnection } from '../../hooks/useIdleConnection';
import { useReactiveValue } from '../../hooks/useReactiveValue';
import { createReactiveSubscriptionFactory } from '../../lib/createReactiveSubscriptionFactory';
import { useCreateFontStyleElement } from '../../views/account/accessibility/hooks/useCreateFontStyleElement';
Expand Down Expand Up @@ -62,6 +63,7 @@ const UserProvider = ({ children }: UserProviderProps): ReactElement => {

useDeleteUser();
useUpdateAvatar();
useIdleConnection();

const contextValue = useMemo(
(): ContextType<typeof UserContext> => ({
Expand Down
Loading