fix(useIdleDetection): debounce online status update to prevent duplicate calls

This commit is contained in:
Abhinav Raut
2025-05-12 21:59:06 +05:30
parent 8d47a7456d
commit 88e07c324d

View File

@@ -5,55 +5,52 @@ import { useStorage } from '@vueuse/core'
export function useIdleDetection () {
const userStore = useUserStore()
// 4 minutes
const AWAY_THRESHOLD = 4 * 60 * 1000
// 1 minute
const CHECK_INTERVAL = 60 * 1000
const CHECK_INTERVAL = 30 * 1000
// Store last activity time in localStorage to sync across tabs
const lastActivity = useStorage('last_active', Date.now())
const timer = ref(null)
function resetTimer () {
// Debounce the goOnline to prevent it from being called too frequently
const goOnline = debounce(() => {
if (userStore.user.availability_status === 'away' || userStore.user.availability_status === 'offline') {
userStore.updateUserAvailability('online', false)
}
const now = Date.now()
if (lastActivity.value < now) {
lastActivity.value = now
}
}, 200)
function resetTimer () {
lastActivity.value = Date.now()
}
const debouncedResetTimer = debounce(resetTimer, 200)
function checkIdle () {
if (Date.now() - lastActivity.value > AWAY_THRESHOLD &&
userStore.user.availability_status === 'online') {
if (
Date.now() - lastActivity.value > AWAY_THRESHOLD &&
userStore.user.availability_status === 'online'
) {
userStore.updateUserAvailability('away', false)
}
}
onMounted(() => {
window.addEventListener('mousemove', debouncedResetTimer)
window.addEventListener('keypress', debouncedResetTimer)
window.addEventListener('click', debouncedResetTimer)
['mousemove', 'keypress', 'click'].forEach(evt =>
window.addEventListener(evt, resetTimer)
)
timer.value = setInterval(checkIdle, CHECK_INTERVAL)
})
onBeforeUnmount(() => {
window.removeEventListener('mousemove', debouncedResetTimer)
window.removeEventListener('keypress', debouncedResetTimer)
window.removeEventListener('click', debouncedResetTimer)
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
['mousemove', 'keypress', 'click'].forEach(evt =>
window.removeEventListener(evt, resetTimer)
)
clearInterval(timer.value)
})
// Watch for lastActivity changes in localStorage to handle multi-tab sync
watch(lastActivity, (newVal, oldVal) => {
if (newVal > oldVal) {
resetTimer()
if (
newVal > oldVal &&
document.visibilityState === 'visible'
) {
goOnline()
}
})
}