diagramming/client.js
2024-06-07 13:58:08 -05:00

67 lines
1.7 KiB
JavaScript

import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'
let lastDiagram = ''
let rendering = false
let theme = 'dark'
function setTheme(lightMatches) {
theme = lightMatches ? 'default' : 'dark'
mermaid.initialize({ startOnLoad: true, theme })
renderLastDiagram()
}
if (window.matchMedia) {
let lightMatcher = window.matchMedia('(prefers-color-scheme: light)')
lightMatcher.addEventListener('change', ({ matches }) => setTheme(matches))
setTheme(lightMatcher.matches)
}
let connectionAttempt = 0
function connectSocket() {
const socket = new WebSocket('ws://localhost:8080')
socket.addEventListener('open', () => {
socket.send(JSON.stringify({ type: 'open', connectionAttempt }))
})
socket.addEventListener('close', () => {
connectionAttempt += 1
setTimeout(() => requestAnimationFrame(connectSocket), 1000)
})
socket.addEventListener('message', handleMessage)
}
async function handleMessage({ data }) {
if (data == 'hi') {
console.log('👋')
} else if (data == 'reload') {
window.location.reload()
} else {
try {
await handleStructuredMessage(JSON.parse(data))
} catch (err) {
console.error(`failed to process structured websocket message: ${err}`)
}
}
}
async function handleStructuredMessage(data) {
switch (data.type) {
case 'mermaid': {
if (rendering) return
rendering = true
lastDiagram = data.contents
await renderLastDiagram()
rendering = false
break
}
}
}
async function renderLastDiagram() {
if (lastDiagram == '') return
document.getElementById('diagram').innerHTML =
(await mermaid.render('mermaid', lastDiagram)).svg
}
addEventListener('DOMContentLoaded', connectSocket)