Feat: enable smart playlist editing #38

This commit is contained in:
jcorporation 2018-10-01 18:07:38 +01:00
parent c4df10c71e
commit bf188ebdc2
3 changed files with 141 additions and 17 deletions

View File

@ -656,11 +656,55 @@
</div>
<div class="modal-body">
<form class="needs-validation" id="saveSmartPlaylistFrm" novalidate>
<div class="form-group">
<label for="saveSmartPlaylistName">Name</label>
<input type="text" class="form-control" id="saveSmartPlaylistName"/>
<div class="invalid-feedback">Invalid filename.</div>
<div class="row">
<div class="form-group col-md-6">
<label for="saveSmartPlaylistName">Name</label>
<input type="text" class="form-control" id="saveSmartPlaylistName"/>
<div class="invalid-feedback">Invalid filename.</div>
</div>
<div class="form-group col-md-6">
<label for="saveSmartPlaylistType">Type</label>
<input type="text" class="form-control" id="saveSmartPlaylistType" readonly/>
<div class="invalid-feedback">Invalid type.</div>
</div>
</div>
<hr/>
<div class="row" id="saveSmartPlaylistSearch" class="hide">
<div class="form-group col-md-6">
<label for="selectSaveSmartPlaylistTag">Tag</label>
<select id="selectSaveSmartPlaylistTag" class="form-control custom-select"></select>
</div>
<div class="form-group col-md-6">
<label for="inputSaveSmartPlaylistSearchstr">Search</label>
<input type="text" class="form-control" id="inputSaveSmartPlaylistSearchstr"/>
</div>
</div>
<div class="row" id="saveSmartPlaylistSticker" class="hide">
<div class="form-group col-md-6">
<label for="selectSaveSmartPlaylistSticker">Sticker</label>
<select id="selectSaveSmartPlaylistSticker" class="form-control custom-select">
<option value="like">Like</option>
<option value="playCount">playCount</option>
</select>
</div>
<div class="form-group col-md-6">
<label for="inputSaveSmartPlaylistStickerMaxentries">Max. entries</label>
<input type="text" class="form-control" id="inputSaveSmartPlaylistStickerMaxentries"/>
<div class="invalid-feedback">Must be a number.</div>
</div>
</div>
<div class="row" id="saveSmartPlaylistNewest" class="hide">
<div class="form-group col-md-6">
<label for="inputSaveSmartPlaylistNewestTimerange">Timerange (days)</label>
<input type="text" class="form-control" id="inputSaveSmartPlaylistNewestTimerange"/>
<div class="invalid-feedback">Must be a number.</div>
</div>
<div class="form-group col-md-6">
<label for="inputSaveSmartPlaylistNewestMaxentries">Max. entries</label>
<input type="text" class="form-control" id="inputSaveSmartPlaylistNewestMaxentries"/>
<div class="invalid-feedback">Must be a number.</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">

View File

@ -503,7 +503,7 @@ function appInit() {
showAddToPlaylist('SEARCH');
}
else if (event.target.innerText == 'Save as smart playlist') {
showSaveSmartPlaylist();
saveSearchAsSmartPlaylist();
}
}
}, false);
@ -1635,26 +1635,98 @@ function toggleAddToPlaylistFrm() {
}
}
function showSaveSmartPlaylist() {
function saveSearchAsSmartPlaylist() {
parseSmartPlaylist({"type": "smartpls", "data": {"playlist": "", "type": "search", "tag": app.current.filter, "searchstr": app.current.search}});
}
function parseSmartPlaylist(obj) {
var nameEl = document.getElementById('saveSmartPlaylistName');
nameEl.value = '';
nameEl.value = obj.data.playlist;
nameEl.classList.remove('is-invalid');
document.getElementById('saveSmartPlaylistType').value = obj.data.type;
document.getElementById('saveSmartPlaylistFrm').classList.remove('was-validated');
document.getElementById('saveSmartPlaylistSearch').classList.add('hide');
document.getElementById('saveSmartPlaylistSticker').classList.add('hide');
document.getElementById('saveSmartPlaylistNewest').classList.add('hide');
var tagList = '<option value="any">Any Tag</option>';
for (var key in settings.tags) {
if (settings.tags[key] == true && key != 'Track') {
tagList += '<option value="' + key + '">' + key + '</option>';
}
}
document.getElementById('selectSaveSmartPlaylistTag').innerHTML = tagList;
if (obj.data.type == 'search') {
document.getElementById('saveSmartPlaylistSearch').classList.remove('hide');
document.getElementById('selectSaveSmartPlaylistTag').value = obj.data.tag;
document.getElementById('inputSaveSmartPlaylistSearchstr').value = obj.data.searchstr;
}
else if (obj.data.type == 'sticker') {
document.getElementById('saveSmartPlaylistSticker').classList.remove('hide');
document.getElementById('selectSaveSmartPlaylistSticker').value = obj.data.sticker;
document.getElementById('inputSaveSmartPlaylistStickerMaxentries').value = obj.data.maxentries;
}
else if (obj.data.type == 'newest') {
document.getElementById('saveSmartPlaylistNewest').classList.remove('hide');
var timerange = obj.data.timerange / 24 / 60 / 60;
document.getElementById('inputSaveSmartPlaylistNewestTimerange').value = timerange;
document.getElementById('inputSaveSmartPlaylistNewestMaxentries').value = obj.data.maxentries;
}
modalSaveSmartPlaylist.show();
nameEl.focus();
}
function chkInt(el, frm) {
var value = el.value.replace(/\d/g,'');
if (value != '') {
el.classList.add('is-invalid');
frm.classList.add('was-validated');
return false;
} else {
el.classList.remove('is-invalid');
return true;
}
}
function saveSmartPlaylist() {
var value = document.getElementById('saveSmartPlaylistName').value;
var valid = value.replace(/[\w\-]/g, '');
if (value != '' && valid == '') {
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": "search", "playlist": value, "tag": app.current.filter, "searchstr": app.current.search}});
var name = document.getElementById('saveSmartPlaylistName').value;
var type = document.getElementById('saveSmartPlaylistType').value;
var valid = name.replace(/[\w\-]/g, '');
var frm = document.getElementById('saveSmartPlaylistFrm');
if (name != '' && valid == '') {
if (type == 'search') {
var tagEl = document.getElementById('selectSaveSmartPlaylistTag');
var tag = tagEl.options[tagEl.selectedIndex].value;
var searchstr = document.getElementById('inputSaveSmartPlaylistSearchstr').value;
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "tag": tag, "searchstr": searchstr}});
} else if (type == 'sticker') {
var stickerEl = document.getElementById('selectSaveSmartPlaylistSticker');
var sticker = stickerEl.options[stickerEl.selectedIndex].value;
var maxentriesEl = document.getElementById('inputSaveSmartPlaylistStickerMaxentries');
if (!chkInt(maxentriesEl, frm))
return;
var maxentries = maxentriesEl.value;
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "sticker": sticker, "maxentries": maxentries}});
} else if (type == 'newest') {
var timerangeEl = document.getElementById('inputSaveSmartPlaylistNewestTimerange');
if (!chkInt(timerangeEl, frm))
return;
var timerange = parseInt(timerangeEl.value) * 60 * 60 * 24;
var maxentriesEl = document.getElementById('inputSaveSmartPlaylistNewestMaxentries');
if (!chkInt(maxentriesEl, frm))
return;
var maxentries = maxentriesEl.value;
sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "timerange": timerange, "maxentries": maxentries}});
}
else {
document.getElementById('saveSmartPlaylistType').classList.add('is-invalid');
return;
}
modalSaveSmartPlaylist.hide();
showNotification('Saved smart playlist ' + value, '', '', 'success');
showNotification('Saved smart playlist ' + name, '', '', 'success');
}
else {
document.getElementById('saveSmartPlaylistName').classList.add('is-invalid');
document.getElementById('saveSmartPlaylistFrm').classList.add('was-validated');
frm.classList.add('was-validated');
}
}
@ -1763,6 +1835,10 @@ function renamePlaylist() {
}
}
function showSmartPlaylist(playlist) {
sendAPI({"cmd": "MPD_API_SMARTPLS_GET", "data": {"playlist": playlist}}, parseSmartPlaylist);
}
function dirname(uri) {
return uri.replace(/\/[^\/]*$/, '');
}
@ -1840,6 +1916,7 @@ function showMenu(el, event) {
menu += addMenuItem({"cmd": "appendQueue", "options": [type, uri, name]}, 'Append to queue') +
addMenuItem({"cmd": "replaceQueue", "options": [type, uri, name]},'Replace queue') +
(type == 'smartpls' ? addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'View playlist') : addMenuItem({"cmd": "playlistDetails", "options": [uri]}, 'Edit playlist'))+
(type == 'smartpls' ? addMenuItem({"cmd": "showSmartPlaylist", "options": [uri]}, 'Edit smart playlist') : '') +
(uri.indexOf('myMPDsmart') != 0 ?
addMenuItem({"cmd": "showRenamePlaylist", "options": [uri]}, 'Rename playlist') +
addMenuItem({"cmd": "delPlaylist", "options": [uri]}, 'Delete playlist') : '');

View File

@ -196,7 +196,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Smart Playlists update failed\"}");
break;
case MPD_API_SMARTPLS_SAVE:
je = json_scanf(msg.p, msg.len, "{data: {type: %Q}}", p_charbuf1);
je = json_scanf(msg.p, msg.len, "{data: {type: %Q}}", &p_charbuf1);
if (je == 1) {
if (strcmp(p_charbuf1, "sticker") == 0) {
je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, sticker: %Q, maxentries: %d}}", &p_charbuf2, &p_charbuf3, &int_buf1);
@ -2006,7 +2006,8 @@ int mympd_smartpls_put(char *buffer, char *playlist) {
if (strcmp(smartpltype, "sticker") == 0) {
je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1);
if (je == 2) {
len = json_printf(&out, "{type: smartpls, data: {type: %Q, sticker: %Q, maxentries: %d}",
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, sticker: %Q, maxentries: %d}}",
playlist,
smartpltype,
p_charbuf1,
int_buf1);
@ -2016,7 +2017,8 @@ int mympd_smartpls_put(char *buffer, char *playlist) {
else if (strcmp(smartpltype, "newest") == 0) {
je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2);
if (je == 2) {
len = json_printf(&out, "{type: smartpls, data: {type: %Q, timerange: %d, maxentries: %d}",
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, timerange: %d, maxentries: %d}}",
playlist,
smartpltype,
int_buf1,
int_buf2);
@ -2025,7 +2027,8 @@ int mympd_smartpls_put(char *buffer, char *playlist) {
else if (strcmp(smartpltype, "search") == 0) {
je = json_scanf(content, strlen(content), "{tag: %Q, searchstr: %Q}", &p_charbuf1, &p_charbuf2);
if (je == 2) {
len = json_printf(&out, "{type: smartpls, data: {type: %Q, tag: %d, searchstr: %d}",
len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, tag: %Q, searchstr: %Q}}",
playlist,
smartpltype,
p_charbuf1,
p_charbuf2);