1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-11-16 10:44:48 +00:00

Feat: "Add all" button in database browse mode #43

Feat: generate taglist from mpd setting "metadata_to_use"
This commit is contained in:
jcorporation 2018-09-11 19:59:22 +01:00
parent 5eb16aa17c
commit 1e39e7346d
4 changed files with 85 additions and 78 deletions

View File

@ -276,3 +276,8 @@ caption {
.modal-body .album-cover { .modal-body .album-cover {
float:none; float:none;
} }
#BrowseDatabaseAlbumListCaption {
width:100%;
margin-left: 15px;
}

View File

@ -134,16 +134,6 @@
<span id="searchqueuetagdesc">Any Tag</span> <span id="searchqueuetagdesc">Any Tag</span>
</button> </button>
<div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchqueuetag"> <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchqueuetag">
<h6 class="dropdown-header text-light">Search in Tag</h6>
<button type="button" class="btn btn-secondary btn-sm btn-block active" data-tag="any">Any Tag</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Title">Title</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Artist">Artist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Album">Album</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="AlbumArtist">AlbumArtist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Composer">Composer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Performer">Performer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Date">Date</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Genre">Genre</button>
</div> </div>
</div> </div>
</div> </div>
@ -302,13 +292,6 @@
<div class="btn-group mr-2"> <div class="btn-group mr-2">
<button id="btnBrowseDatabaseByTag" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">AlbumArtist</button> <button id="btnBrowseDatabaseByTag" class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">AlbumArtist</button>
<div class="dropdown-menu bg-dark px-2" id="BrowseDatabaseByTagDropdown"> <div class="dropdown-menu bg-dark px-2" id="BrowseDatabaseByTagDropdown">
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="AlbumArtist">AlbumArtist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Artist">Artist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Genre">Genre</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Album">Album</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Composer">Composer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Performer">Performer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Date">Date</button>
</div> </div>
</div> </div>
<div class="btn-group mr-2 hide"> <div class="btn-group mr-2 hide">
@ -356,7 +339,9 @@
</table> </table>
</div> </div>
<div id="BrowseDatabaseAlbumList" class="row hide"></div> <div id="BrowseDatabaseAlbumList" class="row hide">
<h2 id="BrowseDatabaseAlbumListCaption"></h2>
</div>
<div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom"> <div class="btn-toolbar hide" id="BrowseDatabaseButtonsBottom">
<div class="btn-group mr-2"> <div class="btn-group mr-2">
@ -465,16 +450,6 @@
<span id="searchtagsdesc">Any Tag</span> <span id="searchtagsdesc">Any Tag</span>
</button> </button>
<div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchtags"> <div class="dropdown-menu bg-dark dropdown-menu-right px-2" id="searchtags">
<h6 class="dropdown-header text-light">Search in Tag</h6>
<button type="button" class="btn btn-secondary btn-sm active btn-block" data-tag="any">Any Tag</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Title">Title</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Artist">Artist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Album">Album</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="AlbumArtist">AlbumArtist</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Composer">Composer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Performer">Performer</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Date">Date</button>
<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="Genre">Genre</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -198,15 +198,7 @@ function appRoute() {
sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange); sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange);
} }
else if (app.current.app == 'Queue' ) { else if (app.current.app == 'Queue' ) {
var btns = document.getElementById('searchqueuetag').getElementsByTagName('button'); selectTag('searchqueuetag', 'searchqueuetagdesc', app.current.filter);
var btnsLen = btns.length;
for (var i = 0; i < btnsLen; i++) {
btns[i].classList.remove('active');
if (btns[i].getAttribute('data-tag') == app.current.filter) {
btns[i].classList.add('active');
document.getElementById('searchqueuetagdesc').innerText = btns[i].innerText;
}
}
getQueue(); getQueue();
} }
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') { else if (app.current.app == 'Browse' && app.current.tab == 'Playlists' && app.current.view == 'All') {
@ -226,15 +218,7 @@ function appRoute() {
else { else {
sendAPI({"cmd": "MPD_API_DATABASE_TAG_LIST","data": {"offset": app.current.page, "filter": app.current.filter, "tag": app.current.view}}, parseListDBtags); sendAPI({"cmd": "MPD_API_DATABASE_TAG_LIST","data": {"offset": app.current.page, "filter": app.current.filter, "tag": app.current.view}}, parseListDBtags);
doSetFilterLetter('BrowseDatabaseFilter'); doSetFilterLetter('BrowseDatabaseFilter');
var btns = document.getElementById('BrowseDatabaseByTagDropdown').getElementsByTagName('button'); selectTag('BrowseDatabaseByTagDropdown', 'btnBrowseDatabaseByTag', app.current.view);
var btnsLen = btns.length;
for (var i = 0; i < btnsLen; i++) {
btns[i].classList.remove('active');
if (btns[i].getAttribute('data-tag') == app.current.view) {
btns[i].classList.add('active');
document.getElementById('btnBrowseDatabaseByTag').innerText = btns[i].innerText;
}
}
} }
} }
else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') { else if (app.current.app == 'Browse' && app.current.tab == 'Filesystem') {
@ -292,16 +276,7 @@ function appRoute() {
document.getElementById('SearchList').classList.remove('opacity05'); document.getElementById('SearchList').classList.remove('opacity05');
setPagination(0); setPagination(0);
} }
selectTag('searchtags', 'searchtagsdesc', app.current.filter);
var btns = document.getElementById('searchtags').getElementsByTagName('button');
var btnsLen = btns.length;
for (var i = 0; i < btnsLen; i++) {
btns[i].classList.remove('active');
if (btns[i].getAttribute('data-tag') == app.current.filter) {
btns[i].classList.add('active');
document.getElementById('searchtagsdesc').innerText = btns[i].innerText;
}
}
} }
else { else {
appGoto("Playback"); appGoto("Playback");
@ -488,7 +463,7 @@ function appInit() {
document.getElementById('searchAddAllSongsDropdown').addEventListener('click', function(event) { document.getElementById('searchAddAllSongsDropdown').addEventListener('click', function(event) {
if (event.target.nodeName == 'BUTTON') { if (event.target.nodeName == 'BUTTON') {
if (event.target.innerText == 'Add all to queue') { if (event.target.innerText == 'Add all to queue') {
addAllFromSearch(); addAllFromSearchPlist('queue');
} }
else if (event.target.innerText == 'Add all to playlist') { else if (event.target.innerText == 'Add all to playlist') {
showAddToPlaylist('SEARCH'); showAddToPlaylist('SEARCH');
@ -496,6 +471,17 @@ function appInit() {
} }
}, false); }, false);
document.getElementById('BrowseDatabaseAddAllSongsDropdown').addEventListener('click', function(event) {
if (event.target.nodeName == 'BUTTON') {
if (event.target.innerText == 'Add all to queue') {
addAllFromBrowseDatabasePlist('queue');
}
else if (event.target.innerText == 'Add all to playlist') {
showAddToPlaylist('DATABASE');
}
}
}, false);
document.getElementById('searchtags').addEventListener('click', function(event) { document.getElementById('searchtags').addEventListener('click', function(event) {
if (event.target.nodeName == 'BUTTON') if (event.target.nodeName == 'BUTTON')
appGoto(app.current.app, app.current.tab, app.current.view, '0/' + event.target.getAttribute('data-tag') + '/' + app.current.search); appGoto(app.current.app, app.current.tab, app.current.view, '0/' + event.target.getAttribute('data-tag') + '/' + app.current.search);
@ -862,13 +848,17 @@ function parseSettings(obj) {
document.getElementsByClassName('mixramp')[0].style.display = 'none'; document.getElementsByClassName('mixramp')[0].style.display = 'none';
} }
settings=obj.data; settings = obj.data;
settings.mpdstream = 'http://'; settings.mpdstream = 'http://';
if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost') if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost')
settings.mpdstream += window.location.hostname; settings.mpdstream += window.location.hostname;
else else
settings.mpdstream += settings.mpdhost; settings.mpdstream += settings.mpdhost;
settings.mpdstream += ':' + settings.streamport + '/'; settings.mpdstream += ':' + settings.streamport + '/';
addTagList('BrowseDatabaseByTagDropdown', false);
addTagList('searchqueuetag', true);
addTagList('searchtags', true);
} }
function getSettings() { function getSettings() {
@ -1242,6 +1232,7 @@ function parseListDBtags(obj) {
document.getElementById('btnBrowseDatabaseTag').parentNode.classList.remove('hide'); document.getElementById('btnBrowseDatabaseTag').parentNode.classList.remove('hide');
document.getElementById('BrowseDatabaseAddAllSongs').parentNode.parentNode.classList.remove('hide'); document.getElementById('BrowseDatabaseAddAllSongs').parentNode.parentNode.classList.remove('hide');
document.getElementById('btnBrowseDatabaseTag').innerHTML = '&laquo; ' + app.current.view; document.getElementById('btnBrowseDatabaseTag').innerHTML = '&laquo; ' + app.current.view;
document.getElementById('BrowseDatabaseAlbumListCaption').innerText = obj.searchtagtype + ': ' + obj.searchstr;
var nrItems = obj.data.length; var nrItems = obj.data.length;
if (nrItems == 1 && obj.data[0].value == '') if (nrItems == 1 && obj.data[0].value == '')
nrItems = 0; nrItems = 0;
@ -1259,7 +1250,7 @@ function parseListDBtags(obj) {
card.innerHTML = '<div class="card mb-4" id="card' + id + '">' + card.innerHTML = '<div class="card mb-4" id="card' + id + '">' +
' <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a>' + ' <a href="#" class="card-img-top"><img class="card-img-top" src="" ></a>' +
' <div class="card-body">' + ' <div class="card-body">' +
' <h5 class="card-title">' + obj.searchstr + '</h5>' + ' <h5 class="card-title" id="albumartist' + id + '"></h5>' +
' <h4 class="card-title">' + obj.data[i].value + '</h4>' + ' <h4 class="card-title">' + obj.data[i].value + '</h4>' +
' <table class="table table-sm table-hover" id="tbl' + id + '"><tbody></tbody></table'+ ' <table class="table table-sm table-hover" id="tbl' + id + '"><tbody></tbody></table'+
' </div>'+ ' </div>'+
@ -1285,11 +1276,13 @@ function parseListDBtags(obj) {
document.getElementById('btnBrowseDatabaseByTag').parentNode.classList.remove('hide'); document.getElementById('btnBrowseDatabaseByTag').parentNode.classList.remove('hide');
document.getElementById('BrowseDatabaseAddAllSongs').parentNode.parentNode.classList.add('hide'); document.getElementById('BrowseDatabaseAddAllSongs').parentNode.parentNode.classList.add('hide');
document.getElementById('btnBrowseDatabaseTag').parentNode.classList.add('hide'); document.getElementById('btnBrowseDatabaseTag').parentNode.classList.add('hide');
if (obj.data[0] && obj.data[0].value == '')
obj.data.shift();
var nrItems = obj.data.length; var nrItems = obj.data.length;
if (nrItems == 1 && obj.data[0].value == '')
nrItems = 0;
var tbody = document.getElementById(app.current.app + app.current.tab + 'TagList').getElementsByTagName('tbody')[0]; var tbody = document.getElementById(app.current.app + app.current.tab + 'TagList').getElementsByTagName('tbody')[0];
var tr = tbody.getElementsByTagName('tr'); var tr = tbody.getElementsByTagName('tr');
var skipped = 0;
for (var i = 0; i < nrItems; i++) { for (var i = 0; i < nrItems; i++) {
var uri = encodeURI(obj.data[i].value); var uri = encodeURI(obj.data[i].value);
if (tr[i]) if (tr[i])
@ -1333,6 +1326,7 @@ function parseListTitles(obj) {
imga.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, ''))); imga.setAttribute('data-uri', encodeURI(obj.data[0].uri.replace(/\/[^\/]+$/, '')));
imga.setAttribute('data-name', obj.album); imga.setAttribute('data-name', obj.album);
imga.setAttribute('data-type', 'dir'); imga.setAttribute('data-type', 'dir');
document.getElementById('albumartist' + id).innerText = obj.albumartist;
var titleList = ''; var titleList = '';
var nrItems = obj.data.length; var nrItems = obj.data.length;
@ -1622,10 +1616,12 @@ function addToPlaylist() {
} }
} }
if (plist != '') { if (plist != '') {
if (uri != 'SEARCH') if (uri == 'SEARCH')
sendAPI({"cmd": "MPD_API_PLAYLIST_ADD_TRACK", "data": {"uri": uri, "plist": plist}});
else
addAllFromSearchPlist(plist); addAllFromSearchPlist(plist);
else if (uri == 'DATABASE')
addAllFromBrowseDatabasePlist(plist);
else
sendAPI({"cmd": "MPD_API_PLAYLIST_ADD_TRACK", "data": {"uri": uri, "plist": plist}});
modalAddToPlaylist.hide(); modalAddToPlaylist.hide();
} }
else { else {
@ -1950,13 +1946,6 @@ function addAllFromBrowseFilesystem() {
showNotification('Added all songs', '', '', 'success'); showNotification('Added all songs', '', '', 'success');
} }
function addAllFromSearch() {
if (app.current.search.length >= 2) {
sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": "queue", "filter": app.current.filter, "searchstr": app.current.search, "offset": 0}});
showNotification('Added '+ parseInt(document.getElementById('panel-heading-search').innerText) +' songs from search', '', '', 'success');
}
}
function addAllFromSearchPlist(plist) { function addAllFromSearchPlist(plist) {
if (app.current.search.length >= 2) { if (app.current.search.length >= 2) {
sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": plist, "filter": app.current.filter, "searchstr": app.current.search, "offset": 0}}); sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": plist, "filter": app.current.filter, "searchstr": app.current.search, "offset": 0}});
@ -1964,6 +1953,13 @@ function addAllFromSearchPlist(plist) {
} }
} }
function addAllFromBrowseDatabasePlist(plist) {
if (app.current.search.length >= 2) {
sendAPI({"cmd": "MPD_API_DATABASE_SEARCH", "data": {"plist": plist, "filter": app.current.view, "searchstr": app.current.search, "offset": 0}});
showNotification('Added songs from database selection to ' + plist, '', '', 'success');
}
}
function scrollTo(pos) { function scrollTo(pos) {
document.body.scrollTop = pos; // For Safari document.body.scrollTop = pos; // For Safari
document.documentElement.scrollTop = pos; // For Chrome, Firefox, IE and Opera document.documentElement.scrollTop = pos; // For Chrome, Firefox, IE and Opera
@ -2144,6 +2140,31 @@ function addFilterLetter(x) {
}, false); }, false);
} }
function selectTag(btnsEl, desc, setTo) {
var btns = document.getElementById(btnsEl);
var aBtn = btns.querySelector('.active')
if (aBtn)
aBtn.classList.remove('active');
aBtn = btns.querySelector('[data-tag=' + setTo + ']');
if (aBtn) {
aBtn.classList.add('active');
document.getElementById(desc).innerText = aBtn.innerText;
}
}
function addTagList(x, any) {
var tagList = '';
if (any == true)
tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>';
for (var key in settings.tags) {
if (settings.tags[key] == true && key != 'Track') {
tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="' + key + '">' + key + '</button>';
}
}
var tagListEl = document.getElementById(x);
tagListEl.innerHTML = tagList;
}
function gotoTagList() { function gotoTagList() {
appGoto(app.current.app, app.current.tab, app.current.view, '0/-/'); appGoto(app.current.app, app.current.tab, app.current.view, '0/-/');
} }
@ -2170,7 +2191,7 @@ function beautifyDuration(x) {
} }
function genId(x) { function genId(x) {
return 'id' + x.replace(/[^\w]/g, ''); return 'id' + x.replace(/[^\w\-\_]/g, '');
} }
//Init app //Init app

View File

@ -636,7 +636,7 @@ void mympd_mpd_features() {
if (mpd.tag_artist == false) if (mpd.tag_artist == false)
printf("WARNING: Artist tag not enabled in mpd\n"); printf("WARNING: Artist tag not enabled in mpd\n");
if (mpd.tag_album_artist == false) if (mpd.tag_album_artist == false)
printf("WARNING: Albumartist tag not enabled in mpd\n"); printf("WARNING: AlbumArtist tag not enabled in mpd\n");
if (mpd.tag_title == false) if (mpd.tag_title == false)
printf("WARNING: Title tag not enabled in mpd\n"); printf("WARNING: Title tag not enabled in mpd\n");
if (mpd.tag_track == false) if (mpd.tag_track == false)
@ -868,6 +868,8 @@ char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
if (str == NULL) { if (str == NULL) {
if (tag == MPD_TAG_TITLE) if (tag == MPD_TAG_TITLE)
str = basename((char *)mpd_song_get_uri(song)); str = basename((char *)mpd_song_get_uri(song));
else if (tag == MPD_TAG_ALBUM_ARTIST)
str = (char *)mpd_song_get_tag(song, MPD_TAG_ARTIST, 0);
else else
str = "-"; str = "-";
} }
@ -1419,6 +1421,7 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
unsigned long entities_returned = 0; unsigned long entities_returned = 0;
int len; int len;
char cover[500]; char cover[500];
char *albumartist;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
if (mpd_search_db_songs(mpd.conn, true) == false) if (mpd_search_db_songs(mpd.conn, true) == false)
@ -1440,9 +1443,10 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
if (entity_count <= MAX_ELEMENTS_PER_PAGE) { if (entity_count <= MAX_ELEMENTS_PER_PAGE) {
if (entities_returned ++) if (entities_returned ++)
len += json_printf(&out, ", "); len += json_printf(&out, ", ");
else else {
mympd_get_cover(mpd_song_get_uri(song), cover, 500); mympd_get_cover(mpd_song_get_uri(song), cover, 500);
albumartist = strdup(mympd_get_tag(song, MPD_TAG_ALBUM_ARTIST));
}
len += json_printf(&out, "{type: song, uri: %Q, duration: %d, title: %Q, track: %Q}", len += json_printf(&out, "{type: song, uri: %Q, duration: %d, title: %Q, track: %Q}",
mpd_song_get_uri(song), mpd_song_get_uri(song),
mpd_song_get_duration(song), mpd_song_get_duration(song),
@ -1453,15 +1457,17 @@ int mympd_put_songs_in_album(char *buffer, char *album, char *search, char *tag)
mpd_song_free(song); mpd_song_free(song);
} }
len += json_printf(&out, "], totalEntities: %d, returnedEntities: %d, album: %Q, search: %Q, tag: %Q, cover: %Q}", len += json_printf(&out, "], totalEntities: %d, returnedEntities: %d, album: %Q, search: %Q, tag: %Q, cover: %Q, albumartist: %Q}",
entity_count, entity_count,
entities_returned, entities_returned,
album, album,
search, search,
tag, tag,
cover cover,
albumartist
); );
} }
free(albumartist);
if (len > MAX_SIZE) if (len > MAX_SIZE)
printf("Buffer truncated\n"); printf("Buffer truncated\n");