-
Notifications
You must be signed in to change notification settings - Fork 285
Expand file tree
/
Copy pathuseInactivityTimer.ts
More file actions
67 lines (55 loc) · 1.83 KB
/
useInactivityTimer.ts
File metadata and controls
67 lines (55 loc) · 1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { useCallback, useEffect, useRef } from 'react';
import { isOnline } from '../../utils/system/network';
const events = ['mousedown', 'keypress', 'click'];
/**
* Hook that triggers a callback after a specified period of user inactivity.
* User activity (mousedown, keypress, click) resets the timer.
*
* @param callback - The function to call once inactivity exceeds `delay`.
* @param delay - Inactivity timeout in milliseconds.
*/
export const useInactivityTimer = (callback: () => void, delay: number) => {
const savedCallback = useRef<(() => void) | null>(null);
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
// Remember the latest callback
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Reset the inactivity timer
const resetTimer = useCallback(() => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
if (delay !== null && savedCallback.current) {
timeoutRef.current = setTimeout(() => {
// Fire callback once inactivity threshold reached if online
if (savedCallback.current && isOnline()) {
savedCallback.current();
}
// Schedule next run while still inactive
resetTimer();
}, delay);
}
}, [delay]);
// Set up event listeners for user activity
useEffect(() => {
if (delay === null) {
return;
}
// Add event listeners to track activity
for (const event of events) {
document.addEventListener(event, resetTimer, { passive: true });
}
// Start initial timer
resetTimer();
// Cleanup function
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
for (const event of events) {
document.removeEventListener(event, resetTimer);
}
};
}, [delay, resetTimer]);
};