diff --git a/public/assets/app.css b/public/assets/app.css index 5f75ad0..d85ddea 100644 --- a/public/assets/app.css +++ b/public/assets/app.css @@ -69,35 +69,15 @@ header h1 { color: white; } +header .led { + margin-left: 1rem; + margin-right: 1rem; +} + header span { font-size: 1.2rem; } -header .status { - background-color: HSL(0, 0%, 80%); - border-radius: 100px; - box-shadow: rgba(255, 255, 255, .25) 0px 15px 11px -9px inset, rgba(0, 0, 0, .25) 0px -12px 11px -9px inset, rgba(0, 0, 0, .65) 0 4px 20px; - padding: 0.6rem 2rem; - text-align: center; - text-decoration: none; - border: 0; - font-size: 1rem; - user-select: none; - margin: 0 1rem 0 1rem; -} - -header .status.red { - background-color: #ff3232; - box-shadow: rgba(255, 255, 255, .25) 0px 15px 11px -9px inset, rgba(0, 0, 0, .25) 0px -12px 11px -9px inset, rgba(0, 0, 0, .65) 0 4px 20px, rgba(255, 50, 50, .5) 0 0 15px; - color: black; -} - -header .status.green { - background-color: #10ef07; - box-shadow: rgba(255, 255, 255, .65) 0px 15px 11px -9px inset, rgba(0, 100, 0, .4) 0px -12px 11px -9px inset, rgba(0, 0, 0, .65) 0 4px 20px, rgba(0, 255, 0, .5) 0 0 15px; - color: black; -} - main { flex: 2 1 auto; } @@ -152,3 +132,36 @@ nav::after { width: 100%; border-top: 1px solid var(--nav-above-border-color); } + +/* Taken from https://github.com/aus/led.css */ +.led { + margin-top: 1px; + width: 20px; + height: 20px; + border-radius: 5px; + background-color: rgba(255, 255, 255, 0.25); + box-shadow: #fff5 3px 5px 7px -8px inset, #000 0 -1px 6px 1px; +} +.led-red { + background-color: #F00; + box-shadow: #000 0 -1px 6px 1px, inset #600 0 -1px 8px, #F00 0 3px 11px; +} +.led-orange { + background-color: #FF7000; + box-shadow: #000 0 -1px 6px 1px, inset #630 0 -1px 8px, #FF7000 0 3px 11px; +} + +.led-yellow { + background-color: #FF0; + box-shadow: #000 0 -1px 6px 1px, inset #660 0 -1px 8px, #FF0 0 3px 11px; +} + +.led-green { + background-color: #80FF00; + box-shadow: #000 0 -1px 6px 1px, inset #460 0 -1px 8px, #80FF00 0 3px 11px; +} + +.led-blue { + background-color: #06F; + box-shadow: #000 0 -1px 6px 1px, inset #006 0 -1px 8px, #06F 0 3px 11px; +} diff --git a/public/assets/app.js b/public/assets/app.js index 1022927..4c05398 100644 --- a/public/assets/app.js +++ b/public/assets/app.js @@ -1,19 +1,71 @@ class WSClient { - constructor() { - // Create WebSocket connection. - const socket = new WebSocket('ws://localhost:4040') + constructor(url = 'ws://localhost:4040') { + this.url = url + this.socket = null + this.connected = false + this.connecting = false + this.reconnectingAt = null + this.retryDuration = 1000 + this.open() + } - // Connection opened - socket.addEventListener('open', function (event) { - console.log('Sending hello server') - socket.send(JSON.stringify({ msg: 'Hello Server!' })) - }) + open() { + if (this.connected || this.connecting) return + this.connecting = true + this.socket = new WebSocket(this.url) - // Listen for messages - socket.addEventListener('message', function (event) { - console.log('Message from server', event.data) - }) + this.socket.addEventListener('open', this.onopen.bind(this)) + this.socket.addEventListener('message', this.onmessage.bind(this)) + this.socket.addEventListener('error', this.onerror.bind(this)) + this.socket.addEventListener('close', this.onclose.bind(this)) + m.redraw() + } + + onopen() { + this.retryDuration = 1000 + this.connecting = false + this.reconnectingAt = null + this.connected = true + console.log('Sending hello server') + this.send({ msg: 'Hello Server!' }) + m.redraw() + } + + send(payload) { + if (!this.connected) return + this.socket.send(JSON.stringify(payload)) + } + + onerror(err) { + console.error(err) + this.reconnect() + } + + onclose() { + this.reconnect() + } + + reconnect() { + if (this.reconnectingAt) return + this.socket = null + this.connected = false + this.connecting = false + + this.reconnectingAt = new Date(new Date().getTime() + this.retryDuration) + setTimeout(() => { + this.reconnectingAt = null + this.retryDuration *= 1.5 + this.open() + }, this.retryDuration) + m.redraw() + } + + onmessage(event) { + try { + let data = JSON.parse(event.data) + console.log('got message', data) + } catch (err) { console.error(err) } } } @@ -25,8 +77,14 @@ class Header { m('h1', 'Fíladelfíu streymi'), m('div.status.green', { hidden: true }, 'No errors'), m('div.filler'), - m('span', 'Status:'), - m('div.status', 'Not live'), + m('span', 'Live:'), + m('div.led'), + client.connected + ? null + : m('div.overlay', [ + m('h2', client.connecting ? 'Connecting to server...' : 'Connection lost'), + m('') + ]), ] } } diff --git a/server/server.mjs b/server/server.mjs index e1b483a..df4cbf8 100644 --- a/server/server.mjs +++ b/server/server.mjs @@ -42,7 +42,7 @@ export function run(http, port, core) { flaska.get('/::file', serve.serve.bind(serve)) return flaska.listenAsync(port).then(function() { - const wss = new WebSocketServer({ server: flaska.server }) + /*const wss = new WebSocketServer({ server: flaska.server }) wss.on('connection', function(ws) { console.log('new connection') @@ -88,6 +88,7 @@ export function run(http, port, core) { wss.on('close', function() { clearInterval(interval) }) + */ core.log.info('Server is listening on port ' + port) })