diff --git a/src/App.js b/src/App.js index dfa7fd7..2cfba9f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,76 +1,69 @@ -import React, {useContext, useState} from 'react'; +import React, {useContext} from 'react'; import './css/App.css'; -import MorseButtons from './components/MorseButtons' + +import { GameModeContext } from "./contexts/gameModeContext" +import { KeyTypeContext } from "./contexts/keyTypeContext" +import { MorseBufferContextProvider } from "./contexts/morseBufferContext" +import { WordFeederContextProvider } from './contexts/wordFeederContext'; +import { WordListPickerContextProvider } from './contexts/wordListPickerContext'; + import ModePicker from './components/ModePicker' import KeyTypePicker from './components/KeyTypePicker' -// import MorseDisplay from './components/MorseDisplay' -// import MorseBufferDisplay from './components/MorseBufferDisplay' +import WordListPicker from './components/WordListPicker'; + +import Legend from './components/Legend'; // import GameClock from "./components/GameClock" -// import ChallengeWord from "./components/ChallengeWord" -import {GameModeContext} from "./contexts/gameContext" -import {KeyTypeContext} from "./contexts/keyTypeContext" -import {MorseBufferContextProvider} from "./contexts/morseBufferContext" +import MorseButtons from './components/MorseButtons' + import PracticeMode from './app-modes/PracticeMode'; import TimedMode from './app-modes/TimedMode' import ChallengeMode from './app-modes/ChallengeMode' -import Legend from './components/Legend'; import MorseBufferDisplay from './components/MorseBufferDisplay' import MorseHistory from './components/MorseHistory' + import StraightKey from './components/StraightKey'; import ElectronicKey from './components/ElectronicKey'; -function App() { +export default React.memo(function App() { console.log('App.js rendered') const {gameMode} = useContext(GameModeContext) const {keyType} = useContext(KeyTypeContext) - // const [keyType, setKeyType] = useState('straight') - - // function handleClick(e) { - // setKeyType(e.target.id) - // console.log("Switched to " + e.target.id + " keyType."); - // } - - let wordList = ['morse', 'code', 'hello', 'gene'] - let wordIndex = 0 - function getNextWord() { - let word = wordList[wordIndex] - wordIndex += 1 - return word - } - return (
- - - {gameMode === 'practice' && - <> - {keyType === "straight" ? - : } -
-
-
- - } - {/* {gameMode === 'timed' && } */} - {gameMode === 'challenge' && - <> - {keyType === "straight" ? - : } - - - } - + + + {gameMode === 'practice' && + <> + {keyType === "straight" ? + : } +
+
+
+ + } + {/* {gameMode === 'timed' && } */} + {gameMode === 'challenge' && + <> + + + + {keyType === "straight" ? + : } + + + + + } +
); -} - -export default React.memo(App); +}) \ No newline at end of file diff --git a/src/app-modes/ChallengeMode.js b/src/app-modes/ChallengeMode.js index 6d7502a..28db298 100644 --- a/src/app-modes/ChallengeMode.js +++ b/src/app-modes/ChallengeMode.js @@ -4,19 +4,17 @@ import morseCode from '../data/morse-reverse.json' import ChallengeWord from '../components/ChallengeWord' import ChallengeBufferDisplay from '../components/ChallengeBufferDisplay'; import { MorseBufferContext } from '../contexts/morseBufferContext'; +import { WordFeederContext } from '../contexts/wordFeederContext'; +import { WordListPickerContext } from '../contexts/wordListPickerContext'; export default React.memo(function ChallengeMode(props) { console.log("ChallengeMode loaded"); - - let wordList = ['morse', 'code', 'hello', 'gene'] - // let word = wordList.shift() - // let word = props.word - let getNextWord = props.getNextWord - let word = getNextWord() - let challengeLetters = word.split('') + const {word, getNextWord} = useContext(WordFeederContext) + + let challengeWordClass = '' const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext) let morseArray = morseCharBuffer.split('_').filter(l => l !== '') @@ -24,14 +22,22 @@ export default React.memo(function ChallengeMode(props) { let correctCharIndexes = [] // Indexes of correct letters in Challenge Word let incorrectCharIndex = null let incorrectMorseIndexes = [] // Indexes of incorrect morse characters in morse character buffer - + let offset = 0 + + if (!word) { + console.log('FINISHED ALL WORDS!') + alert('No more words.') + return + } + let challengeLetters = word.split('') // Iterate through the morse character buffer and compare with each letter of challenge word morseArray.forEach((item, index) => { - // if (morseCharBuffer.slice(-1) === '_') { // If end of morse character - let morseLetter = morseCode[morseArray[index]] + if (morseCharBuffer.slice(-1) === '_') { // If end of morse character + + let morseLetter = morseCode[morseArray[index]] || '[?]' let challengeLetter = challengeLetters[index-offset] if (morseLetter === challengeLetter) { @@ -41,25 +47,44 @@ export default React.memo(function ChallengeMode(props) { else { incorrectCharIndex = index-offset incorrectMorseIndexes.push(index) + if (incorrectMorseIndexes.length > 0) { + setMorseCharBuffer(prev => { + let newState = prev.split('_').filter(l => l !== '') + let x = newState.splice(incorrectMorseIndexes[0], 1) + newState = newState.join('_') + '_' + + return newState + }) + incorrectMorseIndexes.splice(1,incorrectMorseIndexes.length) + } offset = incorrectMorseIndexes.length } - // } + } }) - console.log('morseArray', morseArray); + + function timeout(delay) { + new Promise((resolve) => { + setTimeout(() => { + resolve() + }, delay) + }) + } // Next word once all correct if (correctCharIndexes.length === challengeLetters.length) { - word = wordList.shift() - - setMorseCharBuffer('') + // + challengeWordClass = 'correct' + setTimeout(() => { + getNextWord() + setMorseCharBuffer('') + }, 1000) } - return ( <> - + {/* */} - ); + ) }); diff --git a/src/components/ChallengeBufferDisplay.js b/src/components/ChallengeBufferDisplay.js index a4f786c..2715c99 100644 --- a/src/components/ChallengeBufferDisplay.js +++ b/src/components/ChallengeBufferDisplay.js @@ -1,52 +1,27 @@ -import React, { useContext } from "react" -import DitDahDisplay from "./DitDahDisplay" +import React from "react" import morseCode from '../data/morse-reverse.json' -// import { MorseBufferContext } from "../contexts/morseBufferContext" -function ChallengeBufferDisplay(props) { - - // // INCREMENTING COUNTER TO MONITOR COMPONENT RELOADING - // // console.log('ChallengeMode') - // if (!document.getElementById('counter')) { - // let counter = document.createElement('h1') - // let holder = document.createElement('h3') - // counter.id = 'counter' - // holder.id = 'holder' - // counter.innerText = "0" - // document.querySelector('#main-content').appendChild(counter) - // document.querySelector('#main-content').appendChild(holder) - // } else { - // let num = document.getElementById('counter').innerText - // document.getElementById('counter').innerText = Number(num) + 1 - // document.getElementById('holder').innerText = buffer - // } - // const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext) +export default React.memo(function ChallengeBufferDisplay(props) { const morseArray = props.morseArray let incorrectMorseIndexes = props.incorrectMorseIndexes - console.log('morseArray', morseArray); let ditDahs = [] let alphanumeric = [] - for (let i in morseArray) { let morseChar = morseArray[i] // Alphanumeric + let alpha = morseCode[morseChar] || '[?]' let alphaClass = (incorrectMorseIndexes.includes(Number(i))) ? 'strike morseError' : '' - alphanumeric.push({morseCode[morseChar].toUpperCase()}) + alphanumeric.push({alpha.toUpperCase()}) // DitDahs let ditDahClass = (incorrectMorseIndexes.includes(Number(i))) ? 'morseError' : '' - ditDahs.push({morseChar}) - ditDahs.push( ) + ditDahs.push({morseChar}) + ditDahs.push( ) } - // if (incorrectIndex) { - // setTimeout(() => { - // setMorseCharBuffer(prev => prev.slice(0,prev.length-2)) - // }, 500) - // } return (
@@ -60,6 +35,4 @@ function ChallengeBufferDisplay(props) {
) -} - -export default React.memo(ChallengeBufferDisplay) \ No newline at end of file +}) \ No newline at end of file diff --git a/src/components/ChallengeWord.js b/src/components/ChallengeWord.js index d4d9e07..3e633b0 100644 --- a/src/components/ChallengeWord.js +++ b/src/components/ChallengeWord.js @@ -2,6 +2,7 @@ import React from "react" export default React.memo(function ChallengeWord(props) { + let challengeWordClass= props.className const word = props.word const correctCharIndexes = props.correctCharIndexes const incorrectCharIndex = props.incorrectCharIndex @@ -24,6 +25,6 @@ export default React.memo(function ChallengeWord(props) { }) return ( -
{spannedWord}
+
{spannedWord}
) }) \ No newline at end of file diff --git a/src/components/ModePicker.js b/src/components/ModePicker.js index 89cca8c..e49c880 100644 --- a/src/components/ModePicker.js +++ b/src/components/ModePicker.js @@ -1,11 +1,14 @@ import React, {useContext} from "react" -import {GameModeContext} from "../contexts/gameContext" +import {GameModeContext} from "../contexts/gameModeContext" +import { MorseBufferContext } from "../contexts/morseBufferContext" function ModePicker() { const {setGameMode} = useContext(GameModeContext) + const {setMorseCharBuffer} = useContext(MorseBufferContext) function handleClick(e) { + setMorseCharBuffer('') setGameMode(e.target.id) console.log("Switched to " + e.target.id + " mode."); } diff --git a/src/components/WordListPicker.js b/src/components/WordListPicker.js new file mode 100644 index 0000000..3d4487d --- /dev/null +++ b/src/components/WordListPicker.js @@ -0,0 +1,29 @@ +import React, {useContext} from "react" +import { WordListPickerContext } from "../contexts/wordListPickerContext"; +import { WordFeederContext } from "../contexts/wordFeederContext"; + +export default React.memo(function WordListPicker() { + + const {setWordListCategory} = useContext(WordListPickerContext) + const {resetFeeder} = useContext(WordFeederContext) + + function handleClick(e) { + resetFeeder() + setWordListCategory(e.target.id) + console.log("Switched to " + e.target.id + " mode."); + } + + return ( +
+ + + +
+ ) +}) \ No newline at end of file diff --git a/src/contexts/gameContext.js b/src/contexts/gameModeContext.js similarity index 100% rename from src/contexts/gameContext.js rename to src/contexts/gameModeContext.js diff --git a/src/contexts/wordFeederContext.js b/src/contexts/wordFeederContext.js new file mode 100644 index 0000000..6f2e8a5 --- /dev/null +++ b/src/contexts/wordFeederContext.js @@ -0,0 +1,46 @@ +import React, {useState, useContext} from "react" +import { WordListPickerContext } from "./wordListPickerContext" +const WordFeederContext = React.createContext() + +function WordFeederContextProvider(props) { + + // let wordList = ['hi', 'morse', 'code', 'hello', 'gene'] + const {wordList} = useContext(WordListPickerContext) + + const [wordIndex, setWordIndex] = useState(0) + const [order, setOrder] = useState('sequential') + let indexCache = [] + + let word = wordList[wordIndex] + + function resetFeeder() { + setWordIndex(0) + indexCache = [] + } + + function getNextWord() { + if (order === 'sequential') { + setWordIndex(prev => prev + 1) + word = wordList[wordIndex] || null + } else if (order === 'random') { + let index = Math.floor(Math.random*wordList.length) + indexCache.push(index) + // Need to account for what to do when all words in wordList have been exhausted + while (indexCache.includes(index) && wordList.length !== indexCache.length) { + index = Math.floor(Math.random*wordList.length) + indexCache.push(index) + } + setWordIndex(index) + + word = wordList[wordIndex] + } + } + + return ( + + {props.children} + + ) +} + +export {WordFeederContextProvider, WordFeederContext} diff --git a/src/contexts/wordListPickerContext.js b/src/contexts/wordListPickerContext.js new file mode 100644 index 0000000..3a90410 --- /dev/null +++ b/src/contexts/wordListPickerContext.js @@ -0,0 +1,30 @@ +import React, {useState} from "react" +import alphabet from '../data/alphabet.json' +import common100 from '../data/common100.json' + + +const WordListPickerContext = React.createContext() + +function WordListPickerContextProvider(props) { + + const [wordListCategory, setWordListCategory] = useState('alphabet') + let wordList = [] + const testList = ['gene', 'anya', 'ali', 'liam', 'last'] + wordList = testList + + if (wordListCategory === 'alphabet') { + wordList = alphabet.words + } else if (wordListCategory === 'common100') { + wordList = common100.words + } else if (wordListCategory === 'test') { + wordList = testList + } + + return ( + + {props.children} + + ) +} + +export {WordListPickerContextProvider, WordListPickerContext} diff --git a/src/css/App.css b/src/css/App.css index 48d698f..8336dd9 100644 --- a/src/css/App.css +++ b/src/css/App.css @@ -5,7 +5,7 @@ html, body { width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; - background: #FFF; + background: #444; } #root { @@ -159,6 +159,7 @@ html, body { margin-bottom: 20px; padding-left: 10px; padding-right: 10px; + border-radius: 5px; width: -webkit-fit-content; width: -moz-fit-content; width: fit-content; @@ -170,17 +171,24 @@ html, body { text-transform: uppercase; -ms-flex-item-align: center; align-self: center; + -webkit-transition: all 300ms ease-in-out; + transition: all 300ms ease-in-out; } #challengeWord span { padding: 4px; margin: 1px; - -webkit-transition: background 100ms ease-in-out; - transition: background 100ms ease-in-out; + -webkit-transition: background 300ms ease-in-out; + transition: background 300ms ease-in-out; +} + +#challengeWord.correct { + background: rgba(0, 200, 0, 0.7); } .strike { text-decoration: line-through; + opacity: 30%; } #morseBufferDisplay, #challengeBufferDisplay { @@ -228,8 +236,8 @@ html, body { #morseBufferDisplay #alphanumeric-container #alphanumeric span, #challengeBufferDisplay #alphanumeric-container #alphanumeric span { padding: 4px; - -webkit-transition: background 100ms ease-in-out; - transition: background 100ms ease-in-out; + -webkit-transition: background 300ms ease-in-out; + transition: background 300ms ease-in-out; } #morseBufferDisplay #ditDahs, #challengeBufferDisplay #ditDahs { diff --git a/src/css/App.css.map b/src/css/App.css.map index 9ccfa09..d855eb6 100644 --- a/src/css/App.css.map +++ b/src/css/App.css.map @@ -1,6 +1,6 @@ { "version": 3, - "mappings": "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", + "mappings": "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", "sources": [ "../scss/App.scss" ], diff --git a/src/data/alphabet.json b/src/data/alphabet.json new file mode 100644 index 0000000..2ccaa73 --- /dev/null +++ b/src/data/alphabet.json @@ -0,0 +1,28 @@ +{ "words": [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "x", + "y", + "z" + ] +} \ No newline at end of file diff --git a/src/data/common100.json b/src/data/common100.json new file mode 100644 index 0000000..0b511a8 --- /dev/null +++ b/src/data/common100.json @@ -0,0 +1,103 @@ +{ "words": [ + "the", + "be", + "to", + "of", + "and", + "a", + "in", + "that", + "have", + "I", + "it", + "for", + "not", + "on", + "with", + "he", + "as", + "you", + "do", + "at", + "this", + "but", + "his", + "by", + "from", + "they", + "we", + "say", + "her", + "she", + "or", + "an", + "will", + "my", + "one", + "all", + "would", + "there", + "their", + "what", + "so", + "up", + "out", + "if", + "about", + "who", + "get", + "which", + "go", + "me", + "when", + "make", + "can", + "like", + "time", + "no", + "just", + "him", + "know", + "take", + "person", + "into", + "year", + "your", + "good", + "some", + "could", + "them", + "see", + "other", + "than", + "then", + "now", + "look", + "only", + "come", + "its", + "over", + "think", + "also", + "back", + "after", + "use", + "two", + "how", + "our", + "work", + "first", + "well", + "way", + "even", + "new", + "want", + "because", + "any", + "these", + "give", + "day", + "most", + "us" + ] +} \ No newline at end of file diff --git a/src/hooks/useElectronicKey.js b/src/hooks/useElectronicKey.js index 0e0c5e0..6a956dc 100644 --- a/src/hooks/useElectronicKey.js +++ b/src/hooks/useElectronicKey.js @@ -135,12 +135,19 @@ function useElectronicKey(gameMode) { gapTimer = setInterval(() => { gapTime += 1 - if (gapTime >= wordGapMaxTime) { + // if (gapTime >= wordGapMaxTime) { + if (gameMode === 'practice' && gapTime >= wordGapMaxTime) { setMorseCharBuffer(prev => prev + '/') clearInterval(gapTimer) gapTimer = 0 gapTime = 0 } + else if (gameMode === 'challenge' && gapTime >= letterGapMinTime) { + setMorseCharBuffer(prev => prev + '_') + clearInterval(gapTimer) + gapTimer = 0 + gapTime = 0 + } }, timingUnit) resolve(); @@ -218,10 +225,10 @@ function useElectronicKey(gameMode) { function handleInputStart(event) { event.preventDefault() - if (event.keyCode === 71) { - queue = ['.',' ','.',' ','.',' ','.',' ','-','.','.','.','.','-'] - executeQueue() - } + // if (event.keyCode === 71) { + // queue = ['.',' ','.',' ','.',' ','.',' ','-','.','.','.','.','-'] + // executeQueue() + // } paddlesReleasedSimultaneously = false @@ -292,14 +299,15 @@ function useElectronicKey(gameMode) { depressSyncTime = 0 } function checkGapBetweenInputs() { - console.log('ditMaxTime', ditMaxTime) - console.log('gapTime', gapTime); - console.log('letterGapMinTime', letterGapMinTime); - console.log('wordGapMaxTime', wordGapMaxTime); // Check Gap between letters if (gapTime >= letterGapMinTime && gapTime < wordGapMaxTime) { + // setMorseCharBuffer(prev => prev + ' ') + if (gameMode === 'practice') { setMorseCharBuffer(prev => prev + ' ') - gapTime = 0 + } else if (gameMode === 'challenge') { + setMorseCharBuffer(prev => prev + '_') + } + gapTime = 0 clearInterval(gapTimer) gapTimer = 0 } @@ -336,7 +344,8 @@ function useElectronicKey(gameMode) { useEffect(() => { // PRACTICE MODE - if (morseCharBuffer.slice(-1) === '/') { + // if (morseCharBuffer.slice(-1) === '/') { + if (morseCharBuffer.slice(-1) === '/' && gameMode === 'practice') { // Remove forward slash let val = morseCharBuffer.slice(0,morseCharBuffer.length-1) diff --git a/src/hooks/useStraightKey.js b/src/hooks/useStraightKey.js index 26fd27f..88e748f 100644 --- a/src/hooks/useStraightKey.js +++ b/src/hooks/useStraightKey.js @@ -1,14 +1,11 @@ import {useEffect, useContext} from 'react' import {MorseBufferContext} from '../contexts/morseBufferContext' import config from '../config.json' -// import {GameModeContext} from '../contexts/gameContext' // STRAIGHT KEY TELEGRAPH - function useStraightKey(gameMode) { const {morseCharBuffer, setMorseCharBuffer, morseWords, setMorseWords} = useContext(MorseBufferContext) - // const {gameMode} = useContext(GameModeContext) let charTimer = 0 let charTime = 0 @@ -44,22 +41,19 @@ function useStraightKey(gameMode) { function handleInputStart(event) { event.preventDefault() - console.log("down", event.keyCode); if (isRunning) { return } else { - isRunning = true - - // TODO: - // Make sure only one touchdown event registered at a time if ((event.keyCode !== 32 && event.target.id !== "morseButton" && - event.target.id !== "left" && - event.target.id !== "right") || - (event.repeat)) { - return - } + event.target.className !== "paddle") || + (event.repeat)) { + return + } + + isRunning = true + if (context.state === 'interrupted') { context.resume() } @@ -73,7 +67,7 @@ function useStraightKey(gameMode) { o.connect(g) g.connect(context.destination) o.start() - + checkGapBetweenInputs() clearInterval(gapTimer) @@ -91,17 +85,16 @@ function useStraightKey(gameMode) { function handleInputEnd(event) { event.preventDefault() - console.log("up", event.keyCode); if (isRunning) { if ((event.keyCode !== 32 && event.target.id !== "morseButton" && - event.target.id !== "left" && - event.target.id !== "right") || + event.target.className !== "paddle") || (event.repeat)) { return } isRunning = false + // console.log('charTime:', charTime); if (charTime <= ditMaxTime) { @@ -131,7 +124,6 @@ function useStraightKey(gameMode) { gapTimer = setInterval(() => { gapTime += 1 - console.log('useStraightKey-gameMode:',gameMode); // Gap between words if (gameMode === 'practice' && gapTime >= wordGapMaxTime) { setMorseCharBuffer(prev => prev + '/') @@ -139,7 +131,7 @@ function useStraightKey(gameMode) { gapTimer = 0 gapTime = 0 } - if (gameMode === 'challenge' && gapTime >= letterGapMinTime) { + else if (gameMode === 'challenge' && gapTime >= letterGapMinTime) { setMorseCharBuffer(prev => prev + '_') clearInterval(gapTimer) gapTimer = 0 @@ -150,10 +142,6 @@ function useStraightKey(gameMode) { function checkGapBetweenInputs() { // Check Gap between letters - // console.log('ditMaxTime', ditMaxTime) - // console.log('gapTime', gapTime); - // console.log('letterGapMinTime', letterGapMinTime); - // console.log('wordGapMaxTime', wordGapMaxTime); if (gapTime >= letterGapMinTime && gapTime < wordGapMaxTime) { if (gameMode === 'practice') { setMorseCharBuffer(prev => prev + ' ') @@ -164,7 +152,7 @@ function useStraightKey(gameMode) { gapTimer = 0 } } - + useEffect(() => { document.addEventListener('keydown', handleInputStart) document.addEventListener('keyup', handleInputEnd) diff --git a/src/index.js b/src/index.js index e7c9eea..a1b10c9 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; -import {GameModeContextProvider} from "./contexts/gameContext" +import {GameModeContextProvider} from "./contexts/gameModeContext" import { KeyTypeContextProvider } from './contexts/keyTypeContext'; diff --git a/src/scss/App.scss b/src/scss/App.scss index a2fb0a4..97e6df8 100644 --- a/src/scss/App.scss +++ b/src/scss/App.scss @@ -10,8 +10,8 @@ html, body { height: 100%; width: 100%; box-sizing: border-box; - background: $main-bg-color; - // background: #444 + // background: $main-bg-color; + background: #444; } #root { height: 100%; @@ -117,6 +117,7 @@ html, body { margin-bottom: 20px; padding-left: 10px; padding-right: 10px; + border-radius: 5px; width: fit-content; display: flex; font-size: 40px; @@ -125,15 +126,25 @@ html, body { background: #EEE; text-transform: uppercase; align-self: center; + transition: all 300ms ease-in-out; + span { padding: 4px; margin: 1px; - transition: background 100ms ease-in-out; + transition: background 300ms ease-in-out; //, opacity 100ms ease-in-out; + } + &.correct { + background: rgba(0,200,0,0.7); } } +// #challengeWord.green { +// background: green; +// } + .strike { text-decoration: line-through; + opacity: 30%; } #morseBufferDisplay, #challengeBufferDisplay { @@ -168,7 +179,7 @@ html, body { span { padding: 4px; - transition: background 100ms ease-in-out; + transition: background 300ms ease-in-out; } } }