added queue system on rooms
This commit is contained in:
@@ -7,7 +7,14 @@ interface RoomUser {
|
||||
avatar?: string;
|
||||
isHost: boolean;
|
||||
isGuest: boolean;
|
||||
userId?: number; // ID real del usuario si está logueado
|
||||
userId?: number;
|
||||
}
|
||||
|
||||
export interface QueueItem {
|
||||
uid: string;
|
||||
metadata: RoomMetadata;
|
||||
videoData: any;
|
||||
addedBy: string;
|
||||
}
|
||||
|
||||
interface RoomMetadata {
|
||||
@@ -36,6 +43,7 @@ interface RoomData {
|
||||
metadata?: RoomMetadata | null;
|
||||
exposed: boolean;
|
||||
publicUrl?: string;
|
||||
queue: QueueItem[];
|
||||
}
|
||||
|
||||
const rooms = new Map<string, RoomData>();
|
||||
@@ -57,7 +65,8 @@ export function createRoom(name: string, host: RoomUser, password?: string, expo
|
||||
password: password || undefined,
|
||||
metadata: null,
|
||||
exposed,
|
||||
publicUrl
|
||||
publicUrl,
|
||||
queue: []
|
||||
};
|
||||
|
||||
rooms.set(roomId, room);
|
||||
@@ -75,6 +84,55 @@ export function getAllRooms(): RoomData[] {
|
||||
}));
|
||||
}
|
||||
|
||||
export function addQueueItem(roomId: string, item: QueueItem): boolean {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return false;
|
||||
room.queue.push(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function removeQueueItem(roomId: string, itemUid: string): boolean {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return false;
|
||||
room.queue = room.queue.filter(i => i.uid !== itemUid);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function getNextQueueItem(roomId: string): QueueItem | undefined {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room || room.queue.length === 0) return undefined;
|
||||
return room.queue.shift(); // Saca el primero y lo retorna
|
||||
}
|
||||
|
||||
export function getAndRemoveQueueItem(roomId: string, itemUid: string): QueueItem | undefined {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return undefined;
|
||||
|
||||
const index = room.queue.findIndex(i => i.uid === itemUid);
|
||||
if (index === -1) return undefined;
|
||||
|
||||
const [item] = room.queue.splice(index, 1);
|
||||
return item;
|
||||
}
|
||||
|
||||
export function moveQueueItem(roomId: string, itemUid: string, direction: 'up' | 'down'): boolean {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return false;
|
||||
|
||||
const index = room.queue.findIndex(i => i.uid === itemUid);
|
||||
if (index === -1) return false;
|
||||
|
||||
const newIndex = direction === 'up' ? index - 1 : index + 1;
|
||||
|
||||
if (newIndex < 0 || newIndex >= room.queue.length) return false;
|
||||
|
||||
const temp = room.queue[newIndex];
|
||||
room.queue[newIndex] = room.queue[index];
|
||||
room.queue[index] = temp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function addUserToRoom(roomId: string, user: RoomUser): boolean {
|
||||
const room = rooms.get(roomId);
|
||||
if (!room) return false;
|
||||
|
||||
@@ -155,7 +155,6 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
||||
isGuest
|
||||
});
|
||||
|
||||
// Enviar estado inicial
|
||||
socket.send(JSON.stringify({
|
||||
type: 'init',
|
||||
userId,
|
||||
@@ -171,7 +170,8 @@ async function handleWebSocketConnection(connection: any, req: any) {
|
||||
isHost: u.isHost,
|
||||
isGuest: u.isGuest
|
||||
})),
|
||||
currentVideo: room.currentVideo
|
||||
currentVideo: room.currentVideo,
|
||||
queue: room.queue || []
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -226,6 +226,46 @@ function handleMessage(roomId: string, userId: string, data: any) {
|
||||
});
|
||||
break;
|
||||
|
||||
case 'queue_play_item':
|
||||
if (room.host.id !== userId) return;
|
||||
|
||||
const itemToPlay = roomService.getAndRemoveQueueItem(roomId, data.itemUid);
|
||||
if (itemToPlay) {
|
||||
const videoPayload = {
|
||||
videoData: itemToPlay.videoData.videoData,
|
||||
subtitles: itemToPlay.videoData.subtitles,
|
||||
currentTime: 0,
|
||||
isPlaying: true
|
||||
};
|
||||
|
||||
roomService.updateRoomVideo(roomId, videoPayload);
|
||||
roomService.updateRoomMetadata(roomId, itemToPlay.metadata);
|
||||
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'video_update',
|
||||
video: videoPayload,
|
||||
metadata: itemToPlay.metadata
|
||||
});
|
||||
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'queue_update',
|
||||
queue: room.queue
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 'queue_move':
|
||||
if (room.host.id !== userId) return;
|
||||
|
||||
const moved = roomService.moveQueueItem(roomId, data.itemUid, data.direction);
|
||||
if (moved) {
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'queue_update',
|
||||
queue: room.queue
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 'request_sync':
|
||||
// Cualquier usuario puede pedir sync
|
||||
const host = clients.get(room.host.id);
|
||||
@@ -375,6 +415,63 @@ function handleMessage(roomId: string, userId: string, data: any) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'queue_add':
|
||||
// Solo el host (o todos si quisieras) pueden añadir
|
||||
if (room.host.id !== userId) return;
|
||||
|
||||
const newItem = {
|
||||
uid: `q_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
|
||||
metadata: data.metadata,
|
||||
videoData: data.video, // El objeto que contiene url, type, subtitles
|
||||
addedBy: room.users.get(userId)?.username || 'Unknown'
|
||||
};
|
||||
|
||||
roomService.addQueueItem(roomId, newItem);
|
||||
|
||||
// Avisar a todos que la cola cambió
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'queue_update',
|
||||
queue: room.queue
|
||||
});
|
||||
break;
|
||||
|
||||
case 'queue_remove':
|
||||
if (room.host.id !== userId) return;
|
||||
roomService.removeQueueItem(roomId, data.itemUid);
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'queue_update',
|
||||
queue: room.queue
|
||||
});
|
||||
break;
|
||||
|
||||
case 'play_next':
|
||||
if (room.host.id !== userId) return;
|
||||
|
||||
const nextItem = roomService.getNextQueueItem(roomId);
|
||||
if (nextItem) {
|
||||
const videoPayload = {
|
||||
videoData: nextItem.videoData.videoData,
|
||||
subtitles: nextItem.videoData.subtitles,
|
||||
currentTime: 0,
|
||||
isPlaying: true
|
||||
};
|
||||
|
||||
roomService.updateRoomVideo(roomId, videoPayload);
|
||||
roomService.updateRoomMetadata(roomId, nextItem.metadata);
|
||||
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'video_update',
|
||||
video: videoPayload,
|
||||
metadata: nextItem.metadata
|
||||
});
|
||||
|
||||
broadcastToRoom(roomId, {
|
||||
type: 'queue_update',
|
||||
queue: room.queue
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('Unknown message type:', data.type);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user