Skip to content

Commit

Permalink
live playlist mode
Browse files Browse the repository at this point in the history
  • Loading branch information
IrosTheBeggar committed Feb 7, 2024
1 parent c37b87e commit b66c6d5
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 26 deletions.
25 changes: 11 additions & 14 deletions src/api/playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ exports.setup = (mstream) => {
db.getPlaylistCollection().insert({
name: req.body.title,
filepath: null,
user: req.user.username
user: req.user.username,
live: false
});

db.saveUserDB();
Expand All @@ -113,7 +114,7 @@ exports.setup = (mstream) => {
const schema = Joi.object({
title: Joi.string().required(),
songs: Joi.array().items(Joi.string()),
unlisted: Joi.boolean().optional()
live: Joi.boolean().optional()
});
joiValidate(schema, req.body);

Expand All @@ -134,13 +135,13 @@ exports.setup = (mstream) => {
}

// insert null entry
if (req.body.unlisted !== true) {
db.getPlaylistCollection().insert({
name: req.body.title,
filepath: null,
user: req.user.username
});
}
db.getPlaylistCollection().insert({
name: req.body.title,
filepath: null,
user: req.user.username,
live: typeof req.body.live === 'boolean' ? req.body.live : false
});


db.saveUserDB();
res.json({});
Expand All @@ -154,12 +155,8 @@ exports.setup = (mstream) => {
const playlists = [];

const results = db.getPlaylistCollection().find({ 'user': { '$eq': username }, 'filepath': { '$eq': null } });
const store = {};
for (let row of results) {
if (!store[row.name]) {
playlists.push({ name: row.name });
store[row.name] = true;
}
playlists.push({ name: row.name });
}
return playlists;
}
Expand Down
6 changes: 3 additions & 3 deletions webapp/alpha/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ const MSTREAMAPI = (() => {
return req('POST', mstreamModule.currentServer.host + 'api/v1/file-explorer/recursive', { directory: directory });
}

mstreamModule.savePlaylist = (title, songs, unlisted) => {
mstreamModule.savePlaylist = (title, songs, live) => {
const postData = { title: title, songs: songs };
if (unlisted !== undefined) {
postData.unlisted = unlisted;
if (live !== undefined) {
postData.live = live;
}
return req('POST', mstreamModule.currentServer.host + 'api/v1/playlist/save', postData);
}
Expand Down
69 changes: 64 additions & 5 deletions webapp/alpha/m.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ async function init() {
response.playlists.forEach(p => {
VUEPLAYERCORE.playlists.push(p);
document.getElementById('pop-f').innerHTML += `<div class="pop-list-item" onclick="addToPlaylistUI('${p.name}')">&#8226; ${p.name}</div>`;
document.getElementById('live-playlist-select').innerHTML += `<option value="${p.name}">${p.name}</option>`;
});

if (response.transcode) {
Expand Down Expand Up @@ -456,6 +457,26 @@ async function init() {
MSTREAMPLAYER.transcodeOptions.selectedAlgo = localStorage.getItem('trans-algo-select');
} catch (e) {}

try{
VUEPLAYERCORE.livePlaylist.name = localStorage.getItem('live-playlist-auto-start') ? localStorage.getItem('live-playlist-auto-start') : false;

if (VUEPLAYERCORE.livePlaylist.name) {
// get current playlist
const response = await MSTREAMAPI.loadPlaylist(VUEPLAYERCORE.livePlaylist.name);

// set the queue to the current playlist
MSTREAMPLAYER.clearPlaylist();
response.forEach(value => {
VUEPLAYERCORE.addSongWizard(value.filepath, value.metadata, false, undefined, false, true);
});

document.getElementById('set_live_playlist').classList.remove('green');
document.getElementById('set_live_playlist').classList.add('blue');
document.getElementById('set_live_playlist').value = 'Disable Live Playlist';
}

}catch(err) {}

dbStatus();
}

Expand Down Expand Up @@ -712,6 +733,7 @@ async function getAllPlaylists() {
const response = await MSTREAMAPI.getAllPlaylists();
VUEPLAYERCORE.playlists.length = 0;
document.getElementById('pop-f').innerHTML = '<div class="pop-f pop-playlist">Add To Playlist:</div>';
document.getElementById('live-playlist-select').innerHTML = `<option value="" disabled selected>Select Playlist</option>`;

// loop through the json array and make an array of corresponding divs
let playlists = '<ul class="collection">';
Expand All @@ -721,6 +743,7 @@ async function getAllPlaylists() {
currentBrowsingList.push(lol);
VUEPLAYERCORE.playlists.push(lol);
document.getElementById('pop-f').innerHTML += `<div class="pop-list-item" onclick="addToPlaylistUI('${p.name}')">&#8226; ${p.name}</div>`;
document.getElementById('live-playlist-select').innerHTML += `<option value="${p.name}">${p.name}</option>`;
});
playlists += '</ul>'

Expand Down Expand Up @@ -830,6 +853,7 @@ async function newPlaylist() {
document.getElementById("newPlaylistForm").reset();
VUEPLAYERCORE.playlists.push({ name: title, type: 'playlist'});
document.getElementById('pop-f').innerHTML += `<div class="pop-list-item" onclick="addToPlaylistUI('${title}')">&#8226; ${title}</div>`;
document.getElementById('live-playlist-select').innerHTML += `<option value="${title}">${title}</option>`;

if (programState[0].state === 'allPlaylists') {
getAllPlaylists();
Expand All @@ -844,23 +868,57 @@ async function setLivePlaylist() {
try{
document.getElementById('set_live_playlist').disabled = true;

let livePlaylistName;

if (document.getElementById('radio-use-existing').checked === true) {
if (document.getElementById('live-playlist-select').value === "") {
const err = new Error('No Playlist Selected');
err.responseJSON = { error: 'No Playlist Selected' };
throw err;
}
livePlaylistName = document.getElementById('live-playlist-select').value;
} else {
if (document.getElementById('new-live-playlist-name').value === "") {
const err = new Error('Playlist Name Required');
err.responseJSON = { error: 'Playlist Name Required' };
throw err;
}
livePlaylistName = document.getElementById('new-live-playlist-name').value;
}

// check if checkbox is checked
if(document.getElementById('persist_live_queue').checked === true) {
localStorage.setItem('live-playlist-auto-start', livePlaylistName)
} else {
localStorage.removeItem('live-playlist-auto-start');
}

if (VUEPLAYERCORE.livePlaylist.name !== false) {
VUEPLAYERCORE.livePlaylist.name = false;
document.getElementById('set_live_playlist').classList.remove('blue');
document.getElementById('set_live_playlist').classList.add('green');
document.getElementById('set_live_playlist').value = 'Enable Live Playlist';
} else {
// set live var
VUEPLAYERCORE.livePlaylist.name = 'default-live-playlist';
VUEPLAYERCORE.livePlaylist.name = livePlaylistName;

// get current playlist
const response = await MSTREAMAPI.loadPlaylist(VUEPLAYERCORE.livePlaylist.name);

// set the queue to the current playlist
MSTREAMPLAYER.clearPlaylist();
response.forEach(value => {
VUEPLAYERCORE.addSongWizard(value.filepath, value.metadata, false, undefined, false);
});
if (response.length > 0) {
MSTREAMPLAYER.clearPlaylist();
response.forEach(value => {
VUEPLAYERCORE.addSongWizard(value.filepath, value.metadata, false, undefined, false, true);
});
} else {
// save current queue
const songs = [];
for (let i = 0; i < MSTREAMPLAYER.playlist.length; i++) {
songs.push(MSTREAMPLAYER.playlist[i].filepath);
}
MSTREAMAPI.savePlaylist(livePlaylistName, songs, true);
}

document.getElementById('set_live_playlist').classList.remove('green');
document.getElementById('set_live_playlist').classList.add('blue');
Expand Down Expand Up @@ -911,6 +969,7 @@ async function savePlaylist() {

VUEPLAYERCORE.playlists.push({ name: title, type: 'playlist'});
document.getElementById('pop-f').innerHTML += `<div class="pop-list-item" onclick="addToPlaylistUI('${title}')">&#8226; ${title}</div>`;
document.getElementById('live-playlist-select').innerHTML += `<option value="${title}">${title}</option>`;
}catch(err) {
boilerplateFailure(err);
} finally {
Expand Down
4 changes: 4 additions & 0 deletions webapp/alpha/spa.css
Original file line number Diff line number Diff line change
Expand Up @@ -1001,4 +1001,8 @@ select {

.no-margin p {
margin: 0;
}

.make-white {
color: #FFF;
}
6 changes: 3 additions & 3 deletions webapp/alpha/vp.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ const VUEPLAYERCORE = (() => {
}
});

mstreamModule.addSongWizard = async (filepath, metadata, lookupMetadata, position, livePlaylist) => {
mstreamModule.addSongWizard = async (filepath, metadata, lookupMetadata, position, livePlaylist, autoPlayOff) => {
// Escape filepath
const rawFilepath = filepath;
filepath = filepath.replace(/\%/g, "%25");
Expand Down Expand Up @@ -563,19 +563,19 @@ const VUEPLAYERCORE = (() => {
};

if (position) {
MSTREAMPLAYER.insertSongAt(newSong, position, true);
if (mstreamModule.livePlaylist.name) {
const songs = [];
for (let i = 0; i < MSTREAMPLAYER.playlist.length; i++) {
songs.push(MSTREAMPLAYER.playlist[i].filepath);
}
MSTREAMAPI.savePlaylist(mstreamModule.livePlaylist.name,songs, true);
}
MSTREAMPLAYER.insertSongAt(newSong, position, true);
} else {
MSTREAMPLAYER.addSong(newSong, autoPlayOff);
if (mstreamModule.livePlaylist.name && livePlaylist !== false) {
await MSTREAMAPI.addToPlaylist(mstreamModule.livePlaylist.name, newSong.filepath);
}
MSTREAMPLAYER.addSong(newSong);
}

// perform lookup
Expand Down
28 changes: 27 additions & 1 deletion webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,33 @@ <h5>Live Playlist Mode</h5>
Using live playlist on two devices at the same time might result in some odd behavior
</p>
<form action="javascript:setLivePlaylist()">
<!-- <input id="playlist_name" autocomplete="off" type="text" required placeholder="Enter your playlist name" pattern="[a-zA-Z0-9 _-]+"> -->
<label for="persist_live_queue">
<input type="checkbox" checked class="filled-in" id="persist_live_queue" name="persist_live_queue" />
<span>Start Live Playlist Automatically</span>
</label>
<br>

<p>
<label>
<input class="with-gap" name="group1" type="radio" checked />
<span>Make a new playlist</span>
</label>
<input id="new-live-playlist-name" type="text" name="live-queue-name" placeholder="Playlist Name" autocomplete="off" class="make-white">
</p>

<p>
<label>
<input class="with-gap" name="group1" type="radio" id="radio-use-existing" />
<span>Use an existing playlist</span>
</label>
</p>
<p>
<select id="live-playlist-select" class="browser-default">
<option value="" disabled selected>Select Playlist</option>
</select>
<!-- <label>Materialize Select</label> -->
</p>

<input id="set_live_playlist" type="submit" class="btn green" value="Enable Live Playlist">
</form>
</div>
Expand Down

0 comments on commit b66c6d5

Please sign in to comment.