spotiqueue/src/user.ts

113 lines
3.1 KiB
TypeScript

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<string>) {
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;
}
}