mirror of https://github.com/nealey/vail.git
Respond correctly to URL changes
This commit is contained in:
parent
f50540aefe
commit
80335a6233
|
@ -38,21 +38,22 @@
|
||||||
<div class="mdl-layout__drawer">
|
<div class="mdl-layout__drawer">
|
||||||
<span class="mdl-layout-title">Repeaters</span>
|
<span class="mdl-layout-title">Repeaters</span>
|
||||||
<nav class="mdl-navigation">
|
<nav class="mdl-navigation">
|
||||||
<a class="mdl-navigation__link" href="?repeater=">General Chaos</a>
|
<a class="mdl-navigation__link" href="#">General Chaos</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=1-15+WPM">1-15 WPM</a>
|
<a class="mdl-navigation__link" href="#1-15 WPM">1-15 WPM</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=16-20+WPM">16-20 WPM</a>
|
<a class="mdl-navigation__link" href="#16-20 WPM">16-20 WPM</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=21-99+WPM">21-99 WPM</a>
|
<a class="mdl-navigation__link" href="#21%2B+WPM">21+ WPM</a>
|
||||||
</nav>
|
</nav>
|
||||||
<hr>
|
<hr>
|
||||||
<span class="mdl-layout-title">Local Practice</span>
|
<span class="mdl-layout-title">Local Practice</span>
|
||||||
<nav class="mdl-navigation">
|
<nav class="mdl-navigation">
|
||||||
<a class="mdl-navigation__link" href="?repeater=Fortunes">Fortunes</a>
|
<a class="mdl-navigation__link" href="#Echo">Echo</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=Fortunes: Pauses ×2">Fortunes (slow)</a>
|
<a class="mdl-navigation__link" href="#Fortunes">Fortunes</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=Fortunes: Pauses ×4">Fortunes (very slow)</a>
|
<a class="mdl-navigation__link" href="#Fortunes: Pauses ×2">Fortunes (slow)</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=Fortunes: Pauses ×6">Fortunes (very very slow)</a>
|
<a class="mdl-navigation__link" href="#Fortunes: Pauses ×4">Fortunes (very slow)</a>
|
||||||
<a class="mdl-navigation__link" href="?repeater=Fortunes: Pauses ×10">Fortunes (crazy slow)</a>
|
<a class="mdl-navigation__link" href="#Fortunes: Pauses ×6">Fortunes (very very slow)</a>
|
||||||
|
<a class="mdl-navigation__link" href="#Fortunes: Pauses ×10">Fortunes (crazy slow)</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<hr>
|
||||||
<nav class="mdl-navigation">
|
<nav class="mdl-navigation">
|
||||||
<a class="mdl-navigation__link" href="https://morse.withgoogle.com/learn/">Learn Morse Code</a>
|
<a class="mdl-navigation__link" href="https://morse.withgoogle.com/learn/">Learn Morse Code</a>
|
||||||
<a class="mdl-navigation__link" href="https://github.com/nealey/vail-adapter">Use a physical key</a>
|
<a class="mdl-navigation__link" href="https://github.com/nealey/vail-adapter">Use a physical key</a>
|
||||||
|
@ -80,10 +81,14 @@
|
||||||
<option>1-15 WPM</option>
|
<option>1-15 WPM</option>
|
||||||
<option>16-20 WPM</option>
|
<option>16-20 WPM</option>
|
||||||
<option>21+ WPM</option>
|
<option>21+ WPM</option>
|
||||||
<option>Fortunes: Pauses ×8</option>
|
<option>Null</option>
|
||||||
<option>Fortunes: Pauses ×4</option>
|
<option>Echo</option>
|
||||||
<option>Fortunes: Pauses ×2</option>
|
<option>Echo 5s</option>
|
||||||
|
<option>Echo 10s</option>
|
||||||
<option>Fortunes</option>
|
<option>Fortunes</option>
|
||||||
|
<option>Fortunes: Pauses ×2</option>
|
||||||
|
<option>Fortunes: Pauses ×4</option>
|
||||||
|
<option>Fortunes: Pauses ×8</option>
|
||||||
</datalist>
|
</datalist>
|
||||||
<label class="mdl-textfield__label" for="repeater">Repeater</label>
|
<label class="mdl-textfield__label" for="repeater">Repeater</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -189,6 +189,13 @@ class Keyer {
|
||||||
this.pauseMultiplier = multiplier
|
this.pauseMultiplier = multiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete anything left on the queue.
|
||||||
|
*/
|
||||||
|
Flush() {
|
||||||
|
this.queue.splice(0)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add to the output queue, and start processing the queue if it's not currently being processed.
|
* Add to the output queue, and start processing the queue if it's not currently being processed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,9 +5,9 @@ const Second = 1000 * Millisecond
|
||||||
const Minute = 60 * Second
|
const Minute = 60 * Second
|
||||||
|
|
||||||
export class Vail {
|
export class Vail {
|
||||||
constructor(name, rx) {
|
constructor(rx, name) {
|
||||||
this.name = name
|
|
||||||
this.rx = rx
|
this.rx = rx
|
||||||
|
this.name = name
|
||||||
this.lagDurations = []
|
this.lagDurations = []
|
||||||
this.sent = []
|
this.sent = []
|
||||||
|
|
||||||
|
@ -110,10 +110,33 @@ export class Vail {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Null {
|
export class Null {
|
||||||
constructor() {
|
constructor(rx) {
|
||||||
|
this.rx = rx
|
||||||
|
this.interval = setInterval(() => this.pulse(), 1 * Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
Transmit(time, duration, squelch=True) {
|
pulse() {
|
||||||
|
console.log("pulse")
|
||||||
|
this.rx(0, 0, {note: "local"})
|
||||||
|
}
|
||||||
|
|
||||||
|
Transmit(time, duration, squelch=true) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Close() {
|
||||||
|
clearInterval(this.interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Echo {
|
||||||
|
constructor(rx, delay=0) {
|
||||||
|
this.rx = rx
|
||||||
|
this.delay = delay
|
||||||
|
this.Transmit(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Transmit(time, duration, squelch=true) {
|
||||||
|
this.rx(time + this.delay, duration, {note: "local"})
|
||||||
}
|
}
|
||||||
|
|
||||||
Close() {
|
Close() {
|
||||||
|
@ -135,15 +158,13 @@ export class Fortune {
|
||||||
}
|
}
|
||||||
|
|
||||||
pulse() {
|
pulse() {
|
||||||
|
this.rx(0, 0, {note: "local"})
|
||||||
if (this.keyer.Busy()) {
|
if (this.keyer.Busy()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let fortune = GetFortune()
|
let fortune = GetFortune()
|
||||||
this.keyer.EnqueueAsciiString(`${fortune}\x04 `)
|
this.keyer.EnqueueAsciiString(`${fortune}\x04 `)
|
||||||
this.rx(0, 0, {
|
|
||||||
note: "local",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Transmit(time, duration, squelch=true) {
|
Transmit(time, duration, squelch=true) {
|
||||||
|
@ -151,6 +172,7 @@ export class Fortune {
|
||||||
}
|
}
|
||||||
|
|
||||||
Close() {
|
Close() {
|
||||||
|
this.keyer.Flush()
|
||||||
clearInterval(this.interval)
|
clearInterval(this.interval)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,9 @@ import * as Inputs from "./inputs.mjs"
|
||||||
import * as Repeaters from "./repeaters.mjs"
|
import * as Repeaters from "./repeaters.mjs"
|
||||||
|
|
||||||
const DefaultRepeater = "General Chaos"
|
const DefaultRepeater = "General Chaos"
|
||||||
|
const Millisecond = 1
|
||||||
|
const Second = 1000 * Millisecond
|
||||||
|
const Minute = 60 * Second
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop up a message, using an MDL snackbar.
|
* Pop up a message, using an MDL snackbar.
|
||||||
|
@ -65,16 +68,27 @@ class VailClient {
|
||||||
this.rxDelay = Number(e.target.value)
|
this.rxDelay = Number(e.target.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Fill in the name of our repeater
|
// Fill in the name of our repeater
|
||||||
let repeaterElement = document.querySelector("#repeater").addEventListener("change", e => this.setRepeater(e.target.value.trim()))
|
let repeaterElement = document.querySelector("#repeater").addEventListener("change", e => this.setRepeater(e.target.value.trim()))
|
||||||
this.setRepeater(decodeURI(decodeURIComponent(window.location.hash.split("#")[1] || "")))
|
window.addEventListener("hashchange", () => this.hashchange())
|
||||||
|
this.hashchange()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the hash part of the URL has changed.
|
||||||
|
*/
|
||||||
|
hashchange() {
|
||||||
|
let hashParts = window.location.hash.split("#")
|
||||||
|
|
||||||
|
this.setRepeater(decodeURIComponent(hashParts[1] || ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a repeater by name.
|
* Connect to a repeater by name.
|
||||||
*
|
*
|
||||||
* In the future this may do some fancy switching logic to provide multiple types of repeaters.
|
* This does some switching logic to provide multiple types of repeaters,
|
||||||
* For instance, I'd like to create a set of repeaters that run locally, for practice.
|
* like the Fortunes repeaters.
|
||||||
*
|
*
|
||||||
* @param {string} name Repeater name
|
* @param {string} name Repeater name
|
||||||
*/
|
*/
|
||||||
|
@ -94,12 +108,11 @@ class VailClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window URL
|
// Set window URL
|
||||||
let hash = name
|
let prevHash = window.location.hash
|
||||||
if (name == DefaultRepeater) {
|
window.location.hash = (name == DefaultRepeater) ? "" : name
|
||||||
hash = ""
|
if (window.location.hash != prevHash) {
|
||||||
}
|
// We're going to get a hashchange event, which will re-run this method
|
||||||
if (hash != window.location.hash) {
|
return
|
||||||
window.location.hash = hash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.repeater) {
|
if (this.repeater) {
|
||||||
|
@ -107,17 +120,25 @@ class VailClient {
|
||||||
}
|
}
|
||||||
let rx = (w,d,s) => this.receive(w,d,s)
|
let rx = (w,d,s) => this.receive(w,d,s)
|
||||||
|
|
||||||
// You can set the repeater name to "Fortunes: Pauses×10" for a nice and easy intro
|
// If there's a number in the name, store that for potential later use
|
||||||
|
let numberMatch = name.match(/[0-9]+/)
|
||||||
|
let number = 0
|
||||||
|
if (numberMatch) {
|
||||||
|
number = Number(numberMatch[0])
|
||||||
|
}
|
||||||
|
|
||||||
if (name.startsWith("Fortunes")) {
|
if (name.startsWith("Fortunes")) {
|
||||||
let m = name.match(/[x×]([0-9]+)/)
|
this.roboKeyer.SetPauseMultiplier(number || 1)
|
||||||
let mult = 1
|
|
||||||
if (m) {
|
|
||||||
mult = Number(m[1])
|
|
||||||
}
|
|
||||||
this.roboKeyer.SetPauseMultiplier(mult)
|
|
||||||
this.repeater = new Repeaters.Fortune(rx, this.roboKeyer)
|
this.repeater = new Repeaters.Fortune(rx, this.roboKeyer)
|
||||||
|
} else if (name.startsWith("Echo")) {
|
||||||
|
let delayElement = document.querySelector("#rx-delay")
|
||||||
|
delayElement.value = (number || 2) * Second
|
||||||
|
delayElement.dispatchEvent(new Event("input"))
|
||||||
|
this.repeater = new Repeaters.Echo(rx)
|
||||||
|
} else if (name == "Null") {
|
||||||
|
this.repeater = new Repeaters.Null(rx)
|
||||||
} else {
|
} else {
|
||||||
this.repeater = new Repeaters.Vail(name, rx)
|
this.repeater = new Repeaters.Vail(rx, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
toast(`Now using repeater: ${name}`)
|
toast(`Now using repeater: ${name}`)
|
||||||
|
@ -195,7 +216,6 @@ class VailClient {
|
||||||
this.clockOffset = stats.clockOffset || "?"
|
this.clockOffset = stats.clockOffset || "?"
|
||||||
let now = Date.now()
|
let now = Date.now()
|
||||||
when += this.rxDelay
|
when += this.rxDelay
|
||||||
console.log(stats)
|
|
||||||
|
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
if (when < now) {
|
if (when < now) {
|
||||||
|
|
Loading…
Reference in New Issue