diff --git a/src/app-modes/ChallengeMode.js b/src/app-modes/ChallengeMode.js
index bbac29b..7490f85 100644
--- a/src/app-modes/ChallengeMode.js
+++ b/src/app-modes/ChallengeMode.js
@@ -1,17 +1,57 @@
import React from 'react';
import '../css/App.css';
+import morseCode from '../data/morse-reverse.json'
import useTelegraph from '../hooks/useTelegraph';
// import ChallengeWord from '../components/ChallengeWord'
// import MorseBufferDisplay from '../components/MorseBufferDisplay'
-import ChallengeDisplay from '../components/ChallengeDisplay';
+// import ChallengeDisplay from '../components/ChallengeDisplay';
+import ChallengeBufferDisplay from '../components/ChallengeBufferDisplay';
function ChallengeMode() {
- const {morseCharBuffer, setMorseCharBuffer} = useTelegraph('challenge')
+ let word = "morse"
+ const {morseCharBuffer} = useTelegraph('challenge')
+ // console.log('morseCharBuffer:', morseCharBuffer, '|END');
+ let morseLetters = morseCharBuffer.split('_').filter(l => l !== '')
+ // console.log('morseLetters:', morseLetters, morseLetters.length);
+ let challengeLetters = word.split('')
+ let correctIndexes = []
+ let incorrectIndex = null
+
+ morseLetters.forEach((morseLetter, index) => {
+ let morseAlpha = morseCode[morseLetter]
+ let challengeLetter = challengeLetters[index].toLowerCase()
+
+ if (morseAlpha === challengeLetter) {
+ correctIndexes.push(index)
+ // console.log('MATCH', correctIndexes);
+ }
+ else {
+ if (morseCharBuffer.slice(-1) === "_") {
+ incorrectIndex = index
+ // console.log('MISMATCH:', incorrectIndex, 'should be', challengeLetter, 'instead of', morseAlpha, '>', morseLetter);
+ // props.setMorseCharBuffer(morseLetters.slice(0,-1).join('_') + '_')
+ }
+ }
+ })
+
+ let spannedWord = challengeLetters.map((letter,index) => {
+ // console.log('correctIndexes',correctIndexes);
+ // console.log('index',index);
+ let className = 'cLetter'
+ className += (correctIndexes.includes(index)) ? ' correct' : ''
+ className += (incorrectIndex === index) ? ' morseError' : ''
+ return (
+ {letter}
+ )
+ })
+
+
return (
<>
-
+ {spannedWord}
+
>
);
diff --git a/src/app-modes/PracticeMode.js b/src/app-modes/PracticeMode.js
index 843dd10..187581f 100644
--- a/src/app-modes/PracticeMode.js
+++ b/src/app-modes/PracticeMode.js
@@ -7,7 +7,7 @@ import MorseDisplay from '../components/MorseDisplay'
function PracticeMode() {
const {morseCharBuffer, morseWords, clearHistory} = useTelegraph('practice')
-
+
return (
<>
diff --git a/src/components/ChallengeBufferDisplay.js b/src/components/ChallengeBufferDisplay.js
index f423eee..4c53f75 100644
--- a/src/components/ChallengeBufferDisplay.js
+++ b/src/components/ChallengeBufferDisplay.js
@@ -3,32 +3,45 @@ import DitDahDisplay from "./DitDahDisplay"
import morseCode from '../data/morse-reverse.json'
function ChallengeBufferDisplay(props) {
-
+ // INCREMENTING COUNTER TO MONITOR COMPONENT RELOADING
+ // console.log('ChallengeMode')
+ if (!document.getElementById('counter')) {
+ let counter = document.createElement('h1')
+ let holder = document.createElement('h3')
+ counter.id = 'counter'
+ holder.id = 'holder'
+ counter.innerText = "0"
+ document.querySelector('#main-content').appendChild(counter)
+ document.querySelector('#main-content').appendChild(holder)
+ } else {
+ let num = document.getElementById('counter').innerText
+ document.getElementById('counter').innerText = Number(num) + 1
+ document.getElementById('holder').innerText = props.buffer
+
+ }
+ //
+
let ditDahs = []
let incorrectIndex = props.incorrectIndex
let morseLetters = props.buffer.split(' ')
if (incorrectIndex) {
- console.log('incorrectIndex:', incorrectIndex);
+
for (let i in morseLetters) {
let letter = morseLetters[i]
if (Number(i) === incorrectIndex) {
ditDahs.push(letter.split('').map((ditdah,index) => ))
} else {
- console.log('i === incorrectIndex', i, incorrectIndex);
ditDahs.push(letter.split('').map((ditdah,index) => ))
}
}
} else {
ditDahs = props.buffer.split('').map((ditdah,index) => )
- console.log('ditDahs:', typeof ditDahs, ditDahs.length, ditDahs);
}
let alphanumeric = ''
- // if (props.buffer.includes(' ')) {
-
let letters = props.buffer.split(' ')
if (props.buffer === '') {}
diff --git a/src/hooks/useTelegraph.js b/src/hooks/useTelegraph.js
index 6483439..36625c5 100644
--- a/src/hooks/useTelegraph.js
+++ b/src/hooks/useTelegraph.js
@@ -29,36 +29,49 @@ function useTelegraph(mode = 'practice') {
let o
let frequency = 550.0
+
+ let isRunning = false
function clearHistory() {
setMorseWords([])
}
function handleInputStart(event) {
-
event.preventDefault()
- if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
- (event.repeat)) {
- return
- }
- if (context.state === 'interrupted') {
- context.resume()
- }
-
- o = context.createOscillator()
- o.frequency.value = frequency
- o.type = "sine"
-
- let g = context.createGain()
- g.gain.exponentialRampToValueAtTime(0.08, context.currentTime)
- o.connect(g)
- g.connect(context.destination)
- o.start()
-
- checkGapBetweenInputs()
- clearInterval(gapTimer)
- startCharTimer()
+ if (isRunning) {
+ console.log("isRunning True:", isRunning);
+ return
+ } else {
+ console.log("isRunning False:", isRunning);
+ isRunning = true
+
+ // TODO:
+ // Make sure only one touchdown event registered at a time
+ if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
+ (event.repeat)) {
+ return
+ }
+ if (context.state === 'interrupted') {
+ context.resume()
+ }
+
+ o = context.createOscillator()
+ o.frequency.value = frequency
+ o.type = "sine"
+
+ let g = context.createGain()
+ g.gain.exponentialRampToValueAtTime(0.08, context.currentTime)
+ o.connect(g)
+ g.connect(context.destination)
+ o.start()
+
+ checkGapBetweenInputs()
+ clearInterval(gapTimer)
+
+ startCharTimer()
+ }
+
}
function startCharTimer() {
// Reset character time
@@ -71,20 +84,25 @@ function useTelegraph(mode = 'practice') {
function handleInputEnd(event) {
event.preventDefault()
- if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
- (event.repeat)) {
- return
- }
- if (charTime <= ditMaxTime) {
- setMorseCharBuffer(prev => prev + '.')
- } else {
- setMorseCharBuffer(prev => prev + '-')
- }
-
- stopCharTimer()
- startGapTimer()
- o.stop()
+ if (isRunning) {
+ isRunning = false
+ if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
+ (event.repeat)) {
+ return
+ }
+
+ if (charTime <= ditMaxTime) {
+ setMorseCharBuffer(prev => prev + '.')
+ } else {
+ setMorseCharBuffer(prev => prev + '-')
+ }
+
+ stopCharTimer()
+ startGapTimer()
+ console.log("o.context.state:", o.context.state);
+ if (o.context.state === 'running') {o.stop()}
+ } else { return }
}
function stopCharTimer() {
diff --git a/src/hooks/useTelegraph_baseline.js b/src/hooks/useTelegraph_baseline.js
new file mode 100644
index 0000000..6483439
--- /dev/null
+++ b/src/hooks/useTelegraph_baseline.js
@@ -0,0 +1,173 @@
+import {useState, useEffect} from 'react'
+
+function useTelegraph(mode = 'practice') {
+
+ const [morseCharBuffer, setMorseCharBuffer] = useState('') // e.g. '-..'
+ const [morseWords, setMorseWords] = useState([]) // e.g. [['-..','.','-,'], ['...','---','...']]
+
+ let charTimer = 0
+ let charTime = 0
+ let gapTimer = 0
+ let gapTime = 0
+
+ const timingUnit = 15 // default: 25
+
+ const ditMaxTime = 5 // default: 3
+ const letterGapMinTime = ditMaxTime*3
+ const wordGapMaxTime = ditMaxTime*7
+ const morseHistorySize = 5
+
+ // Tone Setup
+ let AudioContext = window.AudioContext || window.webkitAudioContext || false
+ let context
+ window.AudioContext = window.AudioContext || window.webkitAudioContext;
+ if (AudioContext) {
+ context = new AudioContext()
+ } else {
+ context = null
+ }
+
+ let o
+ let frequency = 550.0
+
+ function clearHistory() {
+ setMorseWords([])
+ }
+
+ function handleInputStart(event) {
+
+ event.preventDefault()
+ if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
+ (event.repeat)) {
+ return
+ }
+ if (context.state === 'interrupted') {
+ context.resume()
+ }
+
+ o = context.createOscillator()
+ o.frequency.value = frequency
+ o.type = "sine"
+
+ let g = context.createGain()
+ g.gain.exponentialRampToValueAtTime(0.08, context.currentTime)
+ o.connect(g)
+ g.connect(context.destination)
+ o.start()
+
+ checkGapBetweenInputs()
+ clearInterval(gapTimer)
+
+ startCharTimer()
+ }
+ function startCharTimer() {
+ // Reset character time
+ charTime = 0
+ // Start Character Timer
+ charTimer = setInterval(() => {
+ charTime += 1
+ }, timingUnit);
+ }
+
+ function handleInputEnd(event) {
+ event.preventDefault()
+ if ((event.keyCode !== 32 && event.target.id !== "morseButton") ||
+ (event.repeat)) {
+ return
+ }
+
+ if (charTime <= ditMaxTime) {
+ setMorseCharBuffer(prev => prev + '.')
+ } else {
+ setMorseCharBuffer(prev => prev + '-')
+ }
+
+ stopCharTimer()
+ startGapTimer()
+ o.stop()
+ }
+
+ function stopCharTimer() {
+ clearInterval(charTimer)
+ charTimer = 0
+ }
+
+ function startGapTimer() {
+ gapTime = 0
+ gapTimer = setInterval(() => {
+ gapTime += 1
+
+ // Gap between words
+ if (mode === 'practice' && gapTime >= wordGapMaxTime) {
+ setMorseCharBuffer(prev => prev + '/')
+ clearInterval(gapTimer)
+ gapTimer = 0
+ gapTime = 0
+ }
+ if (mode === 'challenge' && gapTime >= letterGapMinTime) {
+ setMorseCharBuffer(prev => prev + '_')
+ clearInterval(gapTimer)
+ gapTimer = 0
+ gapTime = 0
+ }
+ }, timingUnit);
+ }
+
+ function checkGapBetweenInputs() {
+ // Check Gap between letters
+
+ if (gapTime >= letterGapMinTime && gapTime < wordGapMaxTime) {
+ if (mode === 'practice') {
+ setMorseCharBuffer(prev => prev + ' ')
+ } else if (mode === 'challenge') {
+ setMorseCharBuffer(prev => prev + '_')
+ }
+ clearInterval(gapTimer)
+ gapTimer = 0
+ }
+ }
+
+ useEffect(() => {
+ document.addEventListener('keydown', handleInputStart)
+ document.addEventListener('keyup', handleInputEnd)
+
+ const morseButton = document.getElementById('morseButton')
+ morseButton.addEventListener('mousedown', handleInputStart)
+ morseButton.addEventListener('touchstart', handleInputStart)
+ morseButton.addEventListener('mouseup', handleInputEnd)
+ morseButton.addEventListener('touchend', handleInputEnd)
+
+ return function cleanup() {
+ document.removeEventListener('keydown', handleInputStart)
+ document.removeEventListener('keyup', handleInputEnd)
+ clearHistory()
+ }
+ // eslint-disable-next-line
+ }, [])
+
+ useEffect(() => {
+ // PRACTICE MODE
+ if (morseCharBuffer.slice(-1) === '/' && mode === 'practice') {
+ // Remove forward slash
+ let val = morseCharBuffer.slice(0,morseCharBuffer.length-1)
+
+ setMorseWords(prev => [val, ...prev])
+
+ if (morseWords.length >= morseHistorySize) {
+ setMorseWords(prev => prev.slice(0,prev.length-1))
+ }
+ setMorseCharBuffer('')
+ }
+ console.log('morseCharBuffer:', morseCharBuffer, '|');
+ // CHALLENGE MODE: leave forward slash there; to be parsed by ChallengeDisplay.js
+ // else if (morseCharBuffer.slice(-1) === '/' && mode === 'challenge') {
+
+ // }
+
+ // eslint-disable-next-line
+ }, [morseCharBuffer])
+
+ return {morseCharBuffer, morseWords, clearHistory, setMorseCharBuffer, setMorseWords}
+}
+
+export default useTelegraph
\ No newline at end of file