All files / web/src/components/toys/euclid/interaction tickTutorialAdvancement.ts

0% Statements 0/83
0% Branches 0/1
0% Functions 0/1
0% Lines 0/83

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                                                                                                                                                                       
import type { RAFContext } from '../engine/rafContext'

/**
 * Observe tool phase transitions (compass, straightedge, extend, macro)
 * and advance tutorial sub-steps accordingly. Called once per RAF frame.
 *
 * Returns the effective sub-steps for the current step (used later in the frame).
 */
export function tickTutorialAdvancement(ctx: RAFContext) {
  const subSteps = ctx.tutorialSubStepsRef.current
  const step = ctx.currentStepRef.current
  const subStep = ctx.tutorialSubStepRef.current
  // Prefer resolved tutorial overrides for adaptive steps
  const effectiveSubStepsForStep = ctx.resolvedTutorialRef.current.get(step) ?? subSteps[step]

  // ── Compass phase transitions ──
  const compassTag = ctx.compassPhaseRef.current.tag
  if (compassTag !== ctx.prevCompassTagRef.current) {
    const prev = ctx.prevCompassTagRef.current
    ctx.prevCompassTagRef.current = compassTag

    if (compassTag === 'idle' && prev !== 'idle') {
      // Gesture cancelled or completed — reset sub-step
      ctx.tutorialSubStepRef.current = 0
      ctx.setTutorialSubStep(0)
    } else {
      const subStepDef = effectiveSubStepsForStep?.[subStep]
      const adv = subStepDef?.advanceOn
      if (adv?.kind === 'compass-phase' && adv.phase === compassTag) {
        const next = subStep + 1
        ctx.tutorialSubStepRef.current = next
        ctx.setTutorialSubStep(next)
      }
    }
  }

  // ── Straightedge phase transitions ──
  const straightedgeTag = ctx.straightedgePhaseRef.current.tag
  if (straightedgeTag !== ctx.prevStraightedgeTagRef.current) {
    const prev = ctx.prevStraightedgeTagRef.current
    ctx.prevStraightedgeTagRef.current = straightedgeTag

    if (straightedgeTag === 'idle' && prev !== 'idle') {
      ctx.tutorialSubStepRef.current = 0
      ctx.setTutorialSubStep(0)
    }
  }

  // ── Extend phase transitions ──
  const extendTag = ctx.extendPhaseRef.current.tag
  if (extendTag !== ctx.prevExtendTagRef.current) {
    const prev = ctx.prevExtendTagRef.current
    ctx.prevExtendTagRef.current = extendTag

    if (extendTag === 'idle' && prev !== 'idle') {
      // Extend gesture completed or cancelled — reset sub-step
      ctx.tutorialSubStepRef.current = 0
      ctx.setTutorialSubStep(0)
    } else {
      const subStepDef = effectiveSubStepsForStep?.[subStep]
      const adv = subStepDef?.advanceOn
      if (adv?.kind === 'extend-phase' && adv.phase === extendTag) {
        const next = subStep + 1
        ctx.tutorialSubStepRef.current = next
        ctx.setTutorialSubStep(next)
      }
    }
  }

  // ── Macro phase transitions ──
  const macroPhase = ctx.macroPhaseRef.current
  if (macroPhase.tag === 'selecting' && macroPhase.selectedPointIds.length > 0) {
    const subStepDef = effectiveSubStepsForStep?.[subStep]
    const adv = subStepDef?.advanceOn
    if (adv?.kind === 'macro-select' && adv.index === macroPhase.selectedPointIds.length - 1) {
      const next = subStep + 1
      ctx.tutorialSubStepRef.current = next
      ctx.setTutorialSubStep(next)
    }
  }

  return effectiveSubStepsForStep
}