v1 feature: added playlists
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { createContext } from "react";
|
||||
import type { Dump, OnlineUser } from "../model.ts";
|
||||
import type { Dump, OnlineUser, Playlist } from "../model.ts";
|
||||
|
||||
export interface VoteEvent {
|
||||
dumpId: string;
|
||||
@@ -7,6 +7,14 @@ export interface VoteEvent {
|
||||
action: "cast" | "remove";
|
||||
}
|
||||
|
||||
export interface PlaylistEvent {
|
||||
type: "created" | "updated" | "deleted" | "dumps_updated";
|
||||
playlistId: string;
|
||||
playlist?: Playlist;
|
||||
userId?: string;
|
||||
dumpIds?: string[];
|
||||
}
|
||||
|
||||
export interface WSContextValue {
|
||||
onlineUsers: OnlineUser[];
|
||||
voteCounts: Record<string, number>;
|
||||
@@ -14,6 +22,8 @@ export interface WSContextValue {
|
||||
recentDumps: Dump[];
|
||||
deletedDumpIds: Set<string>;
|
||||
lastVoteEvent: VoteEvent | null;
|
||||
lastPlaylistEvent: PlaylistEvent | null;
|
||||
deletedPlaylistIds: Set<string>;
|
||||
castVote: (dumpId: string) => void;
|
||||
removeVote: (dumpId: string) => void;
|
||||
}
|
||||
@@ -25,6 +35,8 @@ export const WSContext = createContext<WSContextValue>({
|
||||
recentDumps: [],
|
||||
deletedDumpIds: new Set(),
|
||||
lastVoteEvent: null,
|
||||
lastPlaylistEvent: null,
|
||||
deletedPlaylistIds: new Set(),
|
||||
castVote: () => {},
|
||||
removeVote: () => {},
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user