Fix: Zeige Ergebnis statt Solve/Give Up Button bei bereits abgeschlossenen Rätseln
- Verwende gameState.isSolved/isFailed direkt für UI-Logik - Behebt Problem, dass Solve/Give Up Button bei zurückkehrenden Rätseln angezeigt wurde - isSolved/isFailed werden jetzt direkt aus gameState gelesen für sofortige Konsistenz
This commit is contained in:
@@ -96,6 +96,10 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
if (gameState.isSolved && !gameState.yearGuessed && dailyPuzzle?.releaseYear) {
|
if (gameState.isSolved && !gameState.yearGuessed && dailyPuzzle?.releaseYear) {
|
||||||
setShowYearModal(true);
|
setShowYearModal(true);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Reset states when gameState is null (e.g., during loading)
|
||||||
|
setHasWon(false);
|
||||||
|
setHasLost(false);
|
||||||
}
|
}
|
||||||
}, [gameState, dailyPuzzle]);
|
}, [gameState, dailyPuzzle]);
|
||||||
|
|
||||||
@@ -163,6 +167,10 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
if (!gameState) return <div>{t('loadingState')}</div>;
|
if (!gameState) return <div>{t('loadingState')}</div>;
|
||||||
|
|
||||||
|
// Use gameState directly for isSolved/isFailed to ensure consistency when returning to completed puzzles
|
||||||
|
const isSolved = gameState?.isSolved ?? hasWon;
|
||||||
|
const isFailed = gameState?.isFailed ?? hasLost;
|
||||||
|
|
||||||
const handleGuess = (song: any) => {
|
const handleGuess = (song: any) => {
|
||||||
if (isProcessingGuess) return;
|
if (isProcessingGuess) return;
|
||||||
@@ -176,6 +184,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
if (song.id === dailyPuzzle.songId) {
|
if (song.id === dailyPuzzle.songId) {
|
||||||
addGuess(song.title, true);
|
addGuess(song.title, true);
|
||||||
setHasWon(true);
|
setHasWon(true);
|
||||||
|
// gameState.isSolved will be updated by useGameState
|
||||||
// Track puzzle solved event
|
// Track puzzle solved event
|
||||||
if (typeof window !== 'undefined' && window.plausible) {
|
if (typeof window !== 'undefined' && window.plausible) {
|
||||||
window.plausible('puzzle_solved', {
|
window.plausible('puzzle_solved', {
|
||||||
@@ -196,6 +205,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
if (gameState.guesses.length + 1 >= maxAttempts) {
|
if (gameState.guesses.length + 1 >= maxAttempts) {
|
||||||
setHasLost(true);
|
setHasLost(true);
|
||||||
setHasWon(false);
|
setHasWon(false);
|
||||||
|
// gameState.isFailed will be updated by useGameState
|
||||||
// Track puzzle lost event
|
// Track puzzle lost event
|
||||||
if (typeof window !== 'undefined' && window.plausible) {
|
if (typeof window !== 'undefined' && window.plausible) {
|
||||||
window.plausible('puzzle_solved', {
|
window.plausible('puzzle_solved', {
|
||||||
@@ -236,6 +246,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
if (gameState.guesses.length + 1 >= maxAttempts) {
|
if (gameState.guesses.length + 1 >= maxAttempts) {
|
||||||
setHasLost(true);
|
setHasLost(true);
|
||||||
setHasWon(false);
|
setHasWon(false);
|
||||||
|
// gameState.isFailed will be updated by useGameState
|
||||||
// Track puzzle lost event
|
// Track puzzle lost event
|
||||||
if (typeof window !== 'undefined' && window.plausible) {
|
if (typeof window !== 'undefined' && window.plausible) {
|
||||||
window.plausible('puzzle_solved', {
|
window.plausible('puzzle_solved', {
|
||||||
@@ -260,6 +271,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
giveUp(); // Ensure game is marked as failed and score reset to 0
|
giveUp(); // Ensure game is marked as failed and score reset to 0
|
||||||
setHasLost(true);
|
setHasLost(true);
|
||||||
setHasWon(false);
|
setHasWon(false);
|
||||||
|
// gameState.isFailed will be updated by useGameState
|
||||||
// Track puzzle lost event
|
// Track puzzle lost event
|
||||||
if (typeof window !== 'undefined' && window.plausible) {
|
if (typeof window !== 'undefined' && window.plausible) {
|
||||||
window.plausible('puzzle_solved', {
|
window.plausible('puzzle_solved', {
|
||||||
@@ -409,19 +421,19 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
if (i < gameState.guesses.length) {
|
if (i < gameState.guesses.length) {
|
||||||
if (gameState.guesses[i] === 'SKIPPED') {
|
if (gameState.guesses[i] === 'SKIPPED') {
|
||||||
emojiGrid += '⬛';
|
emojiGrid += '⬛';
|
||||||
} else if (hasWon && i === gameState.guesses.length - 1) {
|
} else if (isSolved && i === gameState.guesses.length - 1) {
|
||||||
emojiGrid += '🟩';
|
emojiGrid += '🟩';
|
||||||
} else {
|
} else {
|
||||||
emojiGrid += '🟥';
|
emojiGrid += '🟥';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If game is lost, fill remaining slots with black squares
|
// If game is lost, fill remaining slots with black squares
|
||||||
emojiGrid += hasLost ? '⬛' : '⬜';
|
emojiGrid += isFailed ? '⬛' : '⬜';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const speaker = hasWon ? '🔉' : '🔇';
|
const speaker = isSolved ? '🔉' : '🔇';
|
||||||
const bonusStar = (hasWon && gameState.yearGuessed && dailyPuzzle.releaseYear && gameState.scoreBreakdown.some(item => item.reason === 'Bonus: Correct Year')) ? '⭐' : '';
|
const bonusStar = (isSolved && gameState.yearGuessed && dailyPuzzle.releaseYear && gameState.scoreBreakdown.some(item => item.reason === 'Bonus: Correct Year')) ? '⭐' : '';
|
||||||
const genreText = genre ? `${isSpecial ? t('special') : t('genre')}: ${genre}\n` : '';
|
const genreText = genre ? `${isSpecial ? t('special') : t('genre')}: ${genre}\n` : '';
|
||||||
|
|
||||||
// Use current domain from window.location to support both hoerdle.de and hördle.de
|
// Use current domain from window.location to support both hoerdle.de and hördle.de
|
||||||
@@ -534,7 +546,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
src={dailyPuzzle.audioUrl}
|
src={dailyPuzzle.audioUrl}
|
||||||
unlockedSeconds={unlockedSeconds}
|
unlockedSeconds={unlockedSeconds}
|
||||||
startTime={dailyPuzzle.startTime}
|
startTime={dailyPuzzle.startTime}
|
||||||
autoPlay={lastAction === 'SKIP' || (lastAction === 'GUESS' && !hasWon && !hasLost)}
|
autoPlay={lastAction === 'SKIP' || (lastAction === 'GUESS' && !isSolved && !isFailed)}
|
||||||
onReplay={addReplay}
|
onReplay={addReplay}
|
||||||
onHasPlayedChange={setHasPlayedAudio}
|
onHasPlayedChange={setHasPlayedAudio}
|
||||||
/>
|
/>
|
||||||
@@ -543,7 +555,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
|
|
||||||
<div className="guess-list">
|
<div className="guess-list">
|
||||||
{gameState.guesses.map((guess, i) => {
|
{gameState.guesses.map((guess, i) => {
|
||||||
const isCorrect = hasWon && i === gameState.guesses.length - 1;
|
const isCorrect = isSolved && i === gameState.guesses.length - 1;
|
||||||
return (
|
return (
|
||||||
<div key={i} className="guess-item">
|
<div key={i} className="guess-item">
|
||||||
<span className="guess-number">#{i + 1}</span>
|
<span className="guess-number">#{i + 1}</span>
|
||||||
@@ -555,7 +567,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!hasWon && !hasLost && (
|
{!isSolved && !isFailed && (
|
||||||
<>
|
<>
|
||||||
<div id="tour-input">
|
<div id="tour-input">
|
||||||
<GuessInput onGuess={handleGuess} disabled={isProcessingGuess} />
|
<GuessInput onGuess={handleGuess} disabled={isProcessingGuess} />
|
||||||
@@ -586,13 +598,13 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(hasWon || hasLost) && (
|
{(isSolved || isFailed) && (
|
||||||
<div className={`message-box ${hasWon ? 'success' : 'failure'}`}>
|
<div className={`message-box ${isSolved ? 'success' : 'failure'}`}>
|
||||||
<h2 style={{ fontSize: '1.5rem', fontWeight: 'bold', marginBottom: '0.5rem' }}>
|
<h2 style={{ fontSize: '1.5rem', fontWeight: 'bold', marginBottom: '0.5rem' }}>
|
||||||
{hasWon ? t('won') : t('lost')}
|
{isSolved ? t('won') : t('lost')}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div style={{ fontSize: '2rem', fontWeight: 'bold', margin: '1rem 0', color: hasWon ? 'var(--success)' : 'var(--danger)' }}>
|
<div style={{ fontSize: '2rem', fontWeight: 'bold', margin: '1rem 0', color: isSolved ? 'var(--success)' : 'var(--danger)' }}>
|
||||||
{t('score')}: {gameState.score}
|
{t('score')}: {gameState.score}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -610,7 +622,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
|
|||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<p>{hasWon ? t('comeBackTomorrow') : t('theSongWas')}</p>
|
<p>{isSolved ? t('comeBackTomorrow') : t('theSongWas')}</p>
|
||||||
|
|
||||||
<div style={{ margin: '1.5rem 0', padding: '1rem', background: 'rgba(255,255,255,0.5)', borderRadius: '0.5rem', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
<div style={{ margin: '1.5rem 0', padding: '1rem', background: 'rgba(255,255,255,0.5)', borderRadius: '0.5rem', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||||||
<img
|
<img
|
||||||
|
|||||||
Reference in New Issue
Block a user