Add custom playlists

This commit is contained in:
2025-03-01 16:11:01 +01:00
parent 2fb5af4171
commit aa10b5b2cc
7 changed files with 450 additions and 10 deletions

View File

@@ -10,16 +10,22 @@ module.exports.roomExists = (roomId) => rooms[roomId] !== undefined;
module.exports.isRoomOpen = (roomId) => rooms[roomId] && rooms[roomId].state === 'waiting';
const initializeRoom = (roomId, user) => {
rooms[roomId] = {
members: [{...user, creator: true}],
settings: {},
state: 'waiting',
playlistVotes: {},
selectedPlaylist: null
};
};
module.exports.connectUserToRoom = (roomId, user) => {
roomId = roomId.toUpperCase();
if (rooms[roomId]) {
rooms[roomId].members.push({...user, creator: false});
} else {
rooms[roomId] = {
members: [{...user, creator: true}],
settings: {},
state: 'waiting'
};
initializeRoom(roomId, user);
}
console.log(`User ${user.name} connected to room ${roomId}`);
}
@@ -132,4 +138,32 @@ module.exports.getUserName = (userId) => {
}
}
return null;
};
module.exports.voteForPlaylist = (roomId, userId, playlistId) => {
if (!rooms[roomId]) return false;
const room = rooms[roomId];
if (room.state !== 'waiting') return false;
// Remove previous vote if exists
const previousVote = Object.entries(room.playlistVotes)
.find(([_, voters]) => voters.includes(userId));
if (previousVote) {
room.playlistVotes[previousVote[0]] =
room.playlistVotes[previousVote[0]].filter(id => id !== userId);
}
// Add new vote
if (!room.playlistVotes[playlistId]) {
room.playlistVotes[playlistId] = [];
}
room.playlistVotes[playlistId].push(userId);
return true;
};
module.exports.getPlaylistVotes = (roomId) => {
return rooms[roomId]?.playlistVotes || {};
};

View File

@@ -308,4 +308,24 @@ module.exports = (io) => (socket) => {
socket.emit("playlist-songs", { songs: youtubeService.getDefaultSongs() });
}
});
socket.on("get-playlist-options", async () => {
try {
const playlists = await youtubeService.getPlaylistDetails();
socket.emit("playlist-options", playlists);
} catch (error) {
console.error("Error fetching playlist options:", error);
socket.emit("error", { message: "Failed to load playlists" });
}
});
socket.on("vote-playlist", ({ playlistId }) => {
const roomId = roomController.getUserRoom(socket.id);
if (!roomId) return;
if (roomController.voteForPlaylist(roomId, socket.id, playlistId)) {
const votes = roomController.getPlaylistVotes(roomId);
io.to(roomId).emit("playlist-votes-updated", votes);
}
});
};

View File

@@ -1,6 +1,17 @@
const { google } = require('googleapis');
const youtube = google.youtube('v3');
const YOUTUBE_API_KEY = process.env.YOUTUBE_API_KEY;
const PLAYLIST_ID = "PLmXxqSJJq-yXrCPGIT2gn8b34JjOrl4Xf";
const PLAYLISTS = {
seventies: 'PLmXxqSJJq-yXrCPGIT2gn8b34JjOrl4Xf',
eighties: 'PLmXxqSJJq-yUvMWKuZQAB_8yxnjZaOZUp',
nineties: 'PLmXxqSJJq-yUF3jbzjF_pa--kuBuMlyQQ'
};
const API_KEY = process.env.YOUTUBE_API_KEY;
let cachedSongs = null;
let lastFetchTime = 0;
const CACHE_TTL = 3600000; // 1 hour
@@ -68,4 +79,38 @@ const getAvailableSongIds = async () => {
return songs.map(song => song.id);
};
module.exports = {fetchPlaylistSongs, getAvailableSongIds};
async function getPlaylistDetails() {
try {
const details = {};
for (const [genre, playlistId] of Object.entries(PLAYLISTS)) {
const response = await youtube.playlists.list({
key: API_KEY,
part: 'snippet,contentDetails',
id: playlistId
});
const playlist = response.data.items[0];
details[genre] = {
id: playlistId,
title: playlist.snippet.title,
description: playlist.snippet.description,
thumbnail: playlist.snippet.thumbnails.maxres || playlist.snippet.thumbnails.high,
songCount: playlist.contentDetails.itemCount,
votes: 0
};
}
return details;
} catch (error) {
console.error('Error fetching playlist details:', error);
throw error;
}
}
module.exports = {
fetchPlaylistSongs,
getAvailableSongIds,
PLAYLISTS,
getPlaylistDetails
};