diff options
| author | Yuval Adam <_@yuv.al> | 2025-03-07 13:36:46 +0100 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2025-03-07 13:36:46 +0100 |
| commit | 0a9549db44f3adff71f6cc7249a1bcdb3db5a479 (patch) | |
| tree | c7198365a31e16f0c84ad1328d641f8c80d91d88 /src/pages | |
| parent | a3347ed1c24ef9182171cc461c02ea6bcbac734d (diff) | |
More fixes
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/HomePage.tsx | 139 |
1 files changed, 75 insertions, 64 deletions
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 442d8c4..f0e1732 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -2,11 +2,14 @@ import { useState, useEffect, useRef } from 'react'; import { Link } from 'react-router'; import cw from 'cw'; import '../styles.css'; +import '../components/OptionButtons.css'; import Footer from '../components/Footer'; declare global { interface Window { cw: any; + AudioContext: typeof AudioContext; + webkitAudioContext: typeof AudioContext; } } @@ -20,6 +23,9 @@ const HomePage = () => { const [wpm, setWpm] = useState(20); const [showHints, setShowHints] = useState(false); const [showHowToPlay, setShowHowToPlay] = useState(false); + const [selectedOption, setSelectedOption] = useState<string | null>(null); + const [_correctAnswers, setCorrectAnswers] = useState<string[]>([]); + const [_incorrectAnswers, setIncorrectAnswers] = useState<string[]>([]); const actxRef = useRef<any>(null); const optionButtonsRef = useRef<Array<HTMLButtonElement | null>>([null, null, null, null]); @@ -45,6 +51,7 @@ const HomePage = () => { // Generate a new round const newRound = () => { + setSelectedOption(null); // Reset button states optionButtonsRef.current.forEach(button => { if (button) { @@ -59,18 +66,15 @@ const HomePage = () => { setCurrentChar(newChar); // Generate options (one correct, three random) - let newOptions = [newChar]; - - // Add three random unique characters - while (newOptions.length < 4) { - const randomChar = allChars[Math.floor(Math.random() * allChars.length)]; - if (!newOptions.includes(randomChar)) { - newOptions.push(randomChar); - } - } + const generateOptions = (correctChar: string): string[] => { + const possibleChars = allChars.split(""); + const filteredChars = possibleChars.filter(char => char !== correctChar); + const shuffled = [...filteredChars].sort(() => 0.5 - Math.random()); + const options = [correctChar, ...shuffled.slice(0, 3)]; + return options.sort(() => 0.5 - Math.random()); + }; - // Shuffle options - newOptions = shuffleArray(newOptions); + const newOptions = generateOptions(newChar); setOptions(newOptions); // Play the Morse code for the character @@ -79,18 +83,28 @@ const HomePage = () => { // Play Morse code for a character const playMorseCode = (char: string) => { - if (actxRef.current) { + if (!char) return; + + try { + if (!actxRef.current) { + actxRef.current = cw.initAudioContext({ tone: 600 }); + } + cw.play(char, { wpm: wpm, actx: actxRef.current }); + } catch (error) { + console.error('Error playing Morse code:', error); } }; // Check if the answer is correct const checkAnswer = (selectedChar: string) => { - if (selectedChar === currentChar) { - // Correct answer + setSelectedOption(selectedChar); + const isCorrect = selectedChar === currentChar; + + if (isCorrect) { setScore(prevScore => prevScore + 1); // Add to score tracker @@ -100,24 +114,7 @@ const HomePage = () => { marker.className = 'score-marker correct'; scoreTracker.appendChild(marker); } - - // Disable all buttons - optionButtonsRef.current.forEach(button => { - if (button) button.disabled = true; - }); - - // Highlight the correct button - const correctButtonIndex = options.indexOf(currentChar); - if (correctButtonIndex !== -1 && optionButtonsRef.current[correctButtonIndex]) { - const button = optionButtonsRef.current[correctButtonIndex]; - if (button) button.classList.add('correct'); - } - - // Move to next round after delay - setTimeout(newRound, 1500); } else { - // Incorrect answer - // Add to score tracker const scoreTracker = document.getElementById('scoreTracker'); if (scoreTracker) { @@ -126,29 +123,25 @@ const HomePage = () => { scoreTracker.appendChild(marker); } - // Disable all buttons - optionButtonsRef.current.forEach(button => { - if (button) button.disabled = true; - }); - - // Highlight the incorrect button and show the correct one - const selectedButtonIndex = options.indexOf(selectedChar); - if (selectedButtonIndex !== -1 && optionButtonsRef.current[selectedButtonIndex]) { - const button = optionButtonsRef.current[selectedButtonIndex]; - if (button) button.classList.add('incorrect'); - } - - const correctButtonIndex = options.indexOf(currentChar); - if (correctButtonIndex !== -1 && optionButtonsRef.current[correctButtonIndex]) { - const button = optionButtonsRef.current[correctButtonIndex]; - if (button) button.classList.add('correct'); + // Highlight the correct answer + const correctIndex = options.findIndex(option => option === currentChar); + if (correctIndex !== -1) { + const correctButton = optionButtonsRef.current[correctIndex]; + if (correctButton) { + // Add a small delay before showing the correct answer + setTimeout(() => { + correctButton.classList.add('correct'); + }, 300); + } } - - // Move to next round after delay - setTimeout(newRound, 2000); } setTotalPlayed(prevTotal => prevTotal + 1); + + // Proceed to next round after a delay + setTimeout(() => { + newRound(); + }, 1500); // Increased delay to give time to see the correct answer }; // Handle keyboard input @@ -166,7 +159,7 @@ const HomePage = () => { button.classList.add('key-pressed'); setTimeout(() => { button.classList.remove('key-pressed'); - checkAnswer(key); + handleOptionClick(key, index); }, 100); } } @@ -178,16 +171,6 @@ const HomePage = () => { }; }, [gameStarted, options]); - // Utility function to shuffle an array - const shuffleArray = (array: string[]) => { - const newArray = [...array]; - for (let i = newArray.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; - } - return newArray; - }; - // Get Morse code representation for a character const getMorseCode = (char: string) => { const morseMap: { [key: string]: string } = { @@ -211,6 +194,8 @@ const HomePage = () => { setTotalPlayed(0); setCurrentChar(''); setOptions([]); + setCorrectAnswers([]); + setIncorrectAnswers([]); // Clear score tracker const scoreTracker = document.getElementById('scoreTracker'); @@ -229,6 +214,27 @@ const HomePage = () => { } }; + // Handle option button click + const handleOptionClick = (option: string, index: number) => { + const button = optionButtonsRef.current[index]; + if (button) { + // Disable all buttons to prevent multiple selections + optionButtonsRef.current.forEach(btn => { + if (btn) btn.disabled = true; + }); + + // Add appropriate class based on correctness + if (option === currentChar) { + button.classList.add('correct'); + } else { + button.classList.add('incorrect'); + } + + // Check the answer + checkAnswer(option); + } + }; + return ( <div className="container"> <h1 onClick={resetGame} className="title-link">Morse Hero</h1> @@ -319,11 +325,17 @@ const HomePage = () => { {options.map((option, index) => ( <button key={index} - className="option-button" + className={`option-button ${selectedOption === option + ? option === currentChar + ? "correct" + : "incorrect" + : "" + }`} ref={el => { optionButtonsRef.current[index] = el; }} - onClick={() => checkAnswer(option)} + onClick={() => handleOptionClick(option, index)} + disabled={selectedOption !== null} > <span className="char-display">{option}</span> {showHints && <span className="morse-hint">{getMorseCode(option)}</span>} @@ -356,7 +368,6 @@ const HomePage = () => { /> <label htmlFor="hintMode">Show Hints</label> </div> - <button className="reset-button" onClick={resetGame}>New Game</button> </div> <div className="keyboard-tip"> |
