fixes: iambic, https, mobile, probably more

This commit is contained in:
Neale Pickett 2020-05-04 22:20:16 -06:00
parent ac08b063fc
commit 863df2b0ed
3 changed files with 61 additions and 50 deletions

View File

@ -14,12 +14,10 @@ type Client struct {
} }
func (c Client) Handle(ws *websocket.Conn) { func (c Client) Handle(ws *websocket.Conn) {
log.Println("c.Handle hooray")
ws.MaxPayloadBytes = 500 ws.MaxPayloadBytes = 500
book.Join(c.repeaterName, ws) book.Join(c.repeaterName, ws)
defer book.Part(c.repeaterName, ws) defer book.Part(c.repeaterName, ws)
log.Println("for loop")
for { for {
buf := make([]byte, ws.MaxPayloadBytes) buf := make([]byte, ws.MaxPayloadBytes)
@ -34,25 +32,18 @@ func (c Client) Handle(ws *websocket.Conn) {
} }
func ChatHandler(w http.ResponseWriter, r *http.Request) { func ChatHandler(w http.ResponseWriter, r *http.Request) {
log.Print("Handling chat")
c := Client { c := Client {
repeaterName: r.FormValue("repeater"), repeaterName: r.FormValue("repeater"),
} }
// This API is confusing as hell. // This API is confusing as hell.
// I suspect there's a better way to do this. // I suspect there's a better way to do this.
log.Print("Web Socketing")
websocket.Handler(c.Handle).ServeHTTP(w, r) websocket.Handler(c.Handle).ServeHTTP(w, r)
} }
func hello(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world"))
}
func main() { func main() {
book = NewBook() book = NewBook()
http.Handle("/chat", http.HandlerFunc(ChatHandler)) http.Handle("/chat", http.HandlerFunc(ChatHandler))
http.Handle("/hello", http.HandlerFunc(hello))
http.Handle("/", http.FileServer(http.Dir("static"))) http.Handle("/", http.FileServer(http.Dir("static")))
go book.Run() go book.Run()

View File

@ -47,7 +47,7 @@
<main class="mdl-layout__content"> <main class="mdl-layout__content">
<div class="flex"> <div class="flex">
<div class="mdl-card mdl-shadow--4dp"> <div class="input mdl-card mdl-shadow--4dp">
<div class="mdl-card__title"> <div class="mdl-card__title">
<h2 class="mdl-card__title-text">Input</h2> <h2 class="mdl-card__title-text">Input</h2>
</div> </div>

View File

@ -13,7 +13,8 @@ class Iambic {
this.endTxFunc = endTxFunc this.endTxFunc = endTxFunc
this.intervalDuration = null this.intervalDuration = null
this.state = this.stateBegin this.state = this.stateBegin
this.keyState = null this.ditDown = false
this.dahDown = false
} }
/** /**
@ -34,23 +35,35 @@ class Iambic {
this.state() this.state()
} }
stateBegin() { stateBegin() {
if (this.keyState) { if (this.ditDown) {
// Don't transmit for one interval. this.stateDit()
this.state = this.keyState } else if (this.dahDown) {
this.state() this.stateDah()
} else { } else {
// No key pressed, go back to sleep.
clearInterval(this.interval) clearInterval(this.interval)
this.interval = null this.interval = null
} }
} }
stateDit() { stateDit() {
// Send a dit // Send a dit
this.beginTxFunc() this.beginTxFunc()
this.state = this.stateEnd this.state = this.stateDitEnd
} }
stateDitEnd() {
this.endTxFunc()
this.state = this.stateDitNext
}
stateDitNext() {
if (this.dahDown) {
this.state = this.stateDah
} else {
this.state = this.stateBegin
}
this.state()
}
stateDah() { stateDah() {
// Send a dah // Send a dah
this.beginTxFunc() this.beginTxFunc()
@ -60,13 +73,21 @@ class Iambic {
this.state = this.stateDah3 this.state = this.stateDah3
} }
stateDah3() { stateDah3() {
this.state = this.stateEnd this.state = this.stateDahEnd
} }
stateEnd() { stateDahEnd() {
// Stop sending
this.endTxFunc() this.endTxFunc()
this.state = this.stateBegin this.state = this.stateDahNext
} }
stateDahNext() {
if (this.ditDown) {
this.state = this.stateDit
} else {
this.state = this.stateBegin
}
this.state()
}
/** /**
* Edge trigger on key press or release * Edge trigger on key press or release
@ -75,20 +96,10 @@ class Iambic {
* @param {number} key DIT or DAH * @param {number} key DIT or DAH
*/ */
Key(down, key) { Key(down, key) {
// By setting keyState we request this state transition,
// the next time the transition is possible.
let keyState = null
if (key == DIT) { if (key == DIT) {
keyState = this.stateDit this.ditDown = down
} else if (key == DAH) { } else if (key == DAH) {
keyState = this.stateDah this.dahDown = down
}
if (down) {
this.keyState = keyState
} else if (keyState == this.keyState) {
// Only stop when we've released the right key
this.keyState = null
} }
// Not pulsing yet? Start right away! // Not pulsing yet? Start right away!
@ -219,16 +230,13 @@ class Vail {
this.rxDelay = 0 // Milliseconds to add to incoming timestamps this.rxDelay = 0 // Milliseconds to add to incoming timestamps
this.beginTxTime = null // Time when we began transmitting this.beginTxTime = null // Time when we began transmitting
// Set up WebSocket this.openSocket()
let wsUrl = new URL(window.location)
wsUrl.protocol = wsUrl.protocol.replace("http", "ws")
wsUrl.pathname += "chat"
this.socket = new WebSocket(wsUrl)
this.socket.addEventListener("message", e => this.wsMessage(e))
// Listen to HTML buttons // Listen to HTML buttons
for (let e of document.querySelectorAll("button.key")) { for (let e of document.querySelectorAll("button.key")) {
e.addEventListener("contextmenu", e => {e.preventDefault(); return false}) e.addEventListener("contextmenu", e => {e.preventDefault(); return false})
e.addEventListener("touchstart", e => this.keyButton(e))
e.addEventListener("touchend", e => this.keyButton(e))
e.addEventListener("mousedown", e => this.keyButton(e)) e.addEventListener("mousedown", e => this.keyButton(e))
e.addEventListener("mouseup", e => this.keyButton(e)) e.addEventListener("mouseup", e => this.keyButton(e))
} }
@ -250,8 +258,20 @@ class Vail {
document.querySelector("#repeater").textContent = repeater document.querySelector("#repeater").textContent = repeater
// Request MIDI access // Request MIDI access
navigator.requestMIDIAccess() if (navigator.requestMIDIAccess) {
.then(a => this.midiInit(a)) navigator.requestMIDIAccess()
.then(a => this.midiInit(a))
}
}
openSocket() {
// Set up WebSocket
let wsUrl = new URL(window.location)
wsUrl.protocol = wsUrl.protocol.replace("http", "ws")
wsUrl.pathname += "chat"
this.socket = new WebSocket(wsUrl)
this.socket.addEventListener("message", e => this.wsMessage(e))
this.socket.addEventListener("close", e => this.openSocket())
} }
inputInit(selector, func) { inputInit(selector, func) {
@ -280,10 +300,8 @@ class Vail {
} }
midiStateChange(event) { midiStateChange(event) {
if (event.port.connection == "open") { // XXX: it's not entirely clear how to handle new devices showing up.
console.log(event) // XXX: possibly we go through this.midiAccess.inputs and somehow only listen on new things
event.port.addEventListiner("midimessage", e => this.midiMessage(e))
}
} }
midiMessage(event) { midiMessage(event) {
@ -461,7 +479,9 @@ class Vail {
} }
keyButton(event) { keyButton(event) {
let begin = event.type.endsWith("down") let begin = event.type.endsWith("down") || event.type.endsWith("start")
event.preventDefault()
if (event.target.id == "dah") { if (event.target.id == "dah") {
this.iambic.Key(begin, DAH) this.iambic.Key(begin, DAH)
@ -471,7 +491,7 @@ class Vail {
this.iambic.Key(begin, DIT) this.iambic.Key(begin, DIT)
} else if (event.target.id == "key") { } else if (event.target.id == "key") {
this.straightKey(begin) this.straightKey(begin)
} else if (event.target.id == "ck") { } else if ((event.target.id == "ck") && begin) {
this.Test() this.Test()
} }
} }