feat(card-sorting): add auto-submit countdown for perfect sequences
When the card sequence is correct, a countdown timer now starts: - Shows 3, 2, 1 in the submit button (1.5s per number) - Auto-submits the solution when countdown reaches 0 - Countdown resets if sequence becomes imperfect - Countdown disabled for spectators This provides: - Visual feedback that the sequence is correct - Automatic submission without requiring a click - Time for players to review before submission - Smooth game flow when solving perfectly Implementation: - perfectCountdown state tracks current number (3, 2, 1, or null) - First useEffect starts/resets countdown based on isSequenceCorrect - Second useEffect decrements countdown every 1.5s and auto-submits at 0 - Button displays countdown number when active, otherwise shows checkmark 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -867,6 +867,9 @@ export function PlayingPhaseDrag() {
|
||||
const [activityFeed, setActivityFeed] = useState<ActivityNotification[]>([])
|
||||
const activityIdCounter = useRef(0)
|
||||
|
||||
// Perfect sequence countdown (auto-submit after 3-2-1)
|
||||
const [perfectCountdown, setPerfectCountdown] = useState<number | null>(null)
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const dragStateRef = useRef<{
|
||||
cardId: string
|
||||
@@ -1312,6 +1315,36 @@ export function PlayingPhaseDrag() {
|
||||
return correctCard && card.id === correctCard.id
|
||||
})
|
||||
|
||||
// Start countdown when sequence is perfect
|
||||
useEffect(() => {
|
||||
if (isSequenceCorrect && !isSpectating) {
|
||||
// Start countdown from 3
|
||||
setPerfectCountdown(3)
|
||||
} else {
|
||||
// Reset countdown if sequence is no longer perfect
|
||||
setPerfectCountdown(null)
|
||||
}
|
||||
}, [isSequenceCorrect, isSpectating])
|
||||
|
||||
// Countdown timer effect
|
||||
useEffect(() => {
|
||||
if (perfectCountdown === null) return
|
||||
if (perfectCountdown <= 0) {
|
||||
// Auto-submit when countdown reaches 0
|
||||
handleCheckSolution()
|
||||
setPerfectCountdown(null)
|
||||
return
|
||||
}
|
||||
|
||||
// Decrement every 1.5 seconds
|
||||
const timer = setTimeout(() => {
|
||||
setPerfectCountdown((prev) => (prev !== null ? prev - 1 : null))
|
||||
}, 1500)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [perfectCountdown])
|
||||
|
||||
// Watch for server confirmations and insert next card or check solution
|
||||
useEffect(() => {
|
||||
if (!waitingToCheck) return
|
||||
@@ -1722,7 +1755,7 @@ export function PlayingPhaseDrag() {
|
||||
animationName: isSequenceCorrect ? 'celebrate' : undefined,
|
||||
}}
|
||||
>
|
||||
✓
|
||||
{perfectCountdown !== null && perfectCountdown > 0 ? perfectCountdown : '✓'}
|
||||
</button>
|
||||
<div
|
||||
className={css({
|
||||
|
||||
Reference in New Issue
Block a user