complete except for drag&drop queue reordering and sorting

This commit is contained in:
Jurn Wubben 2026-02-02 23:13:05 +01:00
parent 63dec0ede2
commit ccbb7fcd13
5 changed files with 532 additions and 17 deletions

View file

@ -1,12 +1,11 @@
import { SpotifyWS } from "./spotify.ts"
import { HeartbeatWS } from "./heartbeat.ts";
import { PlayerManager } from "./playerManager.ts";
import { serveFile } from "@std/http/file-server";
import { serveDir } from "@std/http/file-server";
import { UserWS } from "./user.ts";
const USER_PATTERN = new URLPattern({pathname: "/ws/user"})
const SPOTIFY_PATTERN = new URLPattern({pathname: "/ws/spotify"})
const song = "spotify:track:2VxJVGiTsK6UyrxPJJ2lR9";
function commonWs(req: Request) {
const { socket, response } = Deno.upgradeWebSocket(req);
@ -33,11 +32,11 @@ Deno.serve((req) => {
const spState = spotify?.ws.readyState;
if (spState !== undefined && spState !== WebSocket.CLOSED) spotify?.ws.close();
spotify = new SpotifyWS(socket, () => song);
new SpotifyWS(socket);
new HeartbeatWS(socket);
return response
}
return serveFile(req, "./static/index.html")
return serveDir(req, {fsRoot: "./static", urlRoot: ""})
})

View file

@ -58,6 +58,11 @@ export class PlayerManager {
return song.song;
}
public broadcastStatus() {
for (const user of Object.values(this.userQueue)) {
user.userWS.updateStatus();
}
}
public updateMergedQueue() {
this.generateMergedQueue();
this.broadcastMergedQueue();
@ -69,7 +74,7 @@ export class PlayerManager {
}
private broadcastMergedQueue() {
for (const user of Object.values(this.userQueue)) {
user.userWS.broadcastQueue(this.mergedQueue);
user.userWS.updateQueue();
}
}

View file

@ -22,7 +22,10 @@ export class SpotifyWS {
this.onMessage = this.onMessage.bind(this);
this.onClose = this.onClose.bind(this);
this.onOpen = this.onOpen.bind(this);
this.ws.addEventListener("message", this.onMessage);
this.ws.addEventListener("open", this.onOpen);
this.ws.addEventListener("close", this.onClose);
}
@ -53,8 +56,13 @@ export class SpotifyWS {
this.ws.send(data);
}
private onOpen() {
globalThis.spotify = this;
playerManager.broadcastStatus();
}
private onClose() {
globalThis.spotify = undefined;
playerManager.broadcastStatus();
}
private onMessage(msg: MessageEvent<string>) {
const text = msg.data;

View file

@ -23,24 +23,23 @@ export class UserWS {
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}))
this.ws.send(buildCommand("getqueue", {personal: queue, merged: playerManager.mergedQueue }))
}
public updateStatus() {
this.ws.send(buildCommand("status", {status: spotify !== undefined}))
}
private spotifyConnected(): boolean {
return spotify === undefined;
}
private login(name: string) {
this.name = name;
this.loggedIn = true;
this.playerQueue = playerManager.login(name, this);
this.updateQueue();
this.updateStatus();
}
private async onMessage(msg: MessageEvent<string>) {
const command = parseCommand(msg.data);
@ -73,12 +72,11 @@ export class UserWS {
const cmd = command as Command<{query: string}>;
const songs = await spotify?.search(cmd.d.query)
let songs = await spotify?.search(cmd.d.query).catch(_ => console.log("Failed to search..."))
if (songs === undefined) {
this.ws.send(buildCommand("search", {songs: [], connected: false}))
} else {
this.ws.send(buildCommand("search", {songs, connected: true}))
}
songs = []
}
this.ws.send(buildCommand("search", {songs, connected: true}))
break
}
@ -104,6 +102,11 @@ export class UserWS {
this.playerQueue.queue.push(cmd.d.song);
playerManager.updateMergedQueue();
break
}
case "status": {
this.updateStatus();
break
}
}
}