ironie-nextjs/src/app/components/UserActivityTracker.tsx
2025-09-08 15:30:46 +02:00

61 lines
1.8 KiB
TypeScript

// UserActivityTracker.tsx
'use client'
import { useEffect, useRef } from 'react'
import { useSession } from 'next-auth/react'
type Presence = 'online' | 'away' | 'offline'
export default function UserActivityTracker() {
const { data: session } = useSession()
const lastActivityRef = useRef<number>(Date.now())
const prevStatusRef = useRef<Presence>('offline')
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
useEffect(() => {
if (!session?.user?.steamId) return
const markActive = () => { lastActivityRef.current = Date.now() }
const tick = () => {
const diffMs = Date.now() - lastActivityRef.current
const nextStatus: Presence = diffMs < 30_000 ? 'online' : 'away'
if (nextStatus !== prevStatusRef.current) {
prevStatusRef.current = nextStatus
fetch(nextStatus === 'online' ? '/api/user/activity' : '/api/user/away', { method: 'POST' })
.catch(() => {})
}
}
// Initial online
prevStatusRef.current = 'away'
markActive()
tick()
intervalRef.current = setInterval(tick, 5_000)
// Activity Events
window.addEventListener('mousemove', markActive)
window.addEventListener('keydown', markActive)
window.addEventListener('touchstart', markActive)
document.addEventListener('visibilitychange', () => {
if (!document.hidden) markActive()
})
return () => {
window.removeEventListener('mousemove', markActive)
window.removeEventListener('keydown', markActive)
window.removeEventListener('touchstart', markActive)
document.removeEventListener('visibilitychange', () => {
if (!document.hidden) markActive()
})
if (intervalRef.current) clearInterval(intervalRef.current)
}
}, [session?.user?.steamId])
return null
}