Feature: Skip button becomes Start button on first attempt if audio not played

This commit is contained in:
Hördle Bot
2025-11-25 15:18:25 +01:00
parent 898d2f5959
commit 072158f4ed
2 changed files with 24 additions and 3 deletions

View File

@@ -9,9 +9,10 @@ interface AudioPlayerProps {
onPlay?: () => void; onPlay?: () => void;
onReplay?: () => void; onReplay?: () => void;
autoPlay?: boolean; autoPlay?: boolean;
onHasPlayedChange?: (hasPlayed: boolean) => void;
} }
export default function AudioPlayer({ src, unlockedSeconds, startTime = 0, onPlay, onReplay, autoPlay = false }: AudioPlayerProps) { export default function AudioPlayer({ src, unlockedSeconds, startTime = 0, onPlay, onReplay, autoPlay = false, onHasPlayedChange }: AudioPlayerProps) {
const audioRef = useRef<HTMLAudioElement>(null); const audioRef = useRef<HTMLAudioElement>(null);
const [isPlaying, setIsPlaying] = useState(false); const [isPlaying, setIsPlaying] = useState(false);
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
@@ -24,6 +25,7 @@ export default function AudioPlayer({ src, unlockedSeconds, startTime = 0, onPla
setIsPlaying(false); setIsPlaying(false);
setProgress(0); setProgress(0);
setHasPlayedOnce(false); // Reset for new segment setHasPlayedOnce(false); // Reset for new segment
onHasPlayedChange?.(false); // Notify parent
if (autoPlay) { if (autoPlay) {
const playPromise = audioRef.current.play(); const playPromise = audioRef.current.play();
@@ -33,6 +35,7 @@ export default function AudioPlayer({ src, unlockedSeconds, startTime = 0, onPla
setIsPlaying(true); setIsPlaying(true);
onPlay?.(); onPlay?.();
setHasPlayedOnce(true); setHasPlayedOnce(true);
onHasPlayedChange?.(true); // Notify parent
}) })
.catch(error => { .catch(error => {
console.log("Autoplay prevented:", error); console.log("Autoplay prevented:", error);
@@ -56,6 +59,7 @@ export default function AudioPlayer({ src, unlockedSeconds, startTime = 0, onPla
onReplay?.(); onReplay?.();
} else { } else {
setHasPlayedOnce(true); setHasPlayedOnce(true);
onHasPlayedChange?.(true); // Notify parent
} }
} }
setIsPlaying(!isPlaying); setIsPlaying(!isPlaying);

View File

@@ -37,6 +37,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
const [timeUntilNext, setTimeUntilNext] = useState(''); const [timeUntilNext, setTimeUntilNext] = useState('');
const [hasRated, setHasRated] = useState(false); const [hasRated, setHasRated] = useState(false);
const [showYearModal, setShowYearModal] = useState(false); const [showYearModal, setShowYearModal] = useState(false);
const [hasPlayedAudio, setHasPlayedAudio] = useState(false);
useEffect(() => { useEffect(() => {
const updateCountdown = () => { const updateCountdown = () => {
@@ -116,7 +117,19 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
setTimeout(() => setIsProcessingGuess(false), 500); setTimeout(() => setIsProcessingGuess(false), 500);
}; };
const handleStartAudio = () => {
// This will be called when user clicks "Start" button on first attempt
// We'll trigger the audio player programmatically
setHasPlayedAudio(true);
};
const handleSkip = () => { const handleSkip = () => {
// If user hasn't played audio yet on first attempt, start it instead of skipping
if (gameState.guesses.length === 0 && !hasPlayedAudio) {
handleStartAudio();
return;
}
setLastAction('SKIP'); setLastAction('SKIP');
addGuess("SKIPPED", false); addGuess("SKIPPED", false);
@@ -255,8 +268,9 @@ 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' && !hasWon && !hasLost) || hasPlayedAudio}
onReplay={addReplay} onReplay={addReplay}
onHasPlayedChange={setHasPlayedAudio}
/> />
</div> </div>
@@ -282,7 +296,10 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
onClick={handleSkip} onClick={handleSkip}
className="skip-button" className="skip-button"
> >
Skip (+{unlockSteps[Math.min(gameState.guesses.length + 1, unlockSteps.length - 1)] - unlockedSeconds}s) {gameState.guesses.length === 0 && !hasPlayedAudio
? 'Start'
: `Skip (+${unlockSteps[Math.min(gameState.guesses.length + 1, unlockSteps.length - 1)] - unlockedSeconds}s)`
}
</button> </button>
) : ( ) : (
<button <button