mirror of
https://github.com/genemecija/learn-morse-code.git
synced 2026-01-15 21:10:06 +01:00
Challenge Overlay, working on wordlist finish bug
This commit is contained in:
parent
e63271a386
commit
c4f66724f8
14
src/App.js
14
src/App.js
|
|
@ -2,7 +2,6 @@ import React, {useContext} from 'react';
|
|||
import './css/App.css';
|
||||
|
||||
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';
|
||||
|
|
@ -21,15 +20,14 @@ import Legend from './components/Legend';
|
|||
import WordsPerMinute from "./components/WordsPerMinute"
|
||||
import MorseButtons from './components/MorseButtons'
|
||||
import Footer from './components/Footer';
|
||||
import StraightKey from './components/StraightKey';
|
||||
import ElectronicKey from './components/ElectronicKey';
|
||||
import Info from './components/Info';
|
||||
import { GameClockContextProvider } from './contexts/gameClockContext';
|
||||
import ChallengeOverlay from './components/ChallengeOverlay';
|
||||
|
||||
export default React.memo(function App() {
|
||||
|
||||
console.log('App.js rendered')
|
||||
|
||||
const {keyType} = useContext(KeyTypeContext)
|
||||
const {gameMode} = useContext(GameModeContext)
|
||||
|
||||
return (
|
||||
|
|
@ -43,9 +41,6 @@ export default React.memo(function App() {
|
|||
<Info />
|
||||
</div>
|
||||
<div id="main-interface">
|
||||
{keyType === "straight" ?
|
||||
<StraightKey /> : <ElectronicKey />
|
||||
}
|
||||
|
||||
{gameMode === 'practice' &&
|
||||
<PracticeMode />
|
||||
|
|
@ -62,7 +57,10 @@ export default React.memo(function App() {
|
|||
} */}
|
||||
|
||||
{gameMode === 'challenge' &&
|
||||
<ChallengeMode />
|
||||
<GameClockContextProvider>
|
||||
<ChallengeOverlay />
|
||||
<ChallengeMode />
|
||||
</GameClockContextProvider>
|
||||
}
|
||||
|
||||
<MorseButtons />
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useContext, useEffect} from 'react';
|
||||
import React, {useContext, useEffect, useState} from 'react';
|
||||
import '../css/App.css';
|
||||
import morseCode from '../data/morse-reverse.json'
|
||||
import ChallengeWord from '../components/ChallengeWord'
|
||||
|
|
@ -6,16 +6,24 @@ import ChallengeBufferDisplay from '../components/ChallengeBufferDisplay';
|
|||
import { MorseBufferContext } from '../contexts/morseBufferContext';
|
||||
import { WordFeederContext } from '../contexts/wordFeederContext';
|
||||
import { WordListPickerContext } from '../contexts/wordListPickerContext';
|
||||
import GameClock from '../components/GameClock';
|
||||
import { GameClockContext } from '../contexts/gameClockContext';
|
||||
import { KeyTypeContext } from '../contexts/keyTypeContext';
|
||||
import StraightKey from '../components/StraightKey';
|
||||
import ElectronicKey from '../components/ElectronicKey';
|
||||
|
||||
|
||||
export default React.memo(function ChallengeMode(props) {
|
||||
|
||||
const {startGameClock, stopGameClock, gameClockTime, cleanup} = useContext(GameClockContext)
|
||||
const {word, getNextWord} = useContext(WordFeederContext)
|
||||
|
||||
const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext)
|
||||
const {keyType} = useContext(KeyTypeContext)
|
||||
|
||||
const [challengeStarted, setChallengeStarted] = useState(false)
|
||||
let morseArray = morseCharBuffer.split('_').filter(l => l !== '')
|
||||
let challengeWordClass = ''
|
||||
|
||||
const {morseCharBuffer, setMorseCharBuffer} = useContext(MorseBufferContext)
|
||||
let morseArray = morseCharBuffer.split('_').filter(l => l !== '')
|
||||
|
||||
let correctCharIndexes = [] // Indexes of correct letters in Challenge Word
|
||||
// let incorrectCharIndex = null
|
||||
|
|
@ -26,18 +34,21 @@ export default React.memo(function ChallengeMode(props) {
|
|||
|
||||
if (!word) {
|
||||
console.log('FINISHED ALL WORDS!')
|
||||
alert('Show completion time.')
|
||||
stopGameClock()
|
||||
cleanup()
|
||||
|
||||
//BREAKS HERE AFTER WORDLIST IS COMPLETED
|
||||
alert(`Time: ${document.getElementById('gameClock').innerText}`)
|
||||
return
|
||||
}
|
||||
if (!challengeStarted) {
|
||||
// SHOW "CLICK HERE TO START" OVERLAY
|
||||
}
|
||||
|
||||
|
||||
|
||||
let challengeLetters = word.split('')
|
||||
|
||||
// console.log('word', word);
|
||||
// console.log('morseArray', morseArray);
|
||||
// console.log('morseArray.length', morseArray.length);
|
||||
// if (morseArray.length === 0) {
|
||||
// document.getElementById('challengeWord').childNodes.forEach(node => node.classList = ('cLetter'))
|
||||
// }
|
||||
|
||||
|
||||
// Iterate through the morse character buffer and compare with each letter of challenge word
|
||||
morseArray.forEach((item, index) => {
|
||||
|
|
@ -100,9 +111,13 @@ export default React.memo(function ChallengeMode(props) {
|
|||
|
||||
return (
|
||||
<>
|
||||
{keyType === "straight" ?
|
||||
<StraightKey /> : <ElectronicKey />
|
||||
}
|
||||
<GameClock />
|
||||
<ChallengeWord className={challengeWordClass} word={word} />
|
||||
<ChallengeBufferDisplay morseArray={morseArray} incorrectMorseIndexes={incorrectMorseIndexes} />
|
||||
{/* <button onClick={() => console.log(morseCharBuffer)}>morseCharBuffer</button> */}
|
||||
<button onClick={startGameClock}>start clock</button>
|
||||
</>
|
||||
)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import '../css/App.css';
|
||||
import MorseBufferDisplay from '../components/MorseBufferDisplay'
|
||||
import MorseHistoryTextBox from '../components/MorseHistory_textbox'
|
||||
import MorseHistory from '../components/MorseHistory'
|
||||
import { KeyTypeContext } from '../contexts/keyTypeContext';
|
||||
import StraightKey from '../components/StraightKey';
|
||||
import ElectronicKey from '../components/ElectronicKey';
|
||||
|
||||
|
||||
export default (function PracticeMode(props) {
|
||||
|
||||
const {keyType} = useContext(KeyTypeContext)
|
||||
|
||||
return (
|
||||
<>
|
||||
{keyType === "straight" ?
|
||||
<StraightKey /> : <ElectronicKey />
|
||||
}
|
||||
<MorseBufferDisplay /><br/>
|
||||
<MorseHistoryTextBox />
|
||||
</>
|
||||
|
|
|
|||
29
src/components/ChallengeOverlay.js
Normal file
29
src/components/ChallengeOverlay.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import React, { useContext } from "react"
|
||||
import { GameClockContext } from "../contexts/gameClockContext"
|
||||
|
||||
|
||||
export default (function ChallengeOverlay() {
|
||||
|
||||
const {startGameClock} = useContext(GameClockContext)
|
||||
|
||||
function startChallenge(e) {
|
||||
let countdown
|
||||
let count = 3
|
||||
document.getElementById('challengeReady').innerText = `Challenge starting in ${count}`
|
||||
countdown = setInterval(() => {
|
||||
count--
|
||||
document.getElementById('challengeReady').innerText = `Challenge starting in ${count}`
|
||||
if (count === 0) {
|
||||
// Do this when countdown hits 0
|
||||
clearInterval(countdown)
|
||||
startGameClock()
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="challenge-overlay">
|
||||
<div id="challengeReady" className="notify" onClick={startChallenge}>Click to Start Challenge!</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
@ -1,14 +1,35 @@
|
|||
import React, {useState} from "react"
|
||||
import React, {useState, useContext, useEffect} from "react"
|
||||
import { GameClockContext } from "../contexts/gameClockContext";
|
||||
|
||||
function GameClock(props) {
|
||||
console.log('GameClock rendered');
|
||||
|
||||
// console.log('props.gameClockTime', props.gameClockTime);
|
||||
// const [clockTime, setClockTime] = useState(30)
|
||||
|
||||
// setClockTime(props.time)
|
||||
|
||||
|
||||
// let gameClock
|
||||
// let clockRunning = false
|
||||
// function startClock() {
|
||||
// if (!clockRunning) {
|
||||
// clockRunning = true
|
||||
// gameClock = setInterval(() => {
|
||||
// document.getElementById('gameClock').innerText = Number(document.getElementById('gameClock').innerText) + 1
|
||||
// }, 1000)
|
||||
// }
|
||||
// }
|
||||
// function stopClock() {
|
||||
// if (clockRunning) {
|
||||
// clearInterval(gameClock)
|
||||
// clockRunning = false
|
||||
// }
|
||||
// }
|
||||
|
||||
const {gameClockTime} = useContext(GameClockContext)
|
||||
|
||||
|
||||
return (
|
||||
<div id="gameclock">{props.time}</div>
|
||||
<div id="gameClock">{gameClockTime}</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
64
src/contexts/gameClockContext.js
Normal file
64
src/contexts/gameClockContext.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import React, {useState, useEffect, useContext} from "react"
|
||||
import { KeyTypeContext } from "./keyTypeContext"
|
||||
const GameClockContext = React.createContext()
|
||||
|
||||
function GameClockContextProvider(props) {
|
||||
|
||||
const [gameClockTime, setGameClockTime] = useState(0)
|
||||
const [clockIsRunning, setClockIsRunning] = useState(false)
|
||||
const {keyType} = useContext(KeyTypeContext)
|
||||
|
||||
let gameClock = 0
|
||||
let intervals = []
|
||||
|
||||
|
||||
function startGameClock() {
|
||||
if (!clockIsRunning) {
|
||||
setClockIsRunning(true)
|
||||
intervals.push(setInterval(() => {
|
||||
document.getElementById('gameClock').innerText = Number(document.getElementById('gameClock').innerText) + 1
|
||||
}, 1000))
|
||||
}
|
||||
}
|
||||
function stopGameClock() {
|
||||
if (clockIsRunning) {
|
||||
clearInterval(gameClock)
|
||||
setClockIsRunning(false)
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
for (let i = 0; i < intervals.length; i++) {
|
||||
clearInterval(intervals[i]);
|
||||
}
|
||||
}
|
||||
// function startChallenge(event) {
|
||||
// console.log(event);
|
||||
// document.removeEventListener('keydown', startChallenge)
|
||||
// document.removeEventListener('mousedown', startChallenge)
|
||||
// startGameClock()
|
||||
// }
|
||||
|
||||
useEffect(() => {
|
||||
console.log('KEYTYPE CHANGE');
|
||||
|
||||
return function () {
|
||||
cleanup()
|
||||
}
|
||||
}, [keyType])
|
||||
|
||||
|
||||
return (
|
||||
<GameClockContext.Provider value={{
|
||||
gameClockTime: gameClockTime,
|
||||
setGameClockTime: setGameClockTime,
|
||||
startGameClock: startGameClock,
|
||||
stopGameClock: stopGameClock,
|
||||
cleanup: cleanup
|
||||
}}>
|
||||
{props.children}
|
||||
</GameClockContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export {GameClockContextProvider, GameClockContext}
|
||||
|
|
@ -110,6 +110,7 @@ header {
|
|||
height: 100%;
|
||||
min-width: 500px;
|
||||
width: 500px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
|
@ -410,6 +411,36 @@ i[class*="ri-"] {
|
|||
justify-content: space-around;
|
||||
}
|
||||
|
||||
#challenge-overlay {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
background-color: darkgoldenrod;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#challenge-overlay:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#challenge-overlay .notify {
|
||||
width: 300px;
|
||||
height: 250px;
|
||||
background: #DDD;
|
||||
}
|
||||
|
||||
#challengeWord {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
|
@ -438,8 +469,8 @@ i[class*="ri-"] {
|
|||
font-weight: bold;
|
||||
background: #fdfdfd;
|
||||
text-transform: uppercase;
|
||||
-webkit-transition: all 300ms ease-in-out;
|
||||
transition: all 300ms ease-in-out;
|
||||
-webkit-transition: all 100ms ease-in-out;
|
||||
transition: all 100ms ease-in-out;
|
||||
}
|
||||
|
||||
#challengeWord .cLetter {
|
||||
|
|
@ -455,15 +486,17 @@ i[class*="ri-"] {
|
|||
display: inline-block;
|
||||
padding-top: 10px;
|
||||
background: transparent;
|
||||
-webkit-transition: background 100ms ease-in-out;
|
||||
transition: background 100ms ease-in-out;
|
||||
}
|
||||
|
||||
#challengeWord .cLetter.correct {
|
||||
background: rgba(0, 255, 0, 0.6);
|
||||
background: #5ae65a;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#challengeWord.correct {
|
||||
background: rgba(0, 200, 0, 0.6);
|
||||
background: #5ae65a;
|
||||
}
|
||||
|
||||
#morseBufferDisplay {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -6,8 +6,8 @@ $buffer-font: 'Courier Prime', Courier, monospace;
|
|||
$ditDah-font: 'Courier', monospace;
|
||||
|
||||
$main-bg-color-light: #f1f1f1;
|
||||
|
||||
$main-font-color-light: #333;
|
||||
$correct-bg-color: rgba(90,230,90,1);
|
||||
|
||||
$morseCard-shadow-light: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
$main-box-shadow-light: 0px 3px 3px rgba(0, 0, 0, 0.3), 0px -1px 1px rgba(255, 255, 255, 1);
|
||||
|
|
@ -20,6 +20,8 @@ $main-border-radius: 3px;
|
|||
$border-radius-neumorphic: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.15);
|
||||
$border-radius-neumorphic-dark: 0px -10px 20px rgba(255, 255, 255, 0.1), 0px 10px 10px rgba(0, 0, 0, 0.4);
|
||||
$border-radius-neumorphic-active: 0 15px 20px rgba(0, 0, 0, 0.015), inset 0px -2px 5px rgb(255, 255, 255), inset 0px 2px 5px rgba(0, 0, 0, 0.15);
|
||||
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0px;
|
||||
|
|
@ -56,6 +58,7 @@ header {
|
|||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.sidebar#left {
|
||||
border: 1px solid yellowgreen;
|
||||
display: flex;
|
||||
|
|
@ -87,6 +90,7 @@ header {
|
|||
height: 100%;
|
||||
min-width: 500px;
|
||||
width: 500px;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
footer {
|
||||
|
|
@ -379,7 +383,29 @@ $button-height: 60px;
|
|||
// }
|
||||
// }
|
||||
|
||||
|
||||
#challenge-overlay {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top:0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
background-color: darkgoldenrod;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
.notify {
|
||||
width: 300px;
|
||||
height: 250px;
|
||||
background: #DDD;
|
||||
}
|
||||
}
|
||||
|
||||
#challengeWord {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
@ -403,7 +429,7 @@ $button-height: 60px;
|
|||
|
||||
background: #fdfdfd;
|
||||
text-transform: uppercase;
|
||||
transition: all 300ms ease-in-out;
|
||||
transition: all 100ms ease-in-out;
|
||||
|
||||
.cLetter {
|
||||
padding: 4px;
|
||||
|
|
@ -414,15 +440,15 @@ $button-height: 60px;
|
|||
display: inline-block;
|
||||
padding-top: 10px;
|
||||
background: transparent;
|
||||
// transition: background 100ms ease-in-out; //, opacity 100ms ease-in-out;
|
||||
transition: background 100ms ease-in-out; //, opacity 100ms ease-in-out;
|
||||
|
||||
&.correct {
|
||||
background: rgba(0,255,0,0.6);
|
||||
background: $correct-bg-color;
|
||||
border-radius: $main-border-radius;
|
||||
}
|
||||
}
|
||||
&.correct {
|
||||
background: rgba(0,200,0,0.6);
|
||||
background: $correct-bg-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue