fix: stabilize smart help detection with timer-based state

- Replace unstable render-time calculations with useState timer
- Add useEffect to manage 8-second help timer lifecycle
- Reset help state when advancing to new multi-step
- Fix issue where help only appeared momentarily during bead transitions
- Simplify logic: help shows after 8 seconds if user needs to act
- Provide stable, persistent help display until step completion

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-09-23 08:50:24 -05:00
parent 933b94856d
commit 9cc3a0ea9b

View File

@@ -156,6 +156,7 @@ export function TutorialPlayer({
}: TutorialPlayerProps) {
const [startTime] = useState(Date.now())
const isProgrammaticChange = useRef(false)
const [showHelpForCurrentStep, setShowHelpForCurrentStep] = useState(false)
const [state, dispatch] = useReducer(tutorialPlayerReducer, {
currentStepIndex: initialStepIndex,
@@ -285,6 +286,17 @@ export function TutorialPlayer({
// Get current step summary for real-time user feedback
const currentStepSummary = getCurrentStepSummary()
// Timer for smart help detection
useEffect(() => {
setShowHelpForCurrentStep(false) // Reset help when step changes
const timer = setTimeout(() => {
setShowHelpForCurrentStep(true)
}, 8000) // 8 seconds
return () => clearTimeout(timer)
}, [currentMultiStep, multiStepStartTime]) // Reset when step changes or timer resets
// Helper function to highlight the current mathematical term in the full decomposition
const renderHighlightedDecomposition = useCallback(() => {
if (!fullDecomposition || expectedSteps.length === 0) return null
@@ -923,13 +935,11 @@ export function TutorialPlayer({
const hasMeaningfulSummary = currentStepSummary && !currentStepSummary.includes('No changes needed')
// Smart help detection - show help when user might be confused or stalled
const timeOnCurrentStep = Date.now() - multiStepStartTime
const hasBeenOnStepTooLong = timeOnCurrentStep > 10000 // 10 seconds
const isWrongValue = !isAtExpectedStartingState && currentValue !== expectedSteps[currentMultiStep]?.targetValue
const shouldShowHelp = hasBeenOnStepTooLong || (isWrongValue && timeOnCurrentStep > 5000) // 5 seconds if wrong value
const needsAction = !isAtExpectedStartingState && hasMeaningfulSummary && shouldShowHelp
// Only show help if:
// 1. Not at expected starting state (user needs to do something)
// 2. Has meaningful summary to show
// 3. Timer has expired (user appears stuck for 8+ seconds)
const needsAction = !isAtExpectedStartingState && hasMeaningfulSummary && showHelpForCurrentStep
return (
<div>