import { buildCommand, buildError, Command, parseCommand } from "./commandBuilder.ts"; import { MergedQueue, UserQueue } from "./playerManager.ts"; import { Song } from "./spotify.ts"; export class UserWS { private ws: WebSocket; private loggedIn: boolean = false; private name: string = ""; private playerQueue: UserQueue | undefined; constructor(ws: WebSocket) { this.ws = ws; this.onMessage = this.onMessage.bind(this); this.onClose = this.onClose.bind(this); ws.addEventListener("message", this.onMessage); ws.addEventListener("close", this.onClose); } public disconnect() { this.loggedIn = false; this.ws.send(buildCommand("logout")) this.ws.close(); } public broadcastQueue(queue: MergedQueue) { this.ws.send(buildCommand("updatemergedqueue", {queue})) } public updateQueue() { const queue = this.playerQueue?.queue; if (!queue) return; this.ws.send(buildCommand("getqueue", {queue})) } private spotifyConnected(): boolean { return spotify === undefined; } private login(name: string) { this.name = name; this.loggedIn = true; this.playerQueue = playerManager.login(name, this); } private async onMessage(msg: MessageEvent) { const command = parseCommand(msg.data); if (command === null || (command.c != "login" && !this.loggedIn)) { console.log("User not logged in but sent", command) return }; switch (command.c) { case "login": { if (command.d === undefined || typeof(command.d.name) !== "string") { this.ws.send(buildError(0)) return }; const cmd = command as Command<{name: string}>; const name = cmd.d.name.trim(); if (name === "") { this.ws.send(buildError(0)) return } this.login(command.d.name); break; }; case "search": { if (command.d === undefined || typeof(command.d.query) !== "string") return const cmd = command as Command<{query: string}>; const songs = await spotify?.search(cmd.d.query) if (songs === undefined) { this.ws.send(buildCommand("search", {songs: [], connected: false})) } else { this.ws.send(buildCommand("search", {songs, connected: true})) } break } case "getqueue": { if (!this.playerQueue) return; const queue = this.playerQueue.queue; this.ws.send(buildCommand("getqueue", {queue})) break } case "setqueue": { if (command.d === undefined || typeof(command.d.queue) !== "object" || !this.playerQueue) return const cmd = command as Command<{queue: Song[]}> this.playerQueue.queue = cmd.d.queue; playerManager.updateMergedQueue(); break } case "queuesong": { if (command.d === undefined || typeof(command.d.song) !== "object" || !this.playerQueue) return const cmd = command as Command<{song: Song}> this.playerQueue.queue.push(cmd.d.song); playerManager.updateMergedQueue(); } } } private onClose() { this.loggedIn = false; } }