mirror of
https://github.com/genemecija/learn-morse-code.git
synced 2026-01-20 15:20:24 +01:00
Layout updates
This commit is contained in:
parent
efdff300a1
commit
e683a4a824
40
src/App.js
40
src/App.js
|
|
@ -5,28 +5,23 @@ import { GameModeContext } from "./contexts/gameModeContext"
|
|||
import { MorseBufferContextProvider } from "./contexts/morseBufferContext"
|
||||
import { WordFeederContextProvider } from './contexts/wordFeederContext';
|
||||
import { WordListPickerContextProvider } from './contexts/wordListPickerContext';
|
||||
import { GameClockContextProvider } from './contexts/gameClockContext';
|
||||
import { WPMContextProvider } from './contexts/wpmContext';
|
||||
import { FrequencyContextProvider } from './contexts/frequencyContext';
|
||||
import { KeyTypeContextProvider } from './contexts/keyTypeContext';
|
||||
|
||||
import PracticeMode from './app-modes/PracticeMode';
|
||||
import ChallengeMode from './app-modes/ChallengeMode'
|
||||
|
||||
import ModePicker from './components/ModePicker'
|
||||
import KeyTypePicker from './components/KeyTypePicker'
|
||||
import WordListPicker from './components/WordListPicker';
|
||||
|
||||
import PracticeMode from './app-modes/PracticeMode';
|
||||
import TrainingMode from './app-modes/TrainingMode'
|
||||
import ChallengeMode from './app-modes/ChallengeMode'
|
||||
|
||||
import Header from './components/Header';
|
||||
import Legend from './components/Legend';
|
||||
// import GameClock from "./components/GameClock"
|
||||
import WordsPerMinute from "./components/WordsPerMinute"
|
||||
import MorseButtons from './components/MorseButtons'
|
||||
import Footer from './components/Footer';
|
||||
import Info from './components/Info';
|
||||
import { GameClockContextProvider } from './contexts/gameClockContext';
|
||||
import ChallengeOverlay from './components/ChallengeOverlay';
|
||||
import { KeyTypeContextProvider } from './contexts/keyTypeContext';
|
||||
import { WPMContextProvider } from './contexts/wpmContext';
|
||||
import PlayMorseInput from './components/PlayMorseInput';
|
||||
import SidebarLeft from './components/SidebarLeft';
|
||||
import FrequencyPicker from './components/FrequencyPicker';
|
||||
|
||||
export default React.memo(function App() {
|
||||
|
||||
|
|
@ -34,25 +29,29 @@ export default React.memo(function App() {
|
|||
|
||||
const {gameMode} = useContext(GameModeContext)
|
||||
|
||||
|
||||
function toggleRight() {
|
||||
document.querySelector('.sidebar#right').classList.toggle('hide')
|
||||
// document.querySelector('#main-interface').classList.toggle('expandRight')
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<div id='main-content'>
|
||||
<KeyTypeContextProvider>
|
||||
<WPMContextProvider>
|
||||
<FrequencyContextProvider>
|
||||
<MorseBufferContextProvider>
|
||||
<WordListPickerContextProvider>
|
||||
<WordFeederContextProvider>
|
||||
<GameClockContextProvider>
|
||||
<SidebarLeft />
|
||||
<div id="main-interface">
|
||||
<ModePicker />
|
||||
<div id="mainOptions">
|
||||
<div id="options-left">
|
||||
<ModePicker />
|
||||
<KeyTypePicker />
|
||||
</div>
|
||||
<div id="options-right">
|
||||
<WordsPerMinute />
|
||||
<FrequencyPicker />
|
||||
</div>
|
||||
</div>
|
||||
{gameMode === 'practice' &&
|
||||
<PracticeMode />
|
||||
}
|
||||
|
|
@ -85,6 +84,7 @@ export default React.memo(function App() {
|
|||
</WordFeederContextProvider>
|
||||
</WordListPickerContextProvider>
|
||||
</MorseBufferContextProvider>
|
||||
</FrequencyContextProvider>
|
||||
</WPMContextProvider>
|
||||
</KeyTypeContextProvider>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,7 @@
|
|||
import React from "react"
|
||||
|
||||
|
||||
export default (function ChallengeControls(props) {
|
||||
|
||||
// const {startGameClock} = useContext(GameClockContext)
|
||||
|
||||
// function startChallenge(e) {
|
||||
// let countdown
|
||||
// let count = 3
|
||||
// document.getElementById('challengeReady').classList.add('starting')
|
||||
// document.getElementById('challengeReady').innerHTML = `<span id="message">Challenge starting in</span><span id="count">${count}</span>`
|
||||
// countdown = setInterval(() => {
|
||||
// count--
|
||||
// document.getElementById('challengeReady').innerHTML = `<span id="message">Challenge starting in</span><span id="count">${count}</span>`
|
||||
// if (count === 0) {
|
||||
// // Do this when countdown hits 0
|
||||
// document.getElementById('challenge-overlay').classList.add('hide')
|
||||
// clearInterval(countdown)
|
||||
// startGameClock()
|
||||
// }
|
||||
// }, 1000)
|
||||
// }
|
||||
|
||||
return (
|
||||
<div id="challengeControls">
|
||||
<button onClick={props.stopChallenge}>Exit</button>
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ import ChallengeBufferDisplay from "./ChallengeBufferDisplay";
|
|||
// import ChallengeWord from "./ChallengeWord";
|
||||
|
||||
function ChallengeDisplay(props) {
|
||||
console.log('props.buffer:', props.buffer, '|END');
|
||||
|
||||
let morseLetters = props.buffer.split('_').filter(l => l !== '')
|
||||
console.log('morseLetters:', morseLetters, morseLetters.length);
|
||||
let challengeLetters = props.word.split('')
|
||||
let correctIndexes = []
|
||||
let incorrectIndex = null
|
||||
|
|
|
|||
55
src/components/FrequencyPicker.js
Normal file
55
src/components/FrequencyPicker.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import React, {useContext} from "react"
|
||||
import { FrequencyContext } from "../contexts/frequencyContext";
|
||||
|
||||
export default React.memo(function FrequencyPicker(props) {
|
||||
|
||||
const {frequency, setFrequency} = useContext(FrequencyContext)
|
||||
|
||||
const maxFreq = 1500
|
||||
const minFreq = 300
|
||||
|
||||
function handleChange(e) {
|
||||
if (Number(e.target.value) > maxFreq) {
|
||||
setFrequency(maxFreq)
|
||||
} else if (Number(e.target.value) < minFreq) {
|
||||
setFrequency(minFreq)
|
||||
} else {
|
||||
setFrequency(Number(e.target.value))
|
||||
}
|
||||
// setFrequency(Number(e.target.value))
|
||||
}
|
||||
function increment() {
|
||||
// setFrequency(prevFreq => prevFreq + 10)
|
||||
setFrequency(prevFreq => {
|
||||
if (prevFreq + 10 <= maxFreq) {
|
||||
return (prevFreq + 10)
|
||||
} else {
|
||||
return maxFreq
|
||||
}
|
||||
})
|
||||
}
|
||||
function decrement() {
|
||||
// setFrequency(prevFreq => prevFreq - 10)
|
||||
setFrequency(prevFreq => {
|
||||
if (prevFreq - 10 >= minFreq) {
|
||||
return (prevFreq - 10)
|
||||
} else {
|
||||
return minFreq
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div id='frequency' className='mode-picker'>
|
||||
<div id='title'>
|
||||
Frequency <span id="range">({minFreq}-{maxFreq})</span>
|
||||
</div>
|
||||
<div id='input'>
|
||||
<button id='freq-down' onClick={decrement}><i className="ri-arrow-down-s-line"></i></button>
|
||||
<input type="number" name="frequency" id='frequency-input' value={frequency} onChange={handleChange}></input>
|
||||
<button id='freq-up' onClick={increment}><i className="ri-arrow-up-s-line"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
@ -16,23 +16,23 @@ export default React.memo(function Info() {
|
|||
|
||||
<h2>Dits and Dahs</h2>
|
||||
<p>
|
||||
<h3>Dit</h3> <i className="ri-volume-up-fill" onClick={() => playMorseWord('.')}></i><br />
|
||||
<span className="bold">Dit</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('.')}></i><br />
|
||||
Denoted as a dot (.), dits are short tones and are base unit of morse code.<br />
|
||||
<h3>Dah</h3> <i className="ri-volume-up-fill" onClick={() => playMorseWord('-')}></i><br />
|
||||
<span className="bold">Dah</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('-')}></i><br />
|
||||
Denoted as a dash (-), dahs are long tones the length of three dits.
|
||||
</p>
|
||||
|
||||
<h2>Spacing</h2 >
|
||||
<p>
|
||||
<h3>Intra-character Spacing</h3> <i className="ri-volume-up-fill" onClick={() => playMorseWord('...')}></i><br />
|
||||
Silence between dits and dahs the length of one dit. Three dits separated by dit-long spaces is an "S".<br />
|
||||
<h3>Inter-character Spacing</h3> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. . .')}></i><br />
|
||||
Silence the length of 3 dits. Three dits separated by three-dit-long spaces is "EEE".<br />
|
||||
<h3>Inter-word Spacing</h3> <i className="ri-volume-up-fill" onClick={() => playMorseWord('././.')}></i><br />
|
||||
Silence the length of 7 dits. Three dits separated by seven-dit-long spaces is "E E E".
|
||||
<span className="bold">Intra-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('...')}></i><br />
|
||||
Silence between dits and dahs the length of one dit. Three dits separated by one-dit-long spaces is an "S".<br />
|
||||
<span className="bold">Inter-character Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. . .')}></i><br />
|
||||
Silence the length of three dits. Three dits separated by three-dit-long spaces is "EEE".<br />
|
||||
<span className="bold">Inter-word Spacing</span> <i className="ri-volume-up-fill" onClick={() => playMorseWord('. /. /.')}></i><br />
|
||||
Silence the length of seven dits. Three dits separated by seven-dit-long spaces is "E E E".
|
||||
</p>
|
||||
|
||||
<h2>Speed</h2 >
|
||||
<h2>Speed</h2>
|
||||
<p>
|
||||
Adjusting the <b>WPM</b> (Words Per Minute) in the Options Menu will adjust the lengths of the dits, dahs, and spacing accordingly.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -30,16 +30,13 @@ function ModePicker() {
|
|||
|
||||
return (
|
||||
<div id="gameMode" className="mode-picker">
|
||||
{/* <div id="title">
|
||||
<div id="title">
|
||||
Mode
|
||||
</div> */}
|
||||
</div>
|
||||
<div id='buttons'>
|
||||
<button id="practice" className="selected" onClick={handleClick}>
|
||||
Practice Mode
|
||||
</button>
|
||||
<button id="training" onClick={handleClick}>
|
||||
Training Mode
|
||||
</button>
|
||||
<button id="challenge" onClick={handleClick}>
|
||||
Challenge Mode
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export default React.memo(function MorseBufferDisplay() {
|
|||
|
||||
return (
|
||||
<div id="morseBufferDisplay">
|
||||
<div id="overlay"></div>
|
||||
<div id="ditDahs-container">
|
||||
<div id="ditDahs">
|
||||
{ditDahs}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ export default (function Options() {
|
|||
return (
|
||||
<div id="mainOptions">
|
||||
<div id="mainOptions-title">Options</div>
|
||||
<KeyTypePicker />
|
||||
<WordsPerMinute />
|
||||
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default (function PlayMorseInput() {
|
|||
<h2>Translate To Morse</h2>
|
||||
</div>
|
||||
<div id="input">
|
||||
<input type="text" id='morseInput' value={inputValue} onChange={handleChange} placeholder="Type here." maxLength="25"/> Listen <i className="ri-volume-up-fill" onClick={handlePlay}></i>
|
||||
<input type="text" id='morseInput' value={inputValue} onChange={handleChange} placeholder="Type here." maxLength="25"/> <i className="ri-volume-up-fill" onClick={handlePlay}></i>
|
||||
</div>
|
||||
<div id="morseTranslation">
|
||||
<span id="morseTrans">
|
||||
|
|
|
|||
|
|
@ -41,18 +41,19 @@ export default (function SidebarLeft() {
|
|||
<div id="nav-legend" className="nav-item" onClick={navClicked}>
|
||||
Legend
|
||||
</div>
|
||||
<div id="nav-options" className="nav-item" onClick={navClicked}>
|
||||
Options
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="info-icon" onClick={toggleLeft}><i class="ri-information-line"></i></div>
|
||||
<div id="info-icon" onClick={toggleLeft}><i className="ri-information-line"></i></div>
|
||||
|
||||
<div id='sidebar-content'>
|
||||
{sidebarContent === 'nav-learn' && <Info />}
|
||||
{sidebarContent === 'nav-legend' && <div id="playerAndLegend"><PlayMorseInput /><Legend /></div>}
|
||||
{sidebarContent === 'nav-options' && <Options /> }
|
||||
|
||||
{sidebarContent === 'nav-legend' &&
|
||||
<div id="playerAndLegend">
|
||||
<Legend />
|
||||
<span id="note">Adjust the Morse code speed by changing the WPM in the Options menu.</span>
|
||||
<PlayMorseInput />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default React.memo(function WordListPicker() {
|
|||
}
|
||||
|
||||
let wordLists = ['alphabet', 'numbers', 'common100', 'test', 'short']
|
||||
let options = wordLists.map(wl => (<option value={wl}>{wl.substr(0,1).toUpperCase() + wl.substr(1)}</option>))
|
||||
let options = wordLists.map((wl, index) => (<option value={wl} key={index}>{wl.substr(0,1).toUpperCase() + wl.substr(1)}</option>))
|
||||
|
||||
return (
|
||||
<div id="challengeOptions">
|
||||
|
|
|
|||
|
|
@ -1,35 +1,58 @@
|
|||
import React, {useContext} from "react"
|
||||
import { WPMContext } from "../contexts/wpmContext";
|
||||
import useMorsePlayer from "../hooks/useMorsePlayer";
|
||||
|
||||
export default React.memo(function WordsPerMinute(props) {
|
||||
console.log('WordsPerMinute rendered');
|
||||
|
||||
const {wpm, setWPM} = useContext(WPMContext)
|
||||
|
||||
const {playMorseWord} = useMorsePlayer()
|
||||
const maxWPM = 30
|
||||
const minWPM = 5
|
||||
|
||||
function handleChange(e) {
|
||||
setWPM(Number(e.target.value))
|
||||
// setWPM(Number(e.target.value))
|
||||
if (Number(e.target.value) > maxWPM) {
|
||||
setWPM(maxWPM)
|
||||
} else if (Number(e.target.value) < minWPM) {
|
||||
setWPM(minWPM)
|
||||
} else {
|
||||
setWPM(Number(e.target.value))
|
||||
}
|
||||
}
|
||||
function increment() {
|
||||
setWPM(prevWPM => prevWPM + 1)
|
||||
// setWPM(prevWPM => prevWPM + 1)
|
||||
setWPM(prevWPM => {
|
||||
if (prevWPM + 1 <= maxWPM) {
|
||||
return (prevWPM + 1)
|
||||
} else {
|
||||
return maxWPM
|
||||
}
|
||||
})
|
||||
}
|
||||
function decrement() {
|
||||
setWPM(prevWPM => prevWPM - 1)
|
||||
// setWPM(prevWPM => prevWPM - 1)
|
||||
setWPM(prevWPM => {
|
||||
if (prevWPM - 1 >= minWPM) {
|
||||
return (prevWPM - 1)
|
||||
} else {
|
||||
return minWPM
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
console.log('wpm', wpm);
|
||||
console.log('typeof wpm', typeof wpm);
|
||||
|
||||
return (
|
||||
// <input id='wpm-input' type='text' value={wpm} onChange={handleChange} />
|
||||
<div id='wpm' className='mode-picker'>
|
||||
<div id='title'>
|
||||
WPM
|
||||
WPM <span id="range">({minWPM}-{maxWPM})</span>
|
||||
</div>
|
||||
<div id='input'>
|
||||
<button id='wpm-down' onClick={decrement}><i className="ri-arrow-down-s-line"></i></button>
|
||||
<input type="number" name="wpm" id='wpm-input' min="5" max="30" value={wpm} onChange={handleChange}></input>
|
||||
<button id='wpm-up' onClick={increment}><i className="ri-arrow-up-s-line"></i></button>
|
||||
Test Speed <i className="ri-volume-up-fill" onClick={() => playMorseWord('.....')}></i>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
19
src/contexts/frequencyContext.js
Normal file
19
src/contexts/frequencyContext.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import React, {useState} from "react"
|
||||
|
||||
const FrequencyContext = React.createContext()
|
||||
|
||||
function FrequencyContextProvider(props) {
|
||||
|
||||
const [frequency, setFrequency] = useState(650)
|
||||
|
||||
return (
|
||||
<FrequencyContext.Provider value={{
|
||||
frequency: Number(frequency),
|
||||
setFrequency: setFrequency}
|
||||
}>
|
||||
{props.children}
|
||||
</FrequencyContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export {FrequencyContextProvider, FrequencyContext}
|
||||
|
|
@ -4,7 +4,7 @@ const WPMContext = React.createContext()
|
|||
|
||||
function WPMContextProvider(props) {
|
||||
|
||||
const [wpm, setWPM] = useState(15)
|
||||
const [wpm, setWPM] = useState(10)
|
||||
|
||||
return (
|
||||
<WPMContext.Provider value={{
|
||||
|
|
|
|||
350
src/css/App.css
350
src/css/App.css
|
|
@ -1,4 +1,4 @@
|
|||
@import url("https://fonts.googleapis.com/css?family=Courier+Prime:700|Asap|Roboto:700|Roboto|Ubuntu&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css?family=Courier+Prime:700|Asap|Roboto:700|Roboto&display=swap");
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
|
@ -47,10 +47,11 @@ html, body {
|
|||
background: #333;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 2.5em;
|
||||
color: #dab820;
|
||||
color: #eee;
|
||||
z-index: 1000;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.5);
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.45);
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
#main-content {
|
||||
|
|
@ -74,8 +75,8 @@ html, body {
|
|||
|
||||
#main-content .sidebar#left {
|
||||
background: #eee;
|
||||
-webkit-box-shadow: 3px 0px 5px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 3px 0px 5px rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 3px 0px 3px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 3px 0px 3px rgba(0, 0, 0, 0.25);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
line-height: 1.5em;
|
||||
display: -webkit-box;
|
||||
|
|
@ -137,7 +138,7 @@ html, body {
|
|||
|
||||
#main-content .sidebar#left #sidebar-container .navbar .nav-item {
|
||||
padding: 10px;
|
||||
width: 20%;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
|
|
@ -199,7 +200,6 @@ html, body {
|
|||
justify-content: center;
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
height: calc(100% - 35px);
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #playerAndLegend {
|
||||
|
|
@ -218,6 +218,19 @@ html, body {
|
|||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #playerAndLegend #legend, #main-content .sidebar#left #sidebar-container #sidebar-content #playerAndLegend #playMorseInput, #main-content .sidebar#left #sidebar-container #sidebar-content #playerAndLegend span#note {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #playerAndLegend span#note {
|
||||
font-family: "Courier", monospace;
|
||||
color: #555;
|
||||
display: inline-block;
|
||||
width: 65%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #info {
|
||||
|
|
@ -237,12 +250,14 @@ html, body {
|
|||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #info h3 {
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #info .bold {
|
||||
display: inline-block;
|
||||
font-size: 1.15em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #info p, #main-content .sidebar#left #sidebar-container #sidebar-content #info #legend, #main-content .sidebar#left #sidebar-container #sidebar-content #info #playMorseInput {
|
||||
#main-content .sidebar#left #sidebar-container #sidebar-content #info p {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +271,7 @@ html, body {
|
|||
}
|
||||
|
||||
#main-content #main-interface {
|
||||
background: white;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -279,7 +295,28 @@ html, body {
|
|||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
#main-content #main-interface #gameMode {
|
||||
#main-content #main-interface #mainOptions {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: start;
|
||||
-ms-flex-pack: start;
|
||||
justify-content: flex-start;
|
||||
height: 6em;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background: rgba(112, 128, 144, 0.3);
|
||||
-webkit-box-shadow: inset 0px -2px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0px -2px 2px rgba(0, 0, 0, 0.1);
|
||||
font-family: "Roboto", sans-serif;
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left, #main-content #main-interface #mainOptions #options-right {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -287,38 +324,122 @@ html, body {
|
|||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
width: -webkit-fit-content;
|
||||
width: -moz-fit-content;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker, #main-content #main-interface #mainOptions #options-right .mode-picker {
|
||||
width: -webkit-fit-content;
|
||||
width: -moz-fit-content;
|
||||
width: fit-content;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-line-pack: start;
|
||||
align-content: flex-start;
|
||||
-webkit-box-pack: start;
|
||||
-ms-flex-pack: start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker div, #main-content #main-interface #mainOptions #options-right .mode-picker div {
|
||||
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;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 2em;
|
||||
z-index: 100;
|
||||
padding: 3px;
|
||||
height: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#main-content #main-interface #gameMode button {
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #title, #main-content #main-interface #mainOptions #options-right .mode-picker #title {
|
||||
-webkit-box-pack: end;
|
||||
-ms-flex-pack: end;
|
||||
justify-content: flex-end;
|
||||
width: 10em;
|
||||
font-weight: bold;
|
||||
font-size: 1.15em;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #title span#range, #main-content #main-interface #mainOptions #options-right .mode-picker #title span#range {
|
||||
display: inline-block;
|
||||
padding-left: 5px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #buttons, #main-content #main-interface #mainOptions #options-right .mode-picker #buttons {
|
||||
-webkit-box-pack: space-evenly;
|
||||
-ms-flex-pack: space-evenly;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #input input, #main-content #main-interface #mainOptions #options-right .mode-picker #input input {
|
||||
width: 50px;
|
||||
height: 1.5rem;
|
||||
border: 1px solid #ddd;
|
||||
-webkit-appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
appearance: textfield;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #input select, #main-content #main-interface #mainOptions #options-right .mode-picker #input select {
|
||||
height: 1.4rem;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #input button, #main-content #main-interface #mainOptions #options-right .mode-picker #input button {
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #input button i, #main-content #main-interface #mainOptions #options-right .mode-picker #input button i {
|
||||
position: relative;
|
||||
left: -6px;
|
||||
top: -2px;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker button, #main-content #main-interface #mainOptions #options-right .mode-picker button {
|
||||
background: #eee;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
border-radius: 3px;
|
||||
border: 0px;
|
||||
padding: 0.5em;
|
||||
padding: 0.2em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
font-size: 1rem;
|
||||
font-size: 0.9em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#main-content #main-interface #gameMode button.selected {
|
||||
color: #467686;
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker button.selected, #main-content #main-interface #mainOptions #options-right .mode-picker button.selected {
|
||||
-webkit-box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.3), inset 0px -1px 1px white;
|
||||
box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.3), inset 0px -1px 1px white;
|
||||
}
|
||||
|
||||
#main-content #main-interface #mainOptions #options-left .mode-picker #title {
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
width: 100%;
|
||||
height: 2em;
|
||||
|
|
@ -341,130 +462,6 @@ i[class*="ri-"] {
|
|||
color: #777;
|
||||
}
|
||||
|
||||
#mainOptions {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 100% !important;
|
||||
font-family: "Roboto", sans-serif;
|
||||
padding: 2em;
|
||||
padding-top: 5em;
|
||||
}
|
||||
|
||||
#mainOptions #mainOptions-title {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker {
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-ms-flex-line-pack: start;
|
||||
align-content: flex-start;
|
||||
-webkit-box-pack: start;
|
||||
-ms-flex-pack: start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker div {
|
||||
padding: 3px;
|
||||
height: 100%;
|
||||
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;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #title {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #buttons {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: space-evenly;
|
||||
-ms-flex-pack: space-evenly;
|
||||
justify-content: space-evenly;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #input input {
|
||||
width: 50px;
|
||||
height: 2rem;
|
||||
border: 1px solid #ddd;
|
||||
-webkit-appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
appearance: textfield;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #input select {
|
||||
height: 1.4rem;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #input button {
|
||||
width: 1.6em;
|
||||
height: 1.6em;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker #input button i {
|
||||
position: relative;
|
||||
left: -5px;
|
||||
top: -4px;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker button {
|
||||
background: #eee;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
border-radius: 3px;
|
||||
border: 0px;
|
||||
padding: 0.5em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
font-size: 1em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#mainOptions .mode-picker button.selected {
|
||||
-webkit-box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.3), inset 0px -1px 1px white;
|
||||
box-shadow: inset 0px 2px 2px rgba(0, 0, 0, 0.3), inset 0px -1px 1px white;
|
||||
}
|
||||
|
||||
#playMorseInput {
|
||||
background: #ddd;
|
||||
width: 400px;
|
||||
|
|
@ -482,7 +479,6 @@ i[class*="ri-"] {
|
|||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin-bottom: 45px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#playMorseInput i:hover {
|
||||
|
|
@ -562,8 +558,18 @@ i[class*="ri-"] {
|
|||
width: 15%;
|
||||
margin: 5px;
|
||||
padding: 0.3em;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
-webkit-transition: all 50ms ease-in-out;
|
||||
transition: all 50ms ease-in-out;
|
||||
background: #ddd;
|
||||
border: 0px;
|
||||
background: #eee;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
}
|
||||
|
||||
#legend #legend-items .item span {
|
||||
-webkit-transition: all 50ms ease-in-out;
|
||||
transition: all 50ms ease-in-out;
|
||||
}
|
||||
|
|
@ -572,6 +578,7 @@ i[class*="ri-"] {
|
|||
-webkit-transform: scale(0.95);
|
||||
transform: scale(0.95);
|
||||
border-color: rgba(112, 128, 144, 0.6);
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
#legend #legend-items .item:active span:first-child {
|
||||
|
|
@ -580,6 +587,7 @@ i[class*="ri-"] {
|
|||
|
||||
#legend #legend-items .item:hover {
|
||||
border-color: rgba(112, 128, 144, 0.6);
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
#legend #legend-items .item:hover span:first-child {
|
||||
|
|
@ -622,8 +630,8 @@ i[class*="ri-"] {
|
|||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-transition: width 500ms ease-out, background 500ms ease-out, -webkit-transform 40ms ease-out, -webkit-box-shadow 40ms ease-out;
|
||||
transition: width 500ms ease-out, background 500ms ease-out, -webkit-transform 40ms ease-out, -webkit-box-shadow 40ms ease-out;
|
||||
transition: transform 40ms ease-out, box-shadow 40ms ease-out, width 500ms ease-out, background 500ms ease-out;
|
||||
|
|
@ -661,8 +669,8 @@ i[class*="ri-"] {
|
|||
font-weight: bold;
|
||||
width: 30px;
|
||||
height: 100px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
}
|
||||
|
||||
#morseButton button#left {
|
||||
|
|
@ -740,7 +748,7 @@ i[class*="ri-"] {
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 50;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -776,7 +784,7 @@ i[class*="ri-"] {
|
|||
padding: 1.5rem;
|
||||
height: 250px;
|
||||
background: #fefefe;
|
||||
margin-top: 150px;
|
||||
margin-top: 30%;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.5);
|
||||
|
|
@ -800,8 +808,8 @@ i[class*="ri-"] {
|
|||
|
||||
#challenge-overlay #challengeReady button {
|
||||
background: #eee;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
border-radius: 3px;
|
||||
border: 0px;
|
||||
padding: 0.3em;
|
||||
|
|
@ -943,8 +951,8 @@ i[class*="ri-"] {
|
|||
margin-bottom: 10px;
|
||||
margin-top: 25px;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px white;
|
||||
font-size: 4rem;
|
||||
font-family: "Courier Prime", Courier, monospace;
|
||||
font-weight: bold;
|
||||
|
|
@ -986,6 +994,7 @@ i[class*="ri-"] {
|
|||
}
|
||||
|
||||
#morseBufferDisplay {
|
||||
background: #eee;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -1012,30 +1021,24 @@ i[class*="ri-"] {
|
|||
position: absolute;
|
||||
display: inline-block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
left: calc(50% - 37.5%);
|
||||
width: 600px;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container {
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
min-width: 300px;
|
||||
overflow: hidden;
|
||||
max-width: 75%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric {
|
||||
background: #fdfdfd;
|
||||
height: 5rem;
|
||||
width: 100%;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-top: 0.45rem;
|
||||
font-size: 4rem;
|
||||
min-width: 4rem;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 3px;
|
||||
float: right;
|
||||
|
|
@ -1043,7 +1046,8 @@ i[class*="ri-"] {
|
|||
|
||||
#morseBufferDisplay #ditDahs-container {
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
max-width: 75%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
@ -1207,9 +1211,9 @@ i[class*="ri-"] {
|
|||
}
|
||||
|
||||
#morseHistory-textbox {
|
||||
background: #ddd;
|
||||
background: #f8f8f8;
|
||||
border-radius: 5px;
|
||||
min-height: 2em;
|
||||
min-height: 4em;
|
||||
width: 80%;
|
||||
max-width: 500px;
|
||||
padding: 0.5em;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -3,14 +3,16 @@ import {MorseBufferContext} from '../contexts/morseBufferContext'
|
|||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext'
|
||||
import { GameModeContext } from '../contexts/gameModeContext'
|
||||
import { FrequencyContext } from '../contexts/frequencyContext'
|
||||
|
||||
// ELECTRONIC KEY TELEGRAPH - Iambic A
|
||||
|
||||
function useElectronicKey() {
|
||||
console.log('useElectronicKey');
|
||||
|
||||
const {morseCharBuffer, setMorseCharBuffer, morseWords, setMorseWords} = useContext(MorseBufferContext)
|
||||
const {wpm} = useContext(WPMContext)
|
||||
const {gameMode} = useContext(GameModeContext)
|
||||
const {frequency} = useContext(FrequencyContext)
|
||||
|
||||
let ditMaxTime = 1200/wpm
|
||||
|
||||
|
|
@ -62,7 +64,7 @@ function useElectronicKey() {
|
|||
} else {
|
||||
context = null
|
||||
}
|
||||
let frequency = config.frequency
|
||||
// let frequency = config.frequency
|
||||
|
||||
|
||||
let toneTimer = 0
|
||||
|
|
@ -239,8 +241,13 @@ function useElectronicKey() {
|
|||
|
||||
paddlesReleasedSimultaneously = false
|
||||
|
||||
if ((event.keyCode === 188 || event.keyCode === 190) && document.activeElement.id === 'morseInput') {
|
||||
return
|
||||
if (event.keyCode === 188 || event.keyCode === 190) {
|
||||
if (document.activeElement.id === 'morseInput') {
|
||||
return
|
||||
} else if (document.activeElement.tagName.toLowerCase() !== 'body') {
|
||||
event.preventDefault()
|
||||
document.activeElement.blur()
|
||||
}
|
||||
}
|
||||
if (event.repeat) { return }
|
||||
|
||||
|
|
@ -363,7 +370,7 @@ function useElectronicKey() {
|
|||
// clearHistory()
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [wpm, gameMode])
|
||||
}, [wpm, gameMode, frequency])
|
||||
|
||||
useEffect(() => {
|
||||
// PRACTICE MODE
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext.js';
|
||||
import { useContext } from 'react';
|
||||
import { FrequencyContext } from '../contexts/frequencyContext.js';
|
||||
|
||||
function useMorsePlayer() {
|
||||
|
||||
const {wpm} = useContext(WPMContext)
|
||||
const {frequency} = useContext(FrequencyContext)
|
||||
// const ditMaxTime = 85 //config.ditMaxTime
|
||||
const ditMaxTime = 1200/wpm
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ function useMorsePlayer() {
|
|||
context = null
|
||||
}
|
||||
|
||||
let frequency = config.frequency
|
||||
// let frequency = config.frequency
|
||||
|
||||
function play(ditDah) {
|
||||
let length = ((ditDah === '.') ? ditMaxTime : ditMaxTime*3)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {MorseBufferContext} from '../contexts/morseBufferContext'
|
|||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext'
|
||||
import { GameModeContext } from '../contexts/gameModeContext'
|
||||
import { FrequencyContext } from '../contexts/frequencyContext'
|
||||
|
||||
// STRAIGHT KEY TELEGRAPH
|
||||
function useStraightKey() {
|
||||
|
|
@ -10,6 +11,7 @@ function useStraightKey() {
|
|||
const {morseCharBuffer, setMorseCharBuffer, morseWords, setMorseWords} = useContext(MorseBufferContext)
|
||||
const {wpm} = useContext(WPMContext)
|
||||
const {gameMode} = useContext(GameModeContext)
|
||||
const {frequency} = useContext(FrequencyContext)
|
||||
|
||||
let charTimer = 0
|
||||
let charTime = 0
|
||||
|
|
@ -37,7 +39,7 @@ function useStraightKey() {
|
|||
|
||||
let o // Oscillator Node
|
||||
let g // Gain Node
|
||||
let frequency = config.frequency
|
||||
// let frequency = config.frequency
|
||||
|
||||
let isRunning = false
|
||||
|
||||
|
|
@ -51,13 +53,13 @@ function useStraightKey() {
|
|||
console.log(event.keyCode);
|
||||
|
||||
if (event.keyCode === 32) {
|
||||
if (document.activeElement.id === 'wordlist-picker') {
|
||||
if (document.activeElement.id === 'morseInput') {
|
||||
return
|
||||
}
|
||||
else if (document.activeElement.tagName.toLowerCase() !== 'body') {
|
||||
event.preventDefault()
|
||||
document.activeElement.blur()
|
||||
}
|
||||
else if (document.activeElement.id === 'morseInput') {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -218,7 +220,7 @@ function useStraightKey() {
|
|||
// clearHistory()
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [wpm, gameMode])
|
||||
}, [wpm, gameMode, frequency])
|
||||
|
||||
useEffect(() => {
|
||||
// PRACTICE MODE
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// $main-bg-color-dark: #2c2c2c;
|
||||
@import url('https://fonts.googleapis.com/css?family=Courier+Prime:700|Asap|Roboto:700|Roboto|Ubuntu&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css?family=Courier+Prime:700|Asap|Roboto:700|Roboto&display=swap');
|
||||
// $main-font: 'Asap', sans-serif;
|
||||
$main-font: 'Roboto', sans-serif;
|
||||
// $main-font-bold: 'Roboto', sans-serif;
|
||||
|
|
@ -13,7 +13,7 @@ $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.35), 0px -1px 1px rgba(255, 255, 255, 1);
|
||||
$main-box-shadow-light: 0px 2px 2px rgba(0, 0, 0, 0.35), 0px -1px 1px rgba(255, 255, 255, 1);
|
||||
$main-box-shadow-light-selected: inset 0px 2px 2px rgba(0, 0, 0, 0.3), inset 0px -1px 1px rgba(255, 255, 255, 1);
|
||||
$main-box-shadow-dark: 0px 3px 3px rgba(0, 0, 0, 0.2), 0px -1px 1px rgba(255, 255, 255, 0.1);
|
||||
$main-box-shadow-dark-selected: inset 0px 2px 2px rgba(0, 0, 0, 0.2), inset 0px -1px 1px rgba(255, 255, 255, 0.1);
|
||||
|
|
@ -62,9 +62,11 @@ html, body {
|
|||
font-family: $main-font;
|
||||
font-size: 2.5em;
|
||||
// font-weight: bold;
|
||||
// color: $main-bg-color-light;
|
||||
color: rgb(218, 184, 32);
|
||||
color: $main-bg-color-light;
|
||||
z-index: 1000;
|
||||
box-shadow: 0px 2px 2px rgba(0,0,0,0.5);
|
||||
box-shadow: 0px 2px 2px rgba(0,0,0,0.45);
|
||||
}
|
||||
#main-content {
|
||||
display: flex;
|
||||
|
|
@ -81,8 +83,9 @@ html, body {
|
|||
|
||||
.sidebar#left {
|
||||
// border: 1px solid blue;
|
||||
// background: $main-bg-color-light;
|
||||
background: $main-bg-color-light;
|
||||
box-shadow: 3px 0px 5px rgba(0,0,0,0.2);
|
||||
box-shadow: 3px 0px 3px rgba(0,0,0,0.25);
|
||||
|
||||
font-family: 'Roboto', sans-serif;
|
||||
line-height: 1.5em;
|
||||
|
|
@ -142,7 +145,7 @@ html, body {
|
|||
// border: 1px solid black;
|
||||
padding: 10px;
|
||||
// margin: 10px;
|
||||
width: 20%;
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
@ -186,7 +189,7 @@ html, body {
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-self: center;
|
||||
height: calc(100% - 35px);
|
||||
// height: calc(100% - 35px);
|
||||
// height: 100%;
|
||||
|
||||
#playerAndLegend {
|
||||
|
|
@ -197,6 +200,17 @@ html, body {
|
|||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
overflow-y: scroll;
|
||||
#legend, #playMorseInput, span#note {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
span#note {
|
||||
font-family: $ditDah-font;
|
||||
color: #555;
|
||||
display: inline-block;
|
||||
width: 65%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
#info {
|
||||
|
|
@ -216,11 +230,13 @@ html, body {
|
|||
margin-bottom: 0.3em;
|
||||
// text-transform: uppercase;
|
||||
}
|
||||
h3 {
|
||||
.bold {
|
||||
display: inline-block;
|
||||
font-size: 1.15em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
p, #legend, #playMorseInput {
|
||||
p {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
img {
|
||||
|
|
@ -299,6 +315,7 @@ html, body {
|
|||
#main-interface {
|
||||
// border: 1px solid red;
|
||||
|
||||
background: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -319,36 +336,191 @@ html, body {
|
|||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
#gameMode {
|
||||
#mainOptions {
|
||||
// border: 1px solid red;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 2em;
|
||||
z-index: 100;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
// align-items: flex-start;
|
||||
|
||||
height: 6em;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background: rgba(112, 128, 144,0.3);
|
||||
box-shadow: inset 0px -2px 2px rgba(0,0,0,0.1);
|
||||
|
||||
button {
|
||||
background: $main-bg-color-light;
|
||||
box-shadow: $main-box-shadow-light;
|
||||
border-radius: $main-border-radius;
|
||||
border: 0px;
|
||||
padding: 0.5em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
font-family: $main-font;
|
||||
z-index: 500;
|
||||
|
||||
font-size: 1rem;
|
||||
color: $main-font-color-light;
|
||||
#options-left, #options-right {
|
||||
// border: 1px solid cyan;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: fit-content;
|
||||
|
||||
&.selected {
|
||||
color: rgb(70, 118, 134);;
|
||||
box-shadow: $main-box-shadow-light-selected;
|
||||
.mode-picker {
|
||||
// border: 1px solid green;
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
|
||||
div {
|
||||
// border: 1px solid blue;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 3px;
|
||||
height: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
#title {
|
||||
// border: 1px solid red;
|
||||
justify-content: flex-end;
|
||||
width: 10em;
|
||||
font-weight: bold;
|
||||
font-size: 1.15em;
|
||||
span#range {
|
||||
display: inline-block;
|
||||
padding-left: 5px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
#buttons {
|
||||
// border: 1px solid blue;
|
||||
justify-content: space-evenly;
|
||||
// margin-bottom: 20px;
|
||||
}
|
||||
#input {
|
||||
input {
|
||||
width: 50px;
|
||||
height: 1.5rem;
|
||||
border: 1px solid #ddd;
|
||||
appearance: textfield;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
select {
|
||||
height: 1.4rem;
|
||||
}
|
||||
button {
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
// line-height: 10px;
|
||||
i {
|
||||
position: relative;
|
||||
left: -6px;
|
||||
top: -2px;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
button {
|
||||
background: $main-bg-color-light;
|
||||
box-shadow: $main-box-shadow-light;
|
||||
border-radius: $main-border-radius;
|
||||
border: 0px;
|
||||
padding: 0.2em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
|
||||
font-size: 0.9em;
|
||||
color: $main-font-color-light;
|
||||
|
||||
&.selected {
|
||||
box-shadow: $main-box-shadow-light-selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#options-left .mode-picker {
|
||||
#title {
|
||||
width: 5em;
|
||||
}
|
||||
}
|
||||
|
||||
// #mainOptions-title {
|
||||
// font-size: 2em;
|
||||
// font-weight: bold;
|
||||
// margin-bottom: 30px;
|
||||
// text-transform: uppercase;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
// #gameMode {
|
||||
// // border: 1px solid red;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// width: 100%;
|
||||
// font-size: 1.5em;
|
||||
// font-weight: bold;
|
||||
// // margin-top: 1em;
|
||||
// margin-bottom: 2em;
|
||||
// z-index: 100;
|
||||
|
||||
// #buttons {
|
||||
// // border: 1px solid purple;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// padding: 0px;
|
||||
|
||||
// button {
|
||||
// // background: $main-bg-color-light;
|
||||
// // box-shadow: $main-box-shadow-light;
|
||||
// // border-radius: $main-border-radius;
|
||||
// // border: 0px;
|
||||
// // padding: 0.5em;
|
||||
// // margin-left: 10px;
|
||||
// // margin-right: 10px;
|
||||
|
||||
// // font-size: 1rem;
|
||||
// // color: $main-font-color-light;
|
||||
|
||||
// // &.selected {
|
||||
// // // color: rgb(70, 118, 134);;
|
||||
// // box-shadow: $main-box-shadow-light-selected;
|
||||
// // }
|
||||
// background: white;
|
||||
// font-size: 0.7em;
|
||||
// // font-weight: bold;
|
||||
// // text-transform: uppercase;
|
||||
|
||||
// margin-top: 3px;
|
||||
// padding: 0.3em;
|
||||
// width: 10em;
|
||||
// height: 100%;
|
||||
|
||||
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// // position: relative;
|
||||
// // overflow: hidden;
|
||||
// transition: all 150ms ease-in-out;
|
||||
// border: 0px;
|
||||
// border-bottom: 2px solid transparent;
|
||||
|
||||
// &:hover {
|
||||
// background: rgba(0, 0, 0, 0.1);
|
||||
// border-color: #999;
|
||||
// }
|
||||
// &.selected {
|
||||
// border-color: rgb(180, 60, 60);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
#footer {
|
||||
|
|
@ -361,7 +533,6 @@ html, body {
|
|||
// font-weight: bold;
|
||||
color: $main-bg-color-light;
|
||||
z-index: 1000;
|
||||
// box-shadow: $main-box-shadow-light;
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: 0.5em;
|
||||
|
|
@ -373,107 +544,7 @@ i[class*="ri-"] {
|
|||
color: #777;
|
||||
}
|
||||
|
||||
#mainOptions {
|
||||
// border: 1px solid red;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100% !important;
|
||||
// max-width: 95vw;
|
||||
// height: 200px;
|
||||
font-family: $main-font;
|
||||
padding: 2em;
|
||||
padding-top: 5em;
|
||||
// padding-left: 1.5em;
|
||||
// margin-top: 10px;
|
||||
// top: 50px;
|
||||
|
||||
#mainOptions-title {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.mode-picker {
|
||||
// border: 1px solid green;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-content: flex-start;
|
||||
justify-content: flex-start;
|
||||
|
||||
|
||||
div {
|
||||
// border: 1px solid blue;
|
||||
padding: 3px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
#title {
|
||||
// border: 1px solid red;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
#buttons {
|
||||
// border: 1px solid blue;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
#input {
|
||||
input {
|
||||
width: 50px;
|
||||
height: 2rem;
|
||||
border: 1px solid #ddd;
|
||||
appearance: textfield;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
}
|
||||
select {
|
||||
height: 1.4rem;
|
||||
}
|
||||
button {
|
||||
width: 1.6em;
|
||||
height: 1.6em;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
// line-height: 10px;
|
||||
i {
|
||||
position: relative;
|
||||
left: -5px;
|
||||
top: -4px;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
button {
|
||||
background: $main-bg-color-light;
|
||||
box-shadow: $main-box-shadow-light;
|
||||
border-radius: $main-border-radius;
|
||||
border: 0px;
|
||||
padding: 0.5em;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
|
||||
font-size: 1em;
|
||||
color: $main-font-color-light;
|
||||
|
||||
&.selected {
|
||||
box-shadow: $main-box-shadow-light-selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#playMorseInput {
|
||||
background: #ddd;
|
||||
|
|
@ -486,7 +557,7 @@ i[class*="ri-"] {
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 45px;
|
||||
overflow: hidden;
|
||||
// overflow: hidden;
|
||||
|
||||
i:hover {
|
||||
color: goldenrod;
|
||||
|
|
@ -555,19 +626,28 @@ i[class*="ri-"] {
|
|||
|
||||
margin: 5px;
|
||||
padding: 0.3em;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
transition: all 50ms ease-in-out;
|
||||
// box-shadow: $main-box-shadow-light;
|
||||
background: #ddd;
|
||||
|
||||
border: 0px;
|
||||
background: $main-bg-color-light;
|
||||
box-shadow: $main-box-shadow-light;
|
||||
span {
|
||||
transition: all 50ms ease-in-out;
|
||||
}
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
border-color: rgba(112, 128, 144,0.6);
|
||||
background: #ddd;
|
||||
span:first-child {
|
||||
background: rgba(112, 128, 144,0.6);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border-color: rgba(112, 128, 144,0.6);
|
||||
background: #ddd;
|
||||
span:first-child {
|
||||
background: rgba(112, 128, 144,0.6);
|
||||
}
|
||||
|
|
@ -782,7 +862,7 @@ $button-radius: 50px;
|
|||
height: 100%;
|
||||
z-index: 50;
|
||||
// background-color: rgba(0,0,0,0.4);
|
||||
background: rgba(255,255,255,0.3);
|
||||
background: rgba(255,255,255,0.75);
|
||||
// background-image: linear-gradient(0deg, transparent, rgba(1,1,1,1));
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
@ -811,7 +891,7 @@ $button-radius: 50px;
|
|||
height: 250px;
|
||||
// background: $main-bg-color-light;
|
||||
background: #fefefe;
|
||||
margin-top: 150px;
|
||||
margin-top: 30%;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 5px 15px rgba(0,0,0,0.5);
|
||||
|
||||
|
|
@ -974,6 +1054,7 @@ $button-radius: 50px;
|
|||
|
||||
#morseBufferDisplay {
|
||||
// border: 1px solid green;
|
||||
background: #eee;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column-reverse;
|
||||
|
|
@ -983,40 +1064,37 @@ $button-radius: 50px;
|
|||
margin-bottom: 20px;
|
||||
font-family: $buffer-font;
|
||||
position: relative;
|
||||
// font-weight: bold;
|
||||
// box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
// border-bottom: 2px solid rgba(0,0,0,0.1);
|
||||
|
||||
#overlay {
|
||||
// background: blue;
|
||||
box-shadow: inset 20px 0px 20px -5px $main-bg-color-light;
|
||||
box-shadow: inset 20px 0px 20px -5px #eee;
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
top:0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
left: calc(50% - 37.5%);
|
||||
width: 600px;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
#alphanumeric-container {
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
min-width: 300px;
|
||||
overflow: hidden;
|
||||
|
||||
display: inline-block;
|
||||
padding-top: 10px;
|
||||
// border: 1px solid red;
|
||||
// max-width: 100%;
|
||||
// min-width: 300px;
|
||||
text-align: center;
|
||||
max-width: 75%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
padding-top: 10px;
|
||||
|
||||
#alphanumeric {
|
||||
// border: 1px solid blue;
|
||||
background: #fdfdfd;
|
||||
|
||||
height: 5rem;
|
||||
width: 100%;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-top: 0.45rem;
|
||||
font-size: 4rem;
|
||||
min-width: 4rem;
|
||||
margin-bottom: 10px;
|
||||
border-radius: $main-border-radius;
|
||||
// box-shadow: $main-box-shadow-light;
|
||||
|
|
@ -1024,11 +1102,10 @@ $button-radius: 50px;
|
|||
}
|
||||
}
|
||||
#ditDahs-container {
|
||||
// display: flex;
|
||||
// justify-content: flex-start;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
// border: 1px solid red;
|
||||
text-align: center;
|
||||
max-width: 75%;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
|
||||
#ditDahs {
|
||||
|
|
@ -1203,9 +1280,9 @@ $button-radius: 50px;
|
|||
|
||||
#morseHistory-textbox {
|
||||
// border: 1px solid cyan;
|
||||
background: #ddd;
|
||||
background: #f8f8f8;
|
||||
border-radius: 5px;
|
||||
min-height: 2em;
|
||||
min-height: 4em;
|
||||
width: 80%;
|
||||
max-width: 500px;
|
||||
padding: 0.5em;
|
||||
|
|
|
|||
Loading…
Reference in a new issue