mirror of
https://github.com/genemecija/learn-morse-code.git
synced 2025-12-06 07:02:00 +01:00
Timeouts instead of promises, wpm progress, misc progress
This commit is contained in:
parent
90c9318bb4
commit
1d331a1d21
20
package-lock.json
generated
20
package-lock.json
generated
|
|
@ -4538,6 +4538,15 @@
|
|||
"utila": "~0.4"
|
||||
}
|
||||
},
|
||||
"dom-helpers": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz",
|
||||
"integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.6.3",
|
||||
"csstype": "^2.6.7"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
|
|
@ -11073,6 +11082,17 @@
|
|||
"workbox-webpack-plugin": "4.3.1"
|
||||
}
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz",
|
||||
"integrity": "sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"dom-helpers": "^5.0.1",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
"@testing-library/user-event": "^7.2.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-scripts": "3.3.0"
|
||||
"react-scripts": "3.3.0",
|
||||
"react-transition-group": "^4.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
|||
73
src/App.js
73
src/App.js
|
|
@ -12,12 +12,13 @@ import KeyTypePicker from './components/KeyTypePicker'
|
|||
import WordListPicker from './components/WordListPicker';
|
||||
|
||||
import PracticeMode from './app-modes/PracticeMode';
|
||||
import TimedMode from './app-modes/TimedMode'
|
||||
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 MorseBufferDisplay from './components/MorseBufferDisplay'
|
||||
import MorseHistory from './components/MorseHistory'
|
||||
|
|
@ -25,6 +26,7 @@ import MorseHistory from './components/MorseHistory'
|
|||
import StraightKey from './components/StraightKey';
|
||||
import ElectronicKey from './components/ElectronicKey';
|
||||
import Footer from './components/Footer';
|
||||
import { WPMContextProvider } from './contexts/wpmContext';
|
||||
|
||||
export default React.memo(function App() {
|
||||
|
||||
|
|
@ -32,39 +34,52 @@ export default React.memo(function App() {
|
|||
const {gameMode} = useContext(GameModeContext)
|
||||
|
||||
const {keyType} = useContext(KeyTypeContext)
|
||||
console.log('gameMode', gameMode);
|
||||
console.log('keyType', keyType);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<div id='main-content'>
|
||||
<Legend />
|
||||
<MorseBufferContextProvider>
|
||||
<ModePicker />
|
||||
<KeyTypePicker />
|
||||
{gameMode === 'practice' &&
|
||||
<>
|
||||
{keyType === "straight" ?
|
||||
<StraightKey gameMode='practice' /> : <ElectronicKey gameMode='practice' />}
|
||||
<PracticeMode /><br/>
|
||||
<MorseBufferDisplay /><br/>
|
||||
<MorseHistory /><br/>
|
||||
</>
|
||||
}
|
||||
{/* {gameMode === 'timed' && <TimedMode />} */}
|
||||
{gameMode === 'challenge' &&
|
||||
<>
|
||||
<WordListPickerContextProvider>
|
||||
<WordFeederContextProvider>
|
||||
<WordListPicker />
|
||||
{keyType === "straight" ?
|
||||
<StraightKey gameMode='challenge' /> : <ElectronicKey gameMode='challenge' />}
|
||||
<ChallengeMode />
|
||||
</WordFeederContextProvider>
|
||||
</WordListPickerContextProvider>
|
||||
</>
|
||||
}
|
||||
<MorseButtons />
|
||||
</MorseBufferContextProvider>
|
||||
<WPMContextProvider>
|
||||
<Legend />
|
||||
<WordsPerMinute />
|
||||
<MorseBufferContextProvider>
|
||||
<ModePicker />
|
||||
<KeyTypePicker />
|
||||
{gameMode === 'practice' &&
|
||||
<>
|
||||
{keyType === "straight" ?
|
||||
<StraightKey gameMode='practice' /> : <ElectronicKey gameMode='practice' />}
|
||||
<PracticeMode /><br/>
|
||||
<MorseBufferDisplay /><br/>
|
||||
<MorseHistory /><br/>
|
||||
</>
|
||||
}
|
||||
{gameMode === 'timed' &&
|
||||
<>
|
||||
{keyType === "straight" ?
|
||||
<StraightKey gameMode='training' /> : <ElectronicKey gameMode='training' />}
|
||||
<TrainingMode /><br/>
|
||||
<MorseBufferDisplay /><br/>
|
||||
<MorseHistory /><br/>
|
||||
</>
|
||||
}
|
||||
{gameMode === 'challenge' &&
|
||||
<>
|
||||
<WordListPickerContextProvider>
|
||||
<WordFeederContextProvider>
|
||||
<WordListPicker />
|
||||
{keyType === "straight" ?
|
||||
<StraightKey gameMode='challenge' /> : <ElectronicKey gameMode='challenge' />}
|
||||
<ChallengeMode />
|
||||
</WordFeederContextProvider>
|
||||
</WordListPickerContextProvider>
|
||||
</>
|
||||
}
|
||||
<MorseButtons />
|
||||
</MorseBufferContextProvider>
|
||||
</WPMContextProvider>
|
||||
</div>
|
||||
<Footer />
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import GameClock from '../components/GameClock'
|
|||
import MorseBufferDisplay from '../components/MorseBufferDisplay'
|
||||
import MorseHistory from '../components/MorseHistory'
|
||||
|
||||
function TimedMode() {
|
||||
function TrainingMode() {
|
||||
|
||||
const {morseCharBuffer, morseWords} = useStraightKey('timed')
|
||||
|
||||
console.log('TimedMode.js rendered')
|
||||
console.log('TrainingMode.js rendered')
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -21,4 +21,4 @@ function TimedMode() {
|
|||
|
||||
}
|
||||
|
||||
export default React.memo(TimedMode);
|
||||
export default React.memo(TrainingMode);
|
||||
|
|
@ -2,9 +2,7 @@ import React from "react"
|
|||
|
||||
function DitDahDisplay(props) {
|
||||
return (
|
||||
<div className={`ditDah ${props.className}`}>
|
||||
{props.dd}
|
||||
</div>
|
||||
<div className='ditDah'>{props.dd}</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ function Legend() {
|
|||
let newWord = convertWordToMorse(word)
|
||||
console.log(newWord);
|
||||
|
||||
playMorseWord(newWord)
|
||||
playMorseWord(newWord)
|
||||
}
|
||||
|
||||
function convertWordToMorse(word) {
|
||||
|
|
@ -37,6 +37,7 @@ function Legend() {
|
|||
{legend}
|
||||
<button id="test" onClick={handleClick}>Anya</button>
|
||||
<button id="test" onClick={handleClick}>Alexandra</button>
|
||||
<button id="test" onClick={handleClick}>Paris</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ function ModePicker() {
|
|||
<button id="practice" onClick={handleClick}>
|
||||
Practice
|
||||
</button>
|
||||
<button id="timed" onClick={handleClick}>
|
||||
Timed Mode
|
||||
<button id="training" onClick={handleClick}>
|
||||
Training Mode
|
||||
</button>
|
||||
<button id="challenge" onClick={handleClick}>
|
||||
Challenge Mode
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useContext } from "react"
|
||||
import React, { useContext, useEffect } from "react"
|
||||
import DitDahDisplay from "./DitDahDisplay"
|
||||
import morseCode from '../data/morse-reverse.json'
|
||||
import {MorseBufferContext} from "../contexts/morseBufferContext"
|
||||
|
|
|
|||
44
src/components/MorseHistory_textbox.js
Normal file
44
src/components/MorseHistory_textbox.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import React, {useContext, useState} from "react"
|
||||
// import MorseCard from './MorseCard'
|
||||
import morseCode from '../data/morse-reverse.json'
|
||||
import {MorseBufferContext} from "../contexts/morseBufferContext"
|
||||
|
||||
export default (function MorseHistory() {
|
||||
|
||||
const {morseWords} = useContext(MorseBufferContext)
|
||||
|
||||
let text = ''
|
||||
|
||||
console.log('morseWords', morseWords);
|
||||
|
||||
morseWords.forEach((word) => {
|
||||
if (word.includes(' ')) {
|
||||
let newWord = ''
|
||||
word.split(' ').forEach(letter => {
|
||||
if (morseCode[letter] === undefined) {
|
||||
newWord += '[?]'
|
||||
console.log('undefined', letter);
|
||||
} else {
|
||||
console.log('here1');
|
||||
newWord += morseCode[letter].toUpperCase()
|
||||
}
|
||||
})
|
||||
text = newWord + ' ' + text
|
||||
}
|
||||
else if (morseCode[word] === undefined) {
|
||||
text = '[?]' + text
|
||||
console.log('undefined', word);
|
||||
} else {
|
||||
console.log('here2');
|
||||
text = morseCode[word].toUpperCase() + ' ' + text
|
||||
}
|
||||
})
|
||||
|
||||
// try {
|
||||
// document.getElementById('morseHistory').innerText = text
|
||||
// } catch {}
|
||||
|
||||
return (
|
||||
<div id="morseHistory">{text}</div>
|
||||
)
|
||||
})
|
||||
16
src/components/WordsPerMinute.js
Normal file
16
src/components/WordsPerMinute.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React, {useContext} from "react"
|
||||
import { WPMContext } from "../contexts/wpmContext";
|
||||
|
||||
export default React.memo(function WordsPerMinute(props) {
|
||||
console.log('WordsPerMinute rendered');
|
||||
|
||||
const {wpm, setWPM} = useContext(WPMContext)
|
||||
|
||||
function handleChange(e) {
|
||||
setWPM(e.target.value)
|
||||
}
|
||||
|
||||
return (
|
||||
<input id='wpm-input' type='text' value={wpm} onChange={handleChange} />
|
||||
)
|
||||
})
|
||||
|
|
@ -8,5 +8,5 @@
|
|||
"normal": 24,
|
||||
"fast": 17
|
||||
},
|
||||
"historySize": 5
|
||||
"historySize": 10
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ const KeyTypeContext = React.createContext()
|
|||
|
||||
function KeyTypeContextProvider(props) {
|
||||
|
||||
const [keyType, setKeyType] = useState('')
|
||||
const [keyType, setKeyType] = useState('straight')
|
||||
|
||||
return (
|
||||
<KeyTypeContext.Provider value={{
|
||||
|
|
|
|||
14
src/contexts/wpmContext.js
Normal file
14
src/contexts/wpmContext.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import React, {useState} from "react"
|
||||
const WPMContext = React.createContext()
|
||||
|
||||
function WPMContextProvider(props) {
|
||||
const [wpm, setWPM] = useState(15)
|
||||
|
||||
return (
|
||||
<WPMContext.Provider value={{wpm: wpm, setWPM: setWPM}}>
|
||||
{props.children}
|
||||
</WPMContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export {WPMContextProvider, WPMContext}
|
||||
190
src/css/App.css
190
src/css/App.css
|
|
@ -8,7 +8,7 @@
|
|||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: #444;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
#root {
|
||||
|
|
@ -41,6 +41,9 @@ header {
|
|||
flex-direction: column;
|
||||
width: 95vw;
|
||||
border: 1px solid red;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mode-picker {
|
||||
|
|
@ -58,7 +61,7 @@ header {
|
|||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
border: 0px;
|
||||
border-radius: 0px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.mode-picker .selected {
|
||||
|
|
@ -74,9 +77,9 @@ header {
|
|||
-webkit-box-pack: space-evenly;
|
||||
-ms-flex-pack: space-evenly;
|
||||
justify-content: space-evenly;
|
||||
position: absolute;
|
||||
-ms-flex-item-align: left;
|
||||
align-self: left;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
|
@ -201,7 +204,123 @@ header {
|
|||
background: rgba(0, 200, 0, 0.7);
|
||||
}
|
||||
|
||||
#morseBufferDisplay, #challengeBufferDisplay {
|
||||
#morseBufferDisplay {
|
||||
border: 1px solid green;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: reverse;
|
||||
-ms-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container {
|
||||
background: #ccc;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
padding-left: 5px;
|
||||
height: 50px;
|
||||
min-width: 50px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric {
|
||||
font-size: 40px;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric:first-child {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric span {
|
||||
padding: 4px;
|
||||
-webkit-transition: background 300ms ease-in-out;
|
||||
transition: background 300ms ease-in-out;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs {
|
||||
width: 50%;
|
||||
height: 50px;
|
||||
padding-right: 5px;
|
||||
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: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
font-size: 25px;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs span {
|
||||
padding: 4px;
|
||||
-webkit-transition: background 100ms ease-in-out;
|
||||
transition: background 100ms ease-in-out;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs .ditDah {
|
||||
background: #DDD;
|
||||
height: 40px;
|
||||
width: 30px !important;
|
||||
margin-left: 3px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
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;
|
||||
opacity: 50%;
|
||||
-webkit-transition: all 100ms ease-in-out;
|
||||
transition: all 100ms ease-in-out;
|
||||
}
|
||||
|
||||
.example-appear {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
.example-appear.example-appear-active {
|
||||
opacity: 1;
|
||||
-webkit-transition: opacity .5s ease-in;
|
||||
transition: opacity .5s ease-in;
|
||||
}
|
||||
|
||||
#challengeBufferDisplay {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -217,10 +336,11 @@ header {
|
|||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container, #challengeBufferDisplay #alphanumeric-container {
|
||||
#challengeBufferDisplay #alphanumeric-container {
|
||||
padding-left: 5px;
|
||||
width: 50%;
|
||||
display: -webkit-box;
|
||||
|
|
@ -231,7 +351,7 @@ header {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric, #challengeBufferDisplay #alphanumeric-container #alphanumeric {
|
||||
#challengeBufferDisplay #alphanumeric-container #alphanumeric {
|
||||
font-size: 40px;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
|
|
@ -239,18 +359,18 @@ header {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric:first-child, #challengeBufferDisplay #alphanumeric-container #alphanumeric:first-child {
|
||||
#challengeBufferDisplay #alphanumeric-container #alphanumeric:first-child {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #alphanumeric-container #alphanumeric span, #challengeBufferDisplay #alphanumeric-container #alphanumeric span {
|
||||
#challengeBufferDisplay #alphanumeric-container #alphanumeric span {
|
||||
padding: 4px;
|
||||
-webkit-transition: background 300ms ease-in-out;
|
||||
transition: background 300ms ease-in-out;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs, #challengeBufferDisplay #ditDahs {
|
||||
#challengeBufferDisplay #ditDahs {
|
||||
width: 50%;
|
||||
padding-right: 5px;
|
||||
display: -webkit-box;
|
||||
|
|
@ -268,18 +388,17 @@ header {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs span, #challengeBufferDisplay #ditDahs span {
|
||||
#challengeBufferDisplay #ditDahs span {
|
||||
padding: 4px;
|
||||
-webkit-transition: background 100ms ease-in-out;
|
||||
transition: background 100ms ease-in-out;
|
||||
}
|
||||
|
||||
#morseBufferDisplay #ditDahs .ditDah, #challengeBufferDisplay #ditDahs .ditDah {
|
||||
background: #DDD;
|
||||
#challengeBufferDisplay #ditDahs .ditDah {
|
||||
height: 40px;
|
||||
width: 30px !important;
|
||||
margin-left: 3px;
|
||||
border-radius: 0px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
display: -webkit-box;
|
||||
|
|
@ -313,8 +432,7 @@ header {
|
|||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#morseDisplay {
|
||||
/* border: 1px solid blue; */
|
||||
#morseHistory {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
|
|
@ -324,23 +442,43 @@ header {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
#morseDisplay .morseCard:nth-child(1) {
|
||||
#morseHistory .morseCard:nth-child(1) {
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
#morseDisplay .morseCard:nth-child(2) {
|
||||
#morseHistory .morseCard:nth-child(2) {
|
||||
opacity: 90%;
|
||||
}
|
||||
|
||||
#morseHistory .morseCard:nth-child(3) {
|
||||
opacity: 80%;
|
||||
}
|
||||
|
||||
#morseHistory .morseCard:nth-child(4) {
|
||||
opacity: 70%;
|
||||
}
|
||||
|
||||
#morseDisplay .morseCard:nth-child(3) {
|
||||
#morseHistory .morseCard:nth-child(5) {
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
#morseHistory .morseCard:nth-child(6) {
|
||||
opacity: 50%;
|
||||
}
|
||||
|
||||
#morseDisplay .morseCard:nth-child(4) {
|
||||
#morseHistory .morseCard:nth-child(7) {
|
||||
opacity: 40%;
|
||||
}
|
||||
|
||||
#morseHistory .morseCard:nth-child(8) {
|
||||
opacity: 30%;
|
||||
}
|
||||
|
||||
#morseDisplay .morseCard:nth-child(5) {
|
||||
#morseHistory .morseCard:nth-child(9) {
|
||||
opacity: 20%;
|
||||
}
|
||||
|
||||
#morseHistory .morseCard:nth-child(10) {
|
||||
opacity: 10%;
|
||||
}
|
||||
|
||||
|
|
@ -357,9 +495,8 @@ header {
|
|||
justify-content: center;
|
||||
/* border: 1px solid orange; */
|
||||
margin-bottom: 2px;
|
||||
font-size: 2.5rem;
|
||||
font-size: 1.5rem;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
/* width: 100%; */
|
||||
}
|
||||
|
||||
|
|
@ -369,10 +506,10 @@ header {
|
|||
margin: 3px;
|
||||
background: #EEE;
|
||||
white-space: nowrap;
|
||||
border-radius: 0px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
line-height: 2rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.morseCard .ditDahs-container, .morseCard .alphanumeric-container {
|
||||
|
|
@ -380,6 +517,7 @@ header {
|
|||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
width: 50%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.morseCard .ditDahs-container {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,17 +1,19 @@
|
|||
import {useEffect, useContext} from 'react'
|
||||
import {MorseBufferContext} from '../contexts/morseBufferContext'
|
||||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext'
|
||||
|
||||
// ELECTRONIC KEY TELEGRAPH - Iambic A
|
||||
|
||||
function useElectronicKey(gameMode) {
|
||||
|
||||
const {morseCharBuffer, setMorseCharBuffer, morseWords, setMorseWords} = useContext(MorseBufferContext)
|
||||
const {wpm} = useContext(WPMContext)
|
||||
|
||||
const timingUnit = config.timingUnit
|
||||
|
||||
let ratio = .2
|
||||
const ditMaxTime = 70 // ditMaxTime * 0.365 to get ms, e.g. 85 * 0.365 ~= 31ms
|
||||
const ditMaxTime = 1200/wpm // ditMaxTime * 0.365 to get ms, e.g. 85 * 0.365 ~= 31ms
|
||||
|
||||
const letterGapMinTime = ditMaxTime*ratio*3 //config.practiceSpeed.normal*3
|
||||
const wordGapMaxTime = ditMaxTime*ratio*7 // config.practiceSpeed.normal*7
|
||||
|
|
@ -31,6 +33,8 @@ function useElectronicKey(gameMode) {
|
|||
// let gapTimerRunning = false
|
||||
let paddlesReleasedSimultaneously = false
|
||||
|
||||
let insideBufferDisplay = false
|
||||
|
||||
// function consoleLogVars() {
|
||||
// // Log variables (Debug tool)
|
||||
// console.log('<VARS>');
|
||||
|
|
@ -226,13 +230,30 @@ function useElectronicKey(gameMode) {
|
|||
}
|
||||
}
|
||||
|
||||
const bufferDisplay = ['morseBufferDisplay', 'challengeBufferDisplay', 'ditDahs', 'alphanumeric-container']
|
||||
|
||||
function handleInputStart(event) {
|
||||
event.preventDefault()
|
||||
|
||||
// if (event.keyCode === 71) {
|
||||
// queue = ['.',' ','.',' ','.',' ','.',' ','-','.','.','.','.','-']
|
||||
// executeQueue()
|
||||
// }
|
||||
console.log(event.target);
|
||||
if (event.type === 'mousedown' && event.target.className !== 'paddle') {
|
||||
if (bufferDisplay.includes(event.target.id)) {
|
||||
document.addEventListener('keydown', handleInputStart)
|
||||
document.addEventListener('keyup', handleInputEnd)
|
||||
insideBufferDisplay = true
|
||||
console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
} else {
|
||||
document.removeEventListener('keydown', handleInputStart)
|
||||
document.removeEventListener('keyup', handleInputEnd)
|
||||
insideBufferDisplay = false
|
||||
console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
if (event.target.id === 'wpm-input') {
|
||||
event.target.focus()
|
||||
} else {
|
||||
document.activeElement.blur()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paddlesReleasedSimultaneously = false
|
||||
|
||||
|
|
@ -261,6 +282,8 @@ function useElectronicKey(gameMode) {
|
|||
function handleInputEnd(event) {
|
||||
event.preventDefault()
|
||||
|
||||
if (!insideBufferDisplay) {return}
|
||||
|
||||
if (event.keyCode === 188 || event.target.id === "left") {
|
||||
leftIsPressed = false
|
||||
|
||||
|
|
@ -320,6 +343,7 @@ function useElectronicKey(gameMode) {
|
|||
useEffect(() => {
|
||||
document.addEventListener('keydown', handleInputStart)
|
||||
document.addEventListener('keyup', handleInputEnd)
|
||||
document.addEventListener('mousedown', handleInputStart)
|
||||
|
||||
const paddles = document.querySelectorAll('.paddle')
|
||||
paddles.forEach(paddle => {
|
||||
|
|
@ -333,6 +357,7 @@ function useElectronicKey(gameMode) {
|
|||
return function cleanup() {
|
||||
document.removeEventListener('keydown', handleInputStart)
|
||||
document.removeEventListener('keyup', handleInputEnd)
|
||||
document.removeEventListener('mousedown', handleInputStart)
|
||||
|
||||
const paddles = document.querySelectorAll('.paddle')
|
||||
paddles.forEach(paddle => {
|
||||
|
|
|
|||
84
src/hooks/useMorsePlayer copy.js
Normal file
84
src/hooks/useMorsePlayer copy.js
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import config from '../config.json'
|
||||
|
||||
function useMorsePlayer() {
|
||||
|
||||
const ditMaxTime = 85 //config.ditMaxTime
|
||||
|
||||
// Tone Setup
|
||||
let AudioContext = window.AudioContext || window.webkitAudioContext
|
||||
window.AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||
let context
|
||||
if (AudioContext) {
|
||||
context = new AudioContext()
|
||||
} else {
|
||||
context = null
|
||||
}
|
||||
|
||||
let frequency = config.frequency
|
||||
|
||||
function play(ditDah) {
|
||||
let length = ((ditDah === '.') ? ditMaxTime : ditMaxTime*3)
|
||||
// length = 1
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (context.state === 'interrupted') {
|
||||
context.resume()
|
||||
}
|
||||
let o
|
||||
o = context.createOscillator()
|
||||
o.frequency.value = frequency
|
||||
o.type = "sine"
|
||||
o.onended = () => {
|
||||
resolve()
|
||||
}
|
||||
|
||||
let startTime = context.currentTime;
|
||||
|
||||
let g = context.createGain()
|
||||
g.gain.exponentialRampToValueAtTime(config.mainVolume, startTime)
|
||||
g.gain.setValueAtTime(config.mainVolume, startTime)
|
||||
o.connect(g)
|
||||
g.connect(context.destination)
|
||||
o.start(startTime)
|
||||
|
||||
// g.gain.setTargetAtTime(0.0001, startTime + length/1000, 0.001)
|
||||
// o.stop(startTime + length/1000 + 0.05)
|
||||
setTimeout(() => {
|
||||
g.gain.setTargetAtTime(0.0001, context.currentTime, 0.009)
|
||||
o.stop(context.currentTime + 0.05)
|
||||
}, length)
|
||||
})
|
||||
}
|
||||
|
||||
function playMorseWord(morse) {
|
||||
let chars = Array.from(morse)
|
||||
let currentPromise = Promise.resolve();
|
||||
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
currentPromise = currentPromise.then(() => {
|
||||
return playChar(chars[i]);
|
||||
});
|
||||
}
|
||||
|
||||
function playChar(char) {
|
||||
let delay = (char === '.') ? ditMaxTime + ditMaxTime : ditMaxTime*3 + ditMaxTime
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
if (char === '.' || char === '-') {
|
||||
play(char)
|
||||
.then(setTimeout(() => {
|
||||
resolve();
|
||||
}, delay))
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, delay)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { playMorseWord }
|
||||
}
|
||||
|
||||
export default useMorsePlayer
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext.js';
|
||||
import { useContext } from 'react';
|
||||
|
||||
function useMorsePlayer() {
|
||||
|
||||
const ditMaxTime = 85 //config.ditMaxTime
|
||||
const {wpm} = useContext(WPMContext)
|
||||
// const ditMaxTime = 85 //config.ditMaxTime
|
||||
const ditMaxTime = 1200/wpm
|
||||
|
||||
// Tone Setup
|
||||
let AudioContext = window.AudioContext || window.webkitAudioContext
|
||||
|
|
@ -20,44 +24,87 @@ function useMorsePlayer() {
|
|||
let length = ((ditDah === '.') ? ditMaxTime : ditMaxTime*3)
|
||||
// length = 1
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (context.state === 'interrupted') {
|
||||
context.resume()
|
||||
}
|
||||
let o
|
||||
o = context.createOscillator()
|
||||
o.frequency.value = frequency
|
||||
o.type = "sine"
|
||||
o.onended = () => {
|
||||
resolve()
|
||||
}
|
||||
|
||||
let startTime = context.currentTime;
|
||||
|
||||
let g = context.createGain()
|
||||
g.gain.exponentialRampToValueAtTime(config.mainVolume, startTime)
|
||||
g.gain.setValueAtTime(config.mainVolume, startTime)
|
||||
o.connect(g)
|
||||
g.connect(context.destination)
|
||||
o.start(startTime)
|
||||
|
||||
// g.gain.setTargetAtTime(0.0001, startTime + length/1000, 0.001)
|
||||
// o.stop(startTime + length/1000 + 0.05)
|
||||
setTimeout(() => {
|
||||
g.gain.setTargetAtTime(0.0001, context.currentTime, 0.009)
|
||||
o.stop(context.currentTime + 0.05)
|
||||
}, length)
|
||||
})
|
||||
// return new Promise((resolve, reject) => {
|
||||
if (context.state === 'interrupted') {
|
||||
context.resume()
|
||||
}
|
||||
let o
|
||||
o = context.createOscillator()
|
||||
o.frequency.value = frequency
|
||||
o.type = "sine"
|
||||
// o.onended = () => {
|
||||
// resolve()
|
||||
// }
|
||||
|
||||
let startTime = context.currentTime;
|
||||
|
||||
let g = context.createGain()
|
||||
g.gain.exponentialRampToValueAtTime(config.mainVolume, startTime)
|
||||
g.gain.setValueAtTime(config.mainVolume, startTime)
|
||||
o.connect(g)
|
||||
g.connect(context.destination)
|
||||
o.start(startTime)
|
||||
|
||||
// g.gain.setTargetAtTime(0.0001, startTime + length/1000, 0.001)
|
||||
// o.stop(startTime + length/1000 + 0.05)
|
||||
setTimeout(() => {
|
||||
g.gain.setTargetAtTime(0.0001, context.currentTime, 0.009)
|
||||
o.stop(context.currentTime + 0.05)
|
||||
}, length)
|
||||
// })
|
||||
}
|
||||
|
||||
function playMorseWord(morse) {
|
||||
let chars = Array.from(morse)
|
||||
let currentPromise = Promise.resolve();
|
||||
// let currentPromise = Promise.resolve();
|
||||
|
||||
let soundQueue = []
|
||||
|
||||
let delay = 0
|
||||
let firstWord = true
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
currentPromise = currentPromise.then(() => {
|
||||
return playChar(chars[i]);
|
||||
});
|
||||
// currentPromise = currentPromise.then(() => {
|
||||
// return playChar(chars[i]);
|
||||
// });
|
||||
let char = chars[i]
|
||||
if (char === '.') {
|
||||
if (firstWord) {
|
||||
firstWord = false
|
||||
// soundQueue.push(
|
||||
setTimeout(() => {
|
||||
play(char)
|
||||
}, 0)
|
||||
// )
|
||||
} else {
|
||||
// soundQueue.push(
|
||||
setTimeout(() => {
|
||||
play(char)
|
||||
}, delay)
|
||||
// )
|
||||
}
|
||||
delay += ditMaxTime*2
|
||||
} else if (char === '-') {
|
||||
if (firstWord) {
|
||||
firstWord = false
|
||||
// soundQueue.push(
|
||||
setTimeout(() => {
|
||||
play(char)
|
||||
}, 0)
|
||||
// )
|
||||
} else {
|
||||
// soundQueue.push(
|
||||
setTimeout(() => {
|
||||
play(char)
|
||||
}, delay)
|
||||
// )
|
||||
}
|
||||
delay += ditMaxTime*4
|
||||
} else if (char === ' ') {
|
||||
setTimeout(() => {
|
||||
|
||||
}, delay)
|
||||
delay += ditMaxTime*3
|
||||
}
|
||||
}
|
||||
|
||||
function playChar(char) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import {useEffect, useContext} from 'react'
|
||||
import {MorseBufferContext} from '../contexts/morseBufferContext'
|
||||
import config from '../config.json'
|
||||
import { WPMContext } from '../contexts/wpmContext'
|
||||
|
||||
// STRAIGHT KEY TELEGRAPH
|
||||
function useStraightKey(gameMode) {
|
||||
|
||||
const {morseCharBuffer, setMorseCharBuffer, morseWords, setMorseWords} = useContext(MorseBufferContext)
|
||||
const {wpm} = useContext(WPMContext)
|
||||
|
||||
let charTimer = 0
|
||||
let charTime = 0
|
||||
|
|
@ -14,10 +16,12 @@ function useStraightKey(gameMode) {
|
|||
|
||||
const timingUnit = config.timingUnit
|
||||
|
||||
const ditMaxTime = config.practiceSpeed.normal
|
||||
const ditMaxTime = 1200/wpm
|
||||
const letterGapMinTime = ditMaxTime*3
|
||||
const wordGapMaxTime = ditMaxTime*7
|
||||
const morseHistorySize = config.historySize
|
||||
|
||||
let insideBufferDisplay = false
|
||||
|
||||
// Tone Setup
|
||||
let AudioContext = window.AudioContext || window.webkitAudioContext || false
|
||||
|
|
@ -39,12 +43,36 @@ function useStraightKey(gameMode) {
|
|||
setMorseWords([])
|
||||
}
|
||||
|
||||
const bufferDisplay = ['morseBufferDisplay', 'challengeBufferDisplay', 'ditDahs', 'alphanumeric-container']
|
||||
|
||||
function handleInputStart(event) {
|
||||
event.preventDefault()
|
||||
|
||||
console.log(event.target);
|
||||
if (event.type === 'mousedown' && event.target.className !== 'paddle') {
|
||||
if (bufferDisplay.includes(event.target.id)) {
|
||||
document.addEventListener('keydown', handleInputStart)
|
||||
document.addEventListener('keyup', handleInputEnd)
|
||||
insideBufferDisplay = true
|
||||
console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
} else {
|
||||
document.removeEventListener('keydown', handleInputStart)
|
||||
document.removeEventListener('keyup', handleInputEnd)
|
||||
insideBufferDisplay = false
|
||||
console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
if (event.target.id === 'wpm-input') {
|
||||
event.target.focus()
|
||||
} else {
|
||||
document.activeElement.blur()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isRunning) {
|
||||
console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
return
|
||||
} else {
|
||||
} else if (insideBufferDisplay === true) {
|
||||
if ((event.keyCode !== 32 &&
|
||||
event.target.id !== "morseButton" &&
|
||||
event.target.className !== "paddle") ||
|
||||
|
|
@ -72,6 +100,8 @@ function useStraightKey(gameMode) {
|
|||
clearInterval(gapTimer)
|
||||
|
||||
startCharTimer()
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -86,6 +116,12 @@ function useStraightKey(gameMode) {
|
|||
function handleInputEnd(event) {
|
||||
event.preventDefault()
|
||||
|
||||
// if (event.target.id !== 'morseBufferDisplay') {
|
||||
// insideBufferDisplay = true
|
||||
// console.log('insideBufferDisplay', insideBufferDisplay);
|
||||
// }
|
||||
if (!insideBufferDisplay) {return}
|
||||
|
||||
if (isRunning) {
|
||||
if ((event.keyCode !== 32 &&
|
||||
event.target.id !== "morseButton" &&
|
||||
|
|
@ -153,9 +189,15 @@ function useStraightKey(gameMode) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
// const buffer = document.getElementById('morseBufferDisplay')
|
||||
// document.addEventListener('mousedown', morseOn)
|
||||
// document.addEventListener('mousedown', morseOff)
|
||||
|
||||
document.addEventListener('keydown', handleInputStart)
|
||||
document.addEventListener('keyup', handleInputEnd)
|
||||
document.addEventListener('mousedown', handleInputStart)
|
||||
|
||||
const paddles = document.querySelectorAll('.paddle')
|
||||
paddles.forEach(paddle => {
|
||||
|
|
@ -167,8 +209,13 @@ function useStraightKey(gameMode) {
|
|||
})
|
||||
|
||||
return function cleanup() {
|
||||
// const buffer = document.getElementById('morseBufferDisplay')
|
||||
// document.removeEventListener('mousedown', morseOn)
|
||||
// document.removeEventListener('mousedown', morseOff)
|
||||
|
||||
document.removeEventListener('keydown', handleInputStart)
|
||||
document.removeEventListener('keyup', handleInputEnd)
|
||||
document.removeEventListener('mouseUp', handleInputStart)
|
||||
|
||||
const paddles = document.querySelectorAll('.paddle')
|
||||
paddles.forEach(paddle => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
$main-bg-color: #FFF;
|
||||
$main-box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
||||
$main-border-radius: 0px;
|
||||
$main-border-radius: 5px;
|
||||
$border-radius-neumorphic: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.15);
|
||||
$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);
|
||||
* {
|
||||
|
|
@ -11,8 +11,8 @@ $border-radius-neumorphic-active: 0 15px 20px rgba(0, 0, 0, 0.015), inset 0px -2
|
|||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
// background: $main-bg-color;
|
||||
background: #444;
|
||||
background: $main-bg-color;
|
||||
// background: #444;
|
||||
}
|
||||
#root {
|
||||
height: 100%;
|
||||
|
|
@ -31,6 +31,7 @@ header {
|
|||
flex-direction: column;
|
||||
width: 95vw;
|
||||
border: 1px solid red;
|
||||
align-items: center;
|
||||
}
|
||||
footer {
|
||||
|
||||
|
|
@ -56,8 +57,9 @@ footer {
|
|||
width: 450px;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
position: absolute;
|
||||
align-self: left;
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
div {
|
||||
|
|
@ -158,14 +160,103 @@ footer {
|
|||
|
||||
|
||||
|
||||
#morseBufferDisplay, #challengeBufferDisplay {
|
||||
#morseBufferDisplay {
|
||||
border: 1px solid green;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
#alphanumeric-container {
|
||||
// border-left: 2px solid #000;
|
||||
background: #ccc;
|
||||
display: flex;
|
||||
padding-left: 5px;
|
||||
height: 50px;
|
||||
min-width: 50px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
box-shadow: $main-box-shadow;
|
||||
|
||||
#alphanumeric {
|
||||
font-size: 40px;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
|
||||
|
||||
&:first-child {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
// box-shadow: $main-box-shadow;
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 4px;
|
||||
transition: background 300ms ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ditDahs {
|
||||
width: 50%;
|
||||
height: 50px;
|
||||
padding-right: 5px;
|
||||
// border-right: 2px solid #000;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
font-size: 25px;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
padding: 4px;
|
||||
transition: background 100ms ease-in-out;
|
||||
}
|
||||
|
||||
.ditDah {
|
||||
background: #DDD;
|
||||
height: 40px;
|
||||
width: 30px !important;
|
||||
margin-left: 3px;
|
||||
// box-shadow: 0px 1px 0px #000;
|
||||
border-radius: $main-border-radius;
|
||||
box-shadow: $main-box-shadow;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
opacity: 50%;
|
||||
transition: all 100ms ease-in-out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.example-appear {
|
||||
opacity: 0.01;
|
||||
}
|
||||
|
||||
.example-appear.example-appear-active {
|
||||
opacity: 1;
|
||||
transition: opacity .5s ease-in;
|
||||
}
|
||||
|
||||
#challengeBufferDisplay {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border: 1px solid green;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
// height: 40px;
|
||||
height: 150px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
#alphanumeric-container {
|
||||
|
|
@ -210,9 +301,9 @@ footer {
|
|||
padding: 4px;
|
||||
transition: background 100ms ease-in-out;
|
||||
}
|
||||
|
||||
.ditDah {
|
||||
background: #DDD;
|
||||
// background: #DDD;
|
||||
|
||||
height: 40px;
|
||||
width: 30px !important;
|
||||
margin-left: 3px;
|
||||
|
|
@ -222,7 +313,6 @@ footer {
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -246,8 +336,16 @@ footer {
|
|||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#morseDisplay {
|
||||
/* border: 1px solid blue; */
|
||||
// #morseHistory {
|
||||
// border: 1px solid purple;
|
||||
// padding: 5px;
|
||||
// width: 650px;
|
||||
// font-family: 'Verdana';
|
||||
// font-size: 1.5em;
|
||||
// }
|
||||
|
||||
#morseHistory {
|
||||
// /* border: 1px solid blue; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
|
|
@ -255,15 +353,30 @@ footer {
|
|||
opacity: 100%;
|
||||
}
|
||||
.morseCard:nth-child(2){
|
||||
opacity: 70%;
|
||||
opacity: 90%;
|
||||
}
|
||||
.morseCard:nth-child(3){
|
||||
opacity: 50%;
|
||||
opacity: 80%;
|
||||
}
|
||||
.morseCard:nth-child(4){
|
||||
opacity: 30%;
|
||||
opacity: 70%;
|
||||
}
|
||||
.morseCard:nth-child(5){
|
||||
opacity: 60%;
|
||||
}
|
||||
.morseCard:nth-child(6){
|
||||
opacity: 50%;
|
||||
}
|
||||
.morseCard:nth-child(7){
|
||||
opacity: 40%;
|
||||
}
|
||||
.morseCard:nth-child(8){
|
||||
opacity: 30%;
|
||||
}
|
||||
.morseCard:nth-child(9){
|
||||
opacity: 20%;
|
||||
}
|
||||
.morseCard:nth-child(10){
|
||||
opacity: 10%;
|
||||
}
|
||||
}
|
||||
|
|
@ -274,9 +387,8 @@ footer {
|
|||
justify-content: center;
|
||||
/* border: 1px solid orange; */
|
||||
margin-bottom: 2px;
|
||||
font-size: 2.5rem;
|
||||
font-size: 1.5rem;
|
||||
font-family: 'Courier';
|
||||
font-weight: bold;
|
||||
/* width: 100%; */
|
||||
|
||||
|
||||
|
|
@ -290,11 +402,12 @@ footer {
|
|||
white-space: nowrap;
|
||||
border-radius: $main-border-radius;
|
||||
box-shadow: $main-box-shadow;
|
||||
line-height: 2rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
.ditDahs-container, .alphanumeric-container {
|
||||
display: flex;
|
||||
width: 50%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ditDahs-container {
|
||||
justify-content: flex-end;
|
||||
|
|
|
|||
Loading…
Reference in a new issue