forked from FOSS/BangleApps
feat: add morse code teacher
parent
35d42f590d
commit
a3bd3f0504
12
apps.json
12
apps.json
|
@ -384,6 +384,18 @@
|
|||
{"name":"*hrings","url":"hypno-rings-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "morse",
|
||||
"name": "Morse Code",
|
||||
"icon": "morse-code.png",
|
||||
"description": "Learn morse code by hearing/seeing/feeling the code. Tap to toggle buzz!",
|
||||
"tags": "morse,sound,visual,input",
|
||||
"type":"app",
|
||||
"storage": [
|
||||
{"name":"+morse","url":"morse-code.json"},
|
||||
{"name":"-morse","url":"morse-code.js"},
|
||||
{"name":"*morse","url":"morse-code-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "blescan",
|
||||
"name": "BLE Scanner",
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* Teach a user morse code
|
||||
*/
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
const FONT_NAME = 'Vector12';
|
||||
const FONT_SIZE = 80;
|
||||
const SCREEN_PIXELS = 240;
|
||||
const UNIT = 100;
|
||||
const MORSE_MAP = {
|
||||
A: '.-',
|
||||
B: '-...',
|
||||
C: '-.-.',
|
||||
D: '-..',
|
||||
E: '.',
|
||||
F: '..-.',
|
||||
G: '--.',
|
||||
H: '....',
|
||||
I: '..',
|
||||
J: '.---',
|
||||
K: '-.-',
|
||||
L: '.-..',
|
||||
M: '--',
|
||||
N: '-.',
|
||||
O: '---',
|
||||
P: '.--.',
|
||||
Q: '--.-',
|
||||
R: '.-.',
|
||||
S: '...',
|
||||
T: '-',
|
||||
U: '..-',
|
||||
V: '...-',
|
||||
W: '.--',
|
||||
X: '-..-',
|
||||
Y: '-.--',
|
||||
Z: '--..',
|
||||
'1': '.----',
|
||||
'2': '..---',
|
||||
'3': '...--',
|
||||
'4': '....-',
|
||||
'5': '.....',
|
||||
'6': '-....',
|
||||
'7': '--...',
|
||||
'8': '---..',
|
||||
'9': '----.',
|
||||
'0': '-----',
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the local state
|
||||
*/
|
||||
let INDEX = 0;
|
||||
let BEEPING = false;
|
||||
let BUZZING = true;
|
||||
let UNIT_INDEX = 0;
|
||||
let UNITS = MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]].split('');
|
||||
/**
|
||||
* Utility functions for writing text, changing state
|
||||
*/
|
||||
const writeText = (txt) => {
|
||||
g.clear();
|
||||
const width = g.stringWidth(txt);
|
||||
g.drawString(txt, (SCREEN_PIXELS / 2) - (width / 2), SCREEN_PIXELS / 2);
|
||||
};
|
||||
const writeLetter = () => {
|
||||
writeText(Object.keys(MORSE_MAP)[INDEX]);
|
||||
};
|
||||
const writeCode = () => {
|
||||
writeText(MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]]);
|
||||
};
|
||||
const setUnits = () => {
|
||||
UNITS = MORSE_MAP[Object.keys(MORSE_MAP)[INDEX]].split('');
|
||||
};
|
||||
/**
|
||||
* Bootstrapping
|
||||
*/
|
||||
g.clear();
|
||||
g.setFont(FONT_NAME, FONT_SIZE);
|
||||
g.setColor(0, 1, 0);
|
||||
g.setFontAlign(-1, 0, 0);
|
||||
/**
|
||||
* The length of a dot is one unit
|
||||
* The length of a dash is three units
|
||||
* The length of a space is one unit
|
||||
* The space between letters is three units
|
||||
* The space between words is seven units
|
||||
*/
|
||||
const beepItOut = () => {
|
||||
// If we are starting the beeps, use a timeout for pause of three units
|
||||
const wait = UNIT_INDEX === 0 ? UNIT * 3 : 0;
|
||||
setTimeout(() => {
|
||||
Promise.all([
|
||||
Bangle.beep(UNITS[UNIT_INDEX] === '.' ? UNIT : 3 * UNIT),
|
||||
// Could make buzz optional or switchable potentially
|
||||
BUZZING ? Bangle.buzz(UNITS[UNIT_INDEX] === '.' ? UNIT : 3 * UNIT) : null
|
||||
])
|
||||
.then(() => {
|
||||
if (UNITS[UNIT_INDEX + 1]) {
|
||||
setTimeout(() => {
|
||||
UNIT_INDEX++;
|
||||
beepItOut();
|
||||
}, UNIT);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
BEEPING = false;
|
||||
UNIT_INDEX = 0;
|
||||
writeLetter();
|
||||
}, 3 * UNIT);
|
||||
}
|
||||
});
|
||||
}, wait);
|
||||
};
|
||||
const startBeep = () => {
|
||||
if (BEEPING) return;
|
||||
else {
|
||||
BEEPING = true;
|
||||
writeCode();
|
||||
beepItOut();
|
||||
}
|
||||
};
|
||||
|
||||
const step = (positive) => () => {
|
||||
if (BEEPING) return;
|
||||
if (positive) {
|
||||
INDEX = INDEX + 1;
|
||||
if (INDEX > Object.keys(MORSE_MAP).length - 1) INDEX = 0;
|
||||
} else {
|
||||
INDEX = INDEX - 1;
|
||||
if (INDEX < 0) INDEX = Object.keys(MORSE_MAP).length - 1;
|
||||
}
|
||||
setUnits();
|
||||
writeLetter();
|
||||
};
|
||||
|
||||
const toggleBuzzing = () => (BUZZING = !BUZZING);
|
||||
|
||||
writeLetter();
|
||||
|
||||
// Press the middle button to hear the morse code translation
|
||||
setWatch(startBeep, BTN2, { repeat: true });
|
||||
// Allow user to switch between letters
|
||||
setWatch(step(true), BTN1, { repeat: true });
|
||||
setWatch(step(false), BTN3, { repeat: true });
|
||||
// Toggle buzzing/beeping with the touchscreen
|
||||
setWatch(toggleBuzzing, BTN4, { repeat: true });
|
||||
setWatch(toggleBuzzing, BTN5, { repeat: true });
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name":"Morse Code","type":"app",
|
||||
"icon":"*morse",
|
||||
"src":"-morse"
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 413 B |
Loading…
Reference in New Issue