File size: 2,275 Bytes
843a4b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d96c9a7
843a4b2
 
 
 
d96c9a7
 
843a4b2
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
 * Learn view: the letter ↔ rhythm chart. Tap any entry to hear (or have the
 * robot tap) its rhythm — the whole point is that a letter *is* a rhythm.
 */
import { el, clear, morsePattern } from "./dom.js";
import { CHAR_TO_MORSE, morseToTokens } from "../lib/morse.js";
import { tokensToOnsets } from "../lib/wire.js";

const LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
const DIGITS = "0123456789".split("");

export function createLearn(ctx) {
    const root = el("section.view#view-learn");

    function playChar(ch) {
        const pattern = CHAR_TO_MORSE[ch];
        if (!pattern) return;
        const onsets = tokensToOnsets(morseToTokens(pattern), ctx.timing());
        if (ctx.state.emitter === "robot" && ctx.reachy) {
            ctx.tapper().tap(onsets);
        } else {
            ctx.synth().play(onsets, { clickMs: ctx.timing().clickMs });
        }
    }

    function grid(title, chars) {
        const g = el("div.chart-grid");
        chars.forEach((ch) => {
            const cell = el("button.chart-cell", { onclick: () => {
                playChar(ch);
                cell.classList.remove("ping"); void cell.offsetWidth; cell.classList.add("ping");
            } }, [
                el("span.cell-char", {}, ch),
                morsePattern(CHAR_TO_MORSE[ch]),
            ]);
            g.append(cell);
        });
        return el("div.chart-section", {}, [el("h3", {}, title), g]);
    }

    const emitterNote = el("div.status muted");
    function refresh() {
        emitterNote.textContent = ctx.state.emitter === "robot" && ctx.reachy
            ? "Tapping plays on the robot's antennas."
            : "Tapping plays a beep on this device. (Switch sender in Compose.)";
    }

    root.append(
        el("h2", {}, "Learn Morse"),
        el("p.muted", {}, "A letter is just a rhythm of short and long beats. Tap any tile to feel it."),
        emitterNote,
        grid("Letters", LETTERS),
        grid("Numbers", DIGITS),
        el("div.legend", {}, [
            el("span.legend-item", {}, [morsePattern("."), " dot: one tap"]),
            el("span.legend-item", {}, [morsePattern("-"), " dash: quick double tap"]),
        ]),
    );

    refresh();
    return { node: root, onShow: refresh };
}

void clear;