Compare commits

..

4 Commits

Author SHA1 Message Date
semantic-release-bot
3cdc0695f4 chore(release): 2.8.5 [skip ci]
## [2.8.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.8.4...v2.8.5) (2025-10-09)

### Bug Fixes

* remove redirect loop by not redirecting from room page ([10cf715](10cf71527f))
2025-10-09 01:17:27 +00:00
Thomas Hallock
10cf71527f fix: remove redirect loop by not redirecting from room page
The infinite redirect loop was caused by:
1. /arcade/room redirecting to /arcade when roomData is null
2. /arcade (via useArcadeRedirect) redirecting back to /arcade/room for active session
3. Loop repeats

Fix: Remove the redirect from room page entirely. Instead:
- Show loading state while fetching roomData
- Show error message with link if no room found (no automatic redirect)
- Let useArcadeRedirect on /arcade handle active session redirects

This prevents the redirect conflict and allows proper navigation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 20:16:27 -05:00
semantic-release-bot
678f4423b6 chore(release): 2.8.4 [skip ci]
## [2.8.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.8.3...v2.8.4) (2025-10-09)

### Bug Fixes

* prevent redirect loops by checking if already at target URL ([c5268b7](c5268b79de))
2025-10-09 01:11:33 +00:00
Thomas Hallock
c5268b79de fix: prevent redirect loops by checking if already at target URL
Both useArcadeRedirect and useArcadeGuard were causing infinite loops:
1. User navigates to /arcade/room
2. Room page redirects to /arcade (if roomData null during loading)
3. /arcade sees active session at /arcade/room, redirects back
4. Loop repeats

Fix: Check if pathname already matches target URL before redirecting.
If already at target, skip the redirect and log that we're already there.

This fixes the infinite redirect loop when navigating to /arcade/room.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-08 20:10:40 -05:00
5 changed files with 57 additions and 16 deletions

View File

@@ -1,3 +1,17 @@
## [2.8.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.8.4...v2.8.5) (2025-10-09)
### Bug Fixes
* remove redirect loop by not redirecting from room page ([10cf715](https://github.com/antialias/soroban-abacus-flashcards/commit/10cf71527f7cede7fd93e502dbfc59df99b5a524))
## [2.8.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.8.3...v2.8.4) (2025-10-09)
### Bug Fixes
* prevent redirect loops by checking if already at target URL ([c5268b7](https://github.com/antialias/soroban-abacus-flashcards/commit/c5268b79dee66aa02e14e2024fe1c6242a172ed3))
## [2.8.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.8.2...v2.8.3) (2025-10-08)

View File

@@ -1,7 +1,5 @@
'use client'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
import { useRoomData } from '@/hooks/useRoomData'
import { MemoryPairsGame } from '../matching/components/MemoryPairsGame'
import { ArcadeMemoryPairsProvider } from '../matching/context/ArcadeMemoryPairsContext'
@@ -9,18 +7,14 @@ import { ArcadeMemoryPairsProvider } from '../matching/context/ArcadeMemoryPairs
/**
* /arcade/room - Renders the game for the user's current room
* Since users can only be in one room at a time, this is a simple singular route
*
* Note: We don't redirect to /arcade if no room exists because:
* - It would conflict with arcade session redirects and create loops
* - useArcadeRedirect on /arcade page handles redirecting to active sessions
*/
export default function RoomPage() {
const router = useRouter()
const { roomData, isLoading } = useRoomData()
// Redirect to arcade if no room
useEffect(() => {
if (!isLoading && !roomData) {
router.push('/arcade')
}
}, [isLoading, roomData, router])
// Show loading state
if (isLoading) {
return (
@@ -39,9 +33,33 @@ export default function RoomPage() {
)
}
// Show nothing while redirecting
// Show error if no room (instead of redirecting)
if (!roomData) {
return null
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
fontSize: '18px',
color: '#666',
gap: '1rem',
}}
>
<div>No active room found</div>
<a
href="/arcade"
style={{
color: '#3b82f6',
textDecoration: 'underline',
}}
>
Go to Champion Arena
</a>
</div>
)
}
// Render the appropriate game based on room's gameName

View File

@@ -74,10 +74,13 @@ export function useArcadeGuard(options: UseArcadeGuardOptions = {}): UseArcadeGu
})
// Redirect if we're not already on the active game page (only if enabled)
if (enabled && pathname !== data.gameUrl) {
const isAlreadyAtTarget = pathname === data.gameUrl
if (enabled && !isAlreadyAtTarget) {
console.log('[ArcadeGuard] Redirecting to active session:', data.gameUrl)
onRedirect?.(data.gameUrl)
router.push(data.gameUrl)
} else if (isAlreadyAtTarget) {
console.log('[ArcadeGuard] Already at target URL, no redirect needed')
}
},
@@ -127,10 +130,13 @@ export function useArcadeGuard(options: UseArcadeGuardOptions = {}): UseArcadeGu
})
// Redirect if we're not already on the active game page (only if enabled)
if (enabled && pathname !== session.gameUrl) {
const isAlreadyAtTarget = pathname === session.gameUrl
if (enabled && !isAlreadyAtTarget) {
console.log('[ArcadeGuard] Redirecting to active session:', session.gameUrl)
onRedirect?.(session.gameUrl)
router.push(session.gameUrl)
} else if (isAlreadyAtTarget) {
console.log('[ArcadeGuard] Already at target URL, no redirect needed')
}
} else if (response.status === 404) {
// No active session

View File

@@ -71,10 +71,13 @@ export function useArcadeRedirect(options: UseArcadeRedirectOptions = {}): UseAr
// Determine if we need to redirect
const isArcadeLobby = currentGame === null || currentGame === undefined
const isWrongGame = currentGame && currentGame !== data.currentGame
const isAlreadyAtTarget = _pathname === data.gameUrl
if (isArcadeLobby || isWrongGame) {
if ((isArcadeLobby || isWrongGame) && !isAlreadyAtTarget) {
console.log('[ArcadeRedirect] Redirecting to active game:', data.gameUrl)
router.push(data.gameUrl)
} else if (isAlreadyAtTarget) {
console.log('[ArcadeRedirect] Already at target URL, no redirect needed')
}
},

View File

@@ -1,6 +1,6 @@
{
"name": "soroban-monorepo",
"version": "2.8.3",
"version": "2.8.5",
"private": true,
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
"workspaces": [