dracula-musical/ui/src/syncing.ts
2023-06-22 23:09:42 +02:00

58 lines
1.6 KiB
TypeScript
Executable file

import ReconnectingWebSocket from "reconnecting-websocket"
import { show, ShowPosition, state } from "./state"
import { ref } from "vue"
let socket: ReconnectingWebSocket | null = null
let timeDifference = 0
export const getSyncedTime = () => Date.now() - timeDifference
export const syncedTime = ref(Date.now())
const setSyncedTimeRef = () => {
syncedTime.value = getSyncedTime()
requestAnimationFrame(setSyncedTimeRef)
}
requestAnimationFrame(setSyncedTimeRef)
export const connect = () => new Promise<void>(resolve => {
if (socket !== null) return
const url = new URL(window.location.toString())
url.protocol = "ws"
url.pathname = "/api/ws"
socket = new ReconnectingWebSocket(url.toString(), [], {
reconnectionDelayGrowFactor: 1,
minReconnectionDelay: 1000
})
let isFirstMessage = true
socket.addEventListener("open", () => {
isFirstMessage = true
})
socket.addEventListener("message", event => {
const data = JSON.parse(event.data as string)
if (isFirstMessage) {
isFirstMessage = false
show.value = data
console.log("Show:", data)
} else {
Object.assign(state, data.state)
timeDifference = Date.now() - data.timestamp
console.log("New state:", data.state)
console.log("New time difference:", timeDifference)
resolve()
}
})
})
export async function goToPosition(position: ShowPosition) {
await fetch("/api/go", { method: "POST", body: JSON.stringify(position), headers: { "Content-Type": "application/json" } })
}
export async function setMessage(message: string) {
await fetch("/api/message", { method: "POST", body: message })
}