1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-06-25 22:23:16 +00:00

Add songdetails modal

This commit is contained in:
jcorporation 2018-07-09 18:28:28 +01:00
parent cfd20a36fd
commit ff2b40baf8
5 changed files with 144 additions and 39 deletions

View File

@ -50,7 +50,7 @@ button {
}
}
tbody {
.clickable {
cursor: pointer;
}
@ -58,7 +58,7 @@ tbody {
width: 30px;
}
#album-cover {
.album-cover {
background-size:cover;
border:1px solid black;
border-radius:5px;

View File

@ -76,7 +76,7 @@
<div class="card" id="cardPlayback">
<div class="card-header">Now playing</div>
<div class="card-body">
<div id="album-cover"></div>
<div class="album-cover" id="album-cover"></div>
<h1 id="currenttrack"></h1>
<h3 id="artist"></h3>
<h4 id="album"></h4>
@ -88,7 +88,6 @@
<p id="counter" class="text">&nbsp;&nbsp;</p>
</div>
</div>
<p id="kbitrate"></p>
</div>
</div>
@ -157,7 +156,7 @@
<th></th>
</tr>
</thead>
<tbody>
<tbody class="clickable">
</tbody>
</table>
</div>
@ -227,7 +226,7 @@
<th></th>
</tr>
</thead>
<tbody>
<tbody class="clickable">
</tbody>
</table>
</div>
@ -283,7 +282,7 @@
<th></th>
</tr>
</thead>
<tbody>
<tbody class="clickable">
</tbody>
</table>
</div>
@ -351,7 +350,7 @@
<th></th>
</tr>
</thead>
<tbody>
<tbody class="clickable">
</tbody>
</table>
</div>
@ -429,7 +428,7 @@
<th></th>
</tr>
</thead>
<tbody>
<tbody class="clickable">
</tbody>
</table>
</div>
@ -657,7 +656,7 @@
<div class="row">
<div class="form-group col-md-9">
<label class="control-label" for="playlistname">Playlist Name</label>
<input type="text" class="form-control" id="playlistname" />
<input type="text" class="form-control" id="playlistname"/>
</div>
</div>
</form>
@ -669,7 +668,37 @@
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script src="js/bootstrap-native-v4.min.js"></script>
<script src="js/mpd.js"></script>
<div class="modal fade" id="modalSongDetails" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="savequeueLabel"><span class="material-icons">music_note</span> Song Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="album-cover"></div>
<h1></h1>
<table class="table">
<tbody>
<tr data-name="artist"><td>Artist</td><td></td></tr>
<tr data-name="album"><td>Album</td><td></td></tr>
<tr data-name="albumartist"><td>Albumartist</td><td></td></tr>
<tr data-name="genre"><td>Genre</td><td></td></tr>
<tr data-name="uri"><td>Uri</td><td></td></tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script src="js/bootstrap-native-v4.min.js" type="text/javascript"></script>
<script src="js/mpd.js" type="text/javascript"></script>
</body>
</html>

View File

@ -66,12 +66,12 @@ domCache.btnNext = document.getElementById('btnNext');
domCache.progressBar = document.getElementById('progressBar');
domCache.volumeBar = document.getElementById('volumeBar');
domCache.outputs = document.getElementById('outputs');
domCache.kbitrate = document.getElementById('kbitrate');
var modalConnectionError = new Modal(document.getElementById('modalConnectionError'));
var modalSettings = new Modal(document.getElementById('modalSettings'));
var modalAddstream = new Modal(document.getElementById('modalAddstream'));
var modalSavequeue = new Modal(document.getElementById('modalSavequeue'));
var modalSongDetails = new Modal(document.getElementById('modalSongDetails'));
var mainMenu = new Dropdown(document.getElementById('mainMenu'));
function appPrepare(scrollPos) {
@ -295,19 +295,19 @@ function appInit() {
document.getElementById('modalAbout').addEventListener('shown.bs.modal', function () {
sendAPI({"cmd": "MPD_API_GET_STATS"}, parseStats);
})
});
document.getElementById('modalSettings').addEventListener('shown.bs.modal', function () {
getSettings();
document.getElementById('settingsFrm').classList.remove('was-validated');
document.getElementById('inputCrossfade').classList.remove('is-invalid');
document.getElementById('inputMixrampdb').classList.remove('is-invalid');
document.getElementById('inputMixrampdelay').classList.remove('is-invalid');
})
});
document.getElementById('modalAddstream').addEventListener('shown.bs.modal', function () {
document.getElementById('streamurl').focus();
})
});
document.getElementById('addstreamFrm').addEventListener('submit', function () {
addStream();
@ -720,8 +720,6 @@ function parseState(obj) {
total_minutes + ":" + (total_seconds < 10 ? '0' : '') + total_seconds;
domCache.counter.innerText = counterText;
domCache.kbitrate.innerText = 'Bitrate: ' + obj.data.kbitrate + ' kbit';
//Set playing track in queue view
if (last_state) {
var tr = document.getElementById('queueTrackId' + last_state.data.currentsongid);
@ -790,6 +788,7 @@ function parseQueue(obj) {
row.setAttribute('id','queueTrackId' + obj.data[i].id);
row.setAttribute('data-songpos', (obj.data[i].pos + 1));
row.setAttribute('data-duration', duration);
row.setAttribute('data-uri', obj.data[i].uri);
row.innerHTML = '<td>' + (obj.data[i].pos + 1) + '</td>' +
'<td>' + obj.data[i].title + '</td>' +
'<td>' + obj.data[i].artist + '</td>' +
@ -958,7 +957,7 @@ function parseListDBtags(obj) {
if (nrItems == 0)
tbody.innerHTML = '<tr><td><span class="material-icons">error_outline</span></td>' +
'<td colspan="5">No entries found.</td></tr>'
'<td colspan="5">No entries found.</td></tr>';
document.getElementById('BrowseDatabaseArtistList').classList.remove('opacity05');
} else if (obj.tagtype == 'Album') {
@ -966,7 +965,7 @@ function parseListDBtags(obj) {
document.getElementById('BrowseDatabaseArtistList').classList.add('hide');
document.getElementById('btnBrowseDatabaseArtist').classList.remove('hide');
var nrItems = obj.data.length;
var cardContainer = document.getElementById('BrowseDatabaseAlbumCards')
var cardContainer = document.getElementById('BrowseDatabaseAlbumCards');
var cards = cardContainer.querySelectorAll('.col-md');
for (var i = 0; i < nrItems; i++) {
var id=genId(obj.data[i].value);
@ -1083,15 +1082,15 @@ function appendQueue(type, uri, name) {
switch(type) {
case 'song':
sendAPI({"cmd": "MPD_API_ADD_TRACK", "data": {"uri": uri}});
showNotification('"' + name + '" added','','','success');
showNotification('"' + name + '" added', '', '', 'success');
break;
case 'dir':
sendAPI({"cmd": "MPD_API_ADD_TRACK", "data": {"uri": uri}});
showNotification('"' + name + '" added','','','success');
showNotification('"' + name + '" added', '', '', 'success');
break;
case 'plist':
sendAPI({"cmd": "MPD_API_ADD_PLAYLIST", "data": {"plist": uri}});
showNotification('"' + name + '" added','','','success');
showNotification('"' + name + '" added', '', '', 'success');
break;
}
}
@ -1113,19 +1112,45 @@ function replaceQueue(type, uri, name) {
switch(type) {
case 'song':
sendAPI({"cmd": "MPD_API_REPLACE_TRACK", "data": {"uri": uri}});
showNotification('"' + name + '" replaced','','','success');
showNotification('"' + name + '" replaced', '', '', 'success');
break;
case 'dir':
sendAPI({"cmd": "MPD_API_REPLACE_TRACK", "data": {"uri": uri}});
showNotification('"' + name + '" replaced','','','success');
showNotification('"' + name + '" replaced', '', '', 'success');
break;
case 'plist':
sendAPI({"cmd": "MPD_API_REPLACE_PLAYLIST", "data": {"plist": uri}});
showNotification('"' + name + '" replaced','','','success');
showNotification('"' + name + '" replaced', '', '', 'success');
break;
}
}
function songDetails(uri) {
sendAPI({"cmd": "MPD_API_GET_SONGDETAILS", "data": {"uri": uri}}, parseSongDetails);
modalSongDetails.show();
}
function parseSongDetails(obj) {
var modal = document.getElementById('modalSongDetails');
modal.querySelector('.album-cover').style.backgroundImage = 'url(' + obj.data.cover + ')';
modal.getElementsByTagName('h1')[0].innerText = obj.data.title;
var tr = modal.getElementsByTagName('tr');
var trLen = tr.length;
for (var i = 0; i < trLen; i ++) {
var key = tr[i].getAttribute('data-name');
var value = obj.data[key];
if (key == 'duration') {
var minutes = Math.floor(value / 60);
var seconds = value - minutes * 60;
value = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
}
else if (key == 'uri') {
value = '<a class="text-success" href="/library/' + value + '">' + value + '</a>';
}
tr[i].getElementsByTagName('td')[1].innerHTML = value;
}
}
function showMenu(el) {
var type = el.getAttribute('data-type');
var uri = decodeURI(el.getAttribute('data-uri'));
@ -1144,11 +1169,11 @@ function showMenu(el) {
( type != 'plist' ? '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendAfterQueue\', \'options\': [\'' + type + '\',\'' +
uri + '\',' + last_state.data.nextsongpos + ',\'' + name + '\']}">Add after current playing song</a>' : '') +
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'replaceQueue\', \'options\': [\'' + type + '\',\'' +
uri + '\',\'' + name + '\']}">Replace queue</a>';
/* ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#">Add to playlist</a>' : '') +
uri + '\',\'' + name + '\']}">Replace queue</a>' +
// ( type != 'plist' ? '<div class="dropdown-divider"></div><a class="dropdown-item" href="#">Add to playlist</a>' : '') +
( type != 'dir' ? '<div class="dropdown-divider"></div>' : '') +
( type == 'song' ? '<a class="dropdown-item" href="#">Songdetails</a>' : '') +
( type == 'plist' ? '<a class="dropdown-item" href="#">Show playlist</a>' : '');*/
( type == 'song' ? '<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>' : '');
// ( type == 'plist' ? '<a class="dropdown-item" href="#">Show playlist</a>' : '');
}
else if (app.current.app == 'Browse' && app.current.tab == 'Playlists') {
menu += '<a class="dropdown-item" href="#" data-href="{\'cmd\': \'appendQueue\', \'options\': [\'' + type + '\',\'' +
@ -1167,9 +1192,9 @@ function showMenu(el) {
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'range\',0,'+
el.parentNode.parentNode.getAttribute('data-songpos') + ']}">Remove all upwards</a>' +
'<a class="dropdown-item" href="#" data-href="{\'cmd\': \'delQueueSong\', \'options\': [\'range\',' +
(parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1) + ',-1]}">Remove all downwards</a>';
// '<div class="dropdown-divider"></div>' +
// '<a class="dropdown-item" href="#">Songdetails</a>';
(parseInt(el.parentNode.parentNode.getAttribute('data-songpos'))-1) + ',-1]}">Remove all downwards</a>' +
'<div class="dropdown-divider"></div>' +
'<a class="dropdown-item" data-href="{\'cmd\': \'songDetails\', \'options\': [\'' + uri + '\']}" href="#">Songdetails</a>';
}
if (el.Popover == undefined) {
new Popover(el, { trigger: 'click', template: '<div class="popover" role="tooltip">' +
@ -1363,7 +1388,7 @@ function showNotification(notificationTitle,notificationText,notificationHtml,no
var alertBox;
if (!document.getElementById('alertBox')) {
alertBox = document.createElement('div');
alertBox.setAttribute('id','alertBox');
alertBox.setAttribute('id', 'alertBox');
}
else {
alertBox = document.getElementById('alertBox');
@ -1426,7 +1451,7 @@ function songChange(obj) {
if (playingTr)
playingTr.getElementsByTagName('td')[1].innerText = obj.data.title;
showNotification(obj.data.title,textNotification,htmlNotification,'success');
showNotification(obj.data.title, textNotification, htmlNotification, 'success');
last_song = cur_song;
}

View File

@ -210,11 +210,18 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg)
break;
case MPD_API_GET_CURRENT_SONG:
n = mympd_put_current_song(mpd.buf);
break;
case MPD_API_GET_SONGDETAILS:
je = json_scanf(msg.p, msg.len, "{ data: { uri:%Q } }", &p_charbuf1);
if (je == 1) {
n = mympd_put_songdetails(mpd.buf, p_charbuf1);
free(p_charbuf1);
}
break;
case MPD_API_GET_ARTISTS:
je = json_scanf(msg.p, msg.len, "{ data: { offset:%u, filter:%Q } }", &uint_buf1, &p_charbuf1);
if (je == 2) {
n = mympd_put_db_tag(mpd.buf, uint_buf1, "AlbumArtist","","",p_charbuf1);
n = mympd_put_db_tag(mpd.buf, uint_buf1, "AlbumArtist", "", "", p_charbuf1);
free(p_charbuf1);
}
break;
@ -514,6 +521,16 @@ char* mympd_get_title(struct mpd_song const *song)
return str;
}
char* mympd_get_genre(struct mpd_song const *song)
{
char *str;
str = (char *)mpd_song_get_tag(song, MPD_TAG_GENRE, 0);
if(str == NULL){
str = "-";
}
return str;
}
char* mympd_get_track(struct mpd_song const *song)
{
char *str;
@ -791,6 +808,37 @@ int mympd_put_current_song(char *buffer)
return len;
}
int mympd_put_songdetails(char *buffer, char *uri)
{
struct mpd_entity *entity;
const struct mpd_song *song;
int len;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
char cover[500];
len = json_printf(&out, "{type: song_details, data: {");
mpd_send_list_all_meta(mpd.conn, uri);
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
song = mpd_entity_get_song(entity);
mympd_get_cover(mpd_song_get_uri(song),cover,500);
len += json_printf(&out, "duration: %d, artist: %Q, album: %Q, title: %Q, albumartist: %Q, cover: %Q, uri: %Q, genre: %Q",
mpd_song_get_duration(song),
mympd_get_artist(song),
mympd_get_album(song),
mympd_get_title(song),
mympd_get_album_artist(song),
cover,
uri,
mympd_get_genre(song)
);
mpd_entity_free(entity);
}
len += json_printf(&out, "}}");
if (len > MAX_SIZE) fprintf(stderr,"Buffer truncated\n");
return len;
}
int mympd_put_queue(char *buffer, unsigned int offset)
{
struct mpd_entity *entity;
@ -815,13 +863,14 @@ int mympd_put_queue(char *buffer, unsigned int offset)
entity_count ++;
if (entity_count > offset && entity_count <= offset+MAX_ELEMENTS_PER_PAGE) {
if (entities_returned ++) len += json_printf(&out,",");
len += json_printf(&out, "{ id: %d, pos: %d, duration: %d, artist: %Q, album: %Q, title: %Q }",
len += json_printf(&out, "{ id: %d, pos: %d, duration: %d, artist: %Q, album: %Q, title: %Q, uri: %Q }",
mpd_song_get_id(song),
mpd_song_get_pos(song),
mpd_song_get_duration(song),
mympd_get_artist(song),
mympd_get_album(song),
mympd_get_title(song)
mympd_get_title(song),
mpd_song_get_uri(song)
);
}
}

View File

@ -80,6 +80,7 @@
X(MPD_API_GET_ARTISTALBUMTITLES) \
X(MPD_API_GET_ARTISTS) \
X(MPD_API_GET_CURRENT_SONG) \
X(MPD_API_GET_SONGDETAILS) \
X(MPD_API_WELCOME) \
X(MPD_API_GET_SETTINGS) \
X(MPD_API_SET_SETTINGS)
@ -144,6 +145,7 @@ int mympd_put_settings(char *buffer);
int mympd_put_db_tag(char *buffer, unsigned int offset, char *mpdtagtype, char *mpdsearchtagtype, char *searchstr, char *filter);
int mympd_put_songs_in_album(char *buffer, char *albumartist, char *album);
int mympd_put_playlists(char *buffer, unsigned int offset, char *filter);
int mympd_put_songdetails(char *buffer, char *uri);
void mympd_disconnect();
#endif