/
index.ts
97 lines (86 loc) · 2.3 KB
/
index.ts
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import type { ConfigurableEventFilter } from '@vueuse/shared'
import { createFilterWrapper, throttleFilter, timestamp } from '@vueuse/shared'
import type { Ref } from 'vue-demi'
import { ref } from 'vue-demi'
import type { WindowEventName } from '../useEventListener'
import { useEventListener } from '../useEventListener'
import type { ConfigurableWindow } from '../_configurable'
import { defaultWindow } from '../_configurable'
const defaultEvents: WindowEventName[] = ['mousemove', 'mousedown', 'resize', 'keydown', 'touchstart', 'wheel']
const oneMinute = 60_000
export interface UseIdleOptions extends ConfigurableWindow, ConfigurableEventFilter {
/**
* Event names that listen to for detected user activity
*
* @default ['mousemove', 'mousedown', 'resize', 'keydown', 'touchstart', 'wheel']
*/
events?: WindowEventName[]
/**
* Listen for document visibility change
*
* @default true
*/
listenForVisibilityChange?: boolean
/**
* Initial state of the ref idle
*
* @default false
*/
initialState?: boolean
}
export interface UseIdleReturn {
idle: Ref<boolean>
lastActive: Ref<number>
reset: () => void
}
/**
* Tracks whether the user is being inactive.
*
* @see https://vueuse.org/useIdle
* @param timeout default to 1 minute
* @param options IdleOptions
*/
export function useIdle(
timeout: number = oneMinute,
options: UseIdleOptions = {},
): UseIdleReturn {
const {
initialState = false,
listenForVisibilityChange = true,
events = defaultEvents,
window = defaultWindow,
eventFilter = throttleFilter(50),
} = options
const idle = ref(initialState)
const lastActive = ref(timestamp())
let timer: any
const reset = () => {
idle.value = false
clearTimeout(timer)
timer = setTimeout(() => idle.value = true, timeout)
}
const onEvent = createFilterWrapper(
eventFilter,
() => {
lastActive.value = timestamp()
reset()
},
)
if (window) {
const document = window.document
for (const event of events)
useEventListener(window, event, onEvent, { passive: true })
if (listenForVisibilityChange) {
useEventListener(document, 'visibilitychange', () => {
if (!document.hidden)
onEvent()
})
}
reset()
}
return {
idle,
lastActive,
reset,
}
}