Files
Portfolio-Game/frontend/app/composables/useIdleDetection.ts
skycel 99fa61fcaa feat(frontend): système narrateur contextuel avec arc de révélation
Story 3.3 : Textes narrateur contextuels et arc de révélation
- Composable useNarrator.ts avec queue de messages prioritaires
- Composable useIdleDetection.ts (détection inactivité 30s)
- Plugin narrator-transitions.client.ts (déclencheurs de navigation)
- Layout adventure.vue avec NarratorBubble intégré
- Store progression: narratorStage devient un getter calculé (0-20-40-60-80%)
- Pages projets, competences, temoignages, parcours utilisent layout adventure
- Messages: intro, transitions, encouragements 25/50/75%, hints, contact_unlocked

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 03:04:07 +01:00

45 lines
1011 B
TypeScript

export interface UseIdleDetectionOptions {
timeout?: number
onIdle?: () => void
}
export function useIdleDetection(options: UseIdleDetectionOptions = {}) {
const { timeout = 30000, onIdle } = options
const isIdle = ref(false)
let timeoutId: ReturnType<typeof setTimeout> | null = null
function resetTimer() {
isIdle.value = false
if (timeoutId) {
clearTimeout(timeoutId)
}
timeoutId = setTimeout(() => {
isIdle.value = true
onIdle?.()
}, timeout)
}
const events = ['mousedown', 'mousemove', 'keydown', 'scroll', 'touchstart']
if (import.meta.client) {
onMounted(() => {
events.forEach((event) => {
window.addEventListener(event, resetTimer, { passive: true })
})
resetTimer()
})
onUnmounted(() => {
events.forEach((event) => {
window.removeEventListener(event, resetTimer)
})
if (timeoutId) {
clearTimeout(timeoutId)
}
})
}
return { isIdle: readonly(isIdle) }
}