[PR #1913] [MERGED] fix(staffml): cancel StarGate's verify-delay timer on unmount #32182

Closed
opened 2026-07-12 08:50:55 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/harvard-edge/cs249r_book/pull/1913
Author: @farhan523
Created: 6/28/2026
Status: Merged
Merged: 7/10/2026
Merged by: @profvjreddi

Base: devHead: fix/stargate-clear-verify-timeout


📝 Commits (1)

  • 91fe269 fix(staffml): cancel StarGate's verify-delay timer on unmount

📊 Changes

2 files changed (+92 additions, -2 deletions)

View changed files

interviews/staffml/src/__tests__/stargate-timer-cleanup.test.tsx (+74 -0)
📝 interviews/staffml/src/components/StarGate.tsx (+18 -2)

📄 Description

Summary

Both handleStar ("Star on GitHub") and handleAlreadyStarred ("I already starred") fired setTimeout(onVerified, 1500) to let the user see the "Thank you" confirmation panel before the parent dismisses the gate. The returned timer id was never stored, so if the gate unmounted within that 1.5s window — parent route change, programmatic close, or anything that removes StarGate from the tree — the timer kept running and onVerified fired later on an unmounted parent.

Today the only caller (practice/page.tsx) treats a stray onVerified call as a no-op (it just sets showStarGate=false which was already false), so this was a latent leak, not a visible bug. But the contract becomes accidentally correct rather than correct-by-design — a future caller where onVerified mutates state on a stale tree would surface it immediately.

Changes

  • Store the timer id in verifyTimeoutRef (mirrors the focus-timer pattern already in the same file).
  • Add a no-deps cleanup useEffect that clears verifyTimeoutRef.current on unmount.
  • Both handlers assign into the same ref, which also implicitly handles the unlikely back-to-back click case.

Test plan

  • npx vitest run → 129/129 across 23 files passing (was 126; +3 new for unmount-after-Star, unmount-after-Already-starred, and still-mounted-fires-at-1.5s).
  • npx tsc --noEmit → clean.
  • Manual repro (the regression isn't user-visible today; the test is the verification surface).

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/harvard-edge/cs249r_book/pull/1913 **Author:** [@farhan523](https://github.com/farhan523) **Created:** 6/28/2026 **Status:** ✅ Merged **Merged:** 7/10/2026 **Merged by:** [@profvjreddi](https://github.com/profvjreddi) **Base:** `dev` ← **Head:** `fix/stargate-clear-verify-timeout` --- ### 📝 Commits (1) - [`91fe269`](https://github.com/harvard-edge/cs249r_book/commit/91fe269d91e51de3bdd042da6066df7fae4f7429) fix(staffml): cancel StarGate's verify-delay timer on unmount ### 📊 Changes **2 files changed** (+92 additions, -2 deletions) <details> <summary>View changed files</summary> ➕ `interviews/staffml/src/__tests__/stargate-timer-cleanup.test.tsx` (+74 -0) 📝 `interviews/staffml/src/components/StarGate.tsx` (+18 -2) </details> ### 📄 Description ## Summary Both `handleStar` (\"Star on GitHub\") and `handleAlreadyStarred` (\"I already starred\") fired `setTimeout(onVerified, 1500)` to let the user see the \"Thank you\" confirmation panel before the parent dismisses the gate. The returned timer id was never stored, so if the gate unmounted within that 1.5s window — parent route change, programmatic close, or anything that removes `StarGate` from the tree — the timer kept running and `onVerified` fired later on an unmounted parent. Today the only caller (`practice/page.tsx`) treats a stray `onVerified` call as a no-op (it just sets `showStarGate=false` which was already false), so this was a **latent** leak, not a visible bug. But the contract becomes accidentally correct rather than correct-by-design — a future caller where `onVerified` mutates state on a stale tree would surface it immediately. ### Changes - Store the timer id in `verifyTimeoutRef` (mirrors the focus-timer pattern already in the same file). - Add a no-deps cleanup `useEffect` that clears `verifyTimeoutRef.current` on unmount. - Both handlers assign into the same ref, which also implicitly handles the unlikely back-to-back click case. ## Test plan - [x] `npx vitest run` → 129/129 across 23 files passing (was 126; +3 new for unmount-after-Star, unmount-after-Already-starred, and still-mounted-fires-at-1.5s). - [x] `npx tsc --noEmit` → clean. - [ ] Manual repro (the regression isn't user-visible today; the test is the verification surface). --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-07-12 08:50:55 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/cs249r_book#32182