v1 feature: added playlists

This commit is contained in:
khannurien
2026-03-16 16:52:53 +00:00
parent 867e64cb5b
commit be426eb150
25 changed files with 2958 additions and 101 deletions

View File

@@ -6,10 +6,15 @@ import {
useRef,
useState,
} from "react";
import { type VoteEvent, WSContext, type WSContextValue } from "./WSContext.ts";
import {
type PlaylistEvent,
type VoteEvent,
WSContext,
type WSContextValue,
} from "./WSContext.ts";
import { WS_URL } from "../config/api.ts";
import type { Dump, OnlineUser, RawDump } from "../model.ts";
import { deserializeDump } from "../model.ts";
import type { Dump, OnlineUser, RawDump, RawPlaylist } from "../model.ts";
import { deserializeDump, deserializePlaylist } from "../model.ts";
interface WSProviderProps {
children: ReactNode;
@@ -26,6 +31,12 @@ export function WSProvider({ children, token }: WSProviderProps) {
const [recentDumps, setRecentDumps] = useState<Dump[]>([]);
const [deletedDumpIds, setDeletedDumpIds] = useState<Set<string>>(new Set());
const [lastVoteEvent, setLastVoteEvent] = useState<VoteEvent | null>(null);
const [lastPlaylistEvent, setLastPlaylistEvent] = useState<
PlaylistEvent | null
>(null);
const [deletedPlaylistIds, setDeletedPlaylistIds] = useState<Set<string>>(
new Set(),
);
// Refs to avoid stale closures in event handlers
const voteCountsRef = useRef(voteCounts);
@@ -132,6 +143,40 @@ export function WSProvider({ children, token }: WSProviderProps) {
break;
}
case "playlist_created":
case "playlist_updated": {
const playlist = deserializePlaylist(msg.playlist as RawPlaylist);
setLastPlaylistEvent({
type: msg.type === "playlist_created" ? "created" : "updated",
playlistId: playlist.id,
playlist,
});
break;
}
case "playlist_deleted": {
const { playlistId, userId } = msg as {
playlistId: string;
userId: string;
};
setDeletedPlaylistIds((prev) => new Set([...prev, playlistId]));
setLastPlaylistEvent({ type: "deleted", playlistId, userId });
break;
}
case "playlist_dumps_updated": {
const { playlistId, dumpIds } = msg as {
playlistId: string;
dumpIds: string[];
};
setLastPlaylistEvent({
type: "dumps_updated",
playlistId,
dumpIds,
});
break;
}
case "error":
// On error, revert any pending optimistic update for the affected dump
// (the revert timeout will handle it)
@@ -231,6 +276,8 @@ export function WSProvider({ children, token }: WSProviderProps) {
recentDumps,
deletedDumpIds,
lastVoteEvent,
lastPlaylistEvent,
deletedPlaylistIds,
castVote,
removeVote,
};