Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | /** * Struggle Detection Hook * * Monitors user search behavior and automatically advances to the next hint * when the user appears to be struggling (based on time spent searching). */ import { useEffect, useRef } from 'react' // Thresholds for triggering next hint const STRUGGLE_TIME_THRESHOLD = 30000 // 30 seconds per hint level const STRUGGLE_CHECK_INTERVAL = 5000 // Check every 5 seconds export interface UseStruggleDetectionOptions { /** Whether hot/cold feedback is enabled (implies we're tracking search metrics) */ effectiveHotColdEnabled: boolean /** Whether there are more hints available to show */ hasMoreHints: boolean /** Current region prompt ID */ currentPrompt: string | null /** Function to get search metrics */ getSearchMetrics: (startTime: number) => { timeToFind: number } /** Function to advance to next hint */ nextHint: () => void /** Ref to prompt start time */ promptStartTime: React.RefObject<number> } /** * Hook that detects when a user is struggling to find a region and * automatically advances to the next hint level. * * Hint levels are based on time: * - Level 0 = first 30 seconds * - Level 1 = 30-60 seconds * - Level 2 = 60-90 seconds * - etc. */ export function useStruggleDetection({ effectiveHotColdEnabled, hasMoreHints, currentPrompt, getSearchMetrics, nextHint, promptStartTime, }: UseStruggleDetectionOptions): void { // Track which hint level triggered last hint const lastHintLevelRef = useRef(0) // Check for struggle and advance hint useEffect(() => { // Only run if hot/cold is enabled (means we're tracking search metrics) if (!effectiveHotColdEnabled || !hasMoreHints || !currentPrompt) return const checkStruggle = () => { const metrics = getSearchMetrics(promptStartTime.current ?? Date.now()) // Calculate which hint level we should be at based on time // Level 0 = first 30 seconds, Level 1 = 30-60 seconds, etc. const expectedHintLevel = Math.floor(metrics.timeToFind / STRUGGLE_TIME_THRESHOLD) // If we should be at a higher hint level than last triggered, give next hint if (expectedHintLevel > lastHintLevelRef.current && hasMoreHints) { lastHintLevelRef.current = expectedHintLevel nextHint() } } const intervalId = setInterval(checkStruggle, STRUGGLE_CHECK_INTERVAL) return () => clearInterval(intervalId) }, [ effectiveHotColdEnabled, hasMoreHints, currentPrompt, getSearchMetrics, nextHint, promptStartTime, ]) // Reset hint level tracking when prompt changes useEffect(() => { lastHintLevelRef.current = 0 }, [currentPrompt]) } |