Skip to content

Commit

Permalink
Add feature to allow insertion of track URI at any point in the queue.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcass77 committed Dec 11, 2016
1 parent c264bc5 commit 9bb9521
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 51 deletions.
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,15 @@ Changelog
v2.4.0 (UNRELEASED)
-------------------

- Add ability to insert a track anywhere in the current queue. (Addresses: `#75 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/75>`_).

**Fixes**

- Only show 'Show Album' or 'Show Artist' options in popup menus if URI's for those resources are available.
(Fixes: `#213 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/213>`_).
- Now shows correct hostname information in loader popup. (Fixes: `#209 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/209>`_).
- Now shows server name/IP address and port number at the bottom of the navigation pane. (Fixes: `#67 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/67>`_).
- Reset 'Now Playing' info when the last track in the tracklist is deleted. Fixes an issue where info of the last song played would be displayed even after the queue had been cleared.

v2.3.0 (2016-05-15)
-------------------
Expand Down
52 changes: 46 additions & 6 deletions mopidy_musicbox_webclient/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,14 @@

<h3 id="coverpopupalbumname"></h3>
<h4 id="coverpopupartist"></h4>
<a href="#" onclick="closePopups();"><img id="coverpopupimage" src="" alt="Album cover"/></a>
<a href="#" onclick="$('#coverpopup').popup('close');"><img id="coverpopupimage" src="" alt="Album cover"/></a>
</div>

<div id="artistpopup" data-role="popup" data-theme="c">
<a href="#" data-rel="back" data-role="button" data-icon="delete" data-iconpos="notext"
class="ui-btn-right">Close</a>
<h4 id="artistpopupname">&nbsp;</h4>
<a href="#" onclick="closePopups();"><img id="artistpopupimage" src="" alt="Album artist"/></a>
<a href="#" onclick="$('#artistpopup').popup('close');"><img id="artistpopupimage" src="" alt="Album artist"/></a>
</div>

<div data-role="popup" data-transition="none" data-theme="b" id="popupTracks">
Expand Down Expand Up @@ -160,6 +160,9 @@ <h2>Artists</h2>
<li data-icon="play">
<a href="#" onclick="return controls.playQueueTrack();">Play <span class="popupTrackName"></span></a>
</li>
<li data-icon="playNext">
<a href="#" onclick="return controls.showInsertTrackPopup();">Insert Track After This One</a>
</li>
<li data-icon="remove">
<a href="#" onclick="return controls.removeTrack();">Remove from Queue</a>
</li>
Expand All @@ -178,22 +181,53 @@ <h2>Artists</h2>
</div>
</div>

<div data-role="popup" data-theme="b" id="popupInsertTrack" class="popupDialog">
<form>
<p>Insert a Track to Play Next
<input id="insertTrackInput" placeholder="Track URI" class="span2" data-clear-btn="true"
onkeypress="return controls.checkDefaultButtonClick(event.keyCode, '#popupInsertTrack');" type="text"/>
<div data-role="controlgroup" data-type="horizontal" align="center">
<button class="btn" type="button" onclick="return $('#popupInsertTrack').popup('close');">
Cancel
</button>
<button class="btn" type="button" data-default-btn="true" onclick="return controls.insertTrack($('#insertTrackInput').val());">
Insert
</button>
</div>
</form>
</div><!--/insert track in queue to play next-->

<div data-role="popup" data-theme="b" id="popupAddTrack" class="popupDialog">
<form>
<p>Add a Track to End of Queue
<input id="addTrackInput" placeholder="Track URI" class="span2" data-clear-btn="true"
onkeypress="return controls.checkDefaultButtonClick(event.keyCode, '#popupAddTrack');" type="text"/>
<div data-role="controlgroup" data-type="horizontal" align="center">
<button class="btn" type="button" onclick="return $('#popupAddTrack').popup('close');">
Cancel
</button>
<button class="btn" type="button" data-default-btn="true" onclick="return controls.addTrack($('#addTrackInput').val());">
Add
</button>
</div>
</form>
</div><!--/add track to bottom of queue-->

<div data-role="popup" data-theme="b" id="popupSave" class="popupDialog">
<form>
<p>Save Current Queue to a Playlist
<input id="saveinput" placeholder="Playlist name" class="span2" data-clear-btn="true"
onkeypress="return controls.savePressed(event.keyCode);" type="text"/>
onkeypress="return controls.checkDefaultButtonClick(event.keyCode, '#popupSave');" type="text"/>
<div data-role="controlgroup" data-type="horizontal" align="center">
<button class="btn" type="button" onclick="return $('#popupSave').popup('close');">
Cancel
</button>
<button class="btn" type="button" onclick="return controls.saveQueue();">
<button class="btn" type="button" data-default-btn="true" onclick="return controls.saveQueue();">
Save
</button>
</div>
</form>
</div>
<!--/save queue to playlist-->
</div><!--/save queue to playlist-->

<div data-role="popup" data-theme="b" id="popupOverwrite" class="popupDialog">
<form>
Expand Down Expand Up @@ -347,6 +381,12 @@ <h4>Browse</h4>
<h4>Play Queue</h4>
</div>
<div align="right" class="ui-block-b" data-role="controlgroup" data-type="horizontal">
<button class="btn" type="button" title="Insert a Track to Play Next" onclick="return controls.showInsertTrackPopup();">
<i class="fa fa-level-down"></i>
</button>
<button class="btn" type="button" title="Add a Track to Bottom of Queue" onclick="return controls.showAddTrackPopup();">
<i class="fa fa-plus-square-o"></i>
</button>
<button class="btn" type="button" title="Save queue to playlist" onclick="return controls.showSavePopup();">
<i class="fa fa-bookmark-o"></i>
</button>
Expand Down
120 changes: 95 additions & 25 deletions mopidy_musicbox_webclient/static/js/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
* Adds tracks to current tracklist and starts playback if necessary.
*
* @param {string} action - The action to perform. Valid actions are:
* PLAY_NOW: add the track at 'trackIndex' and start playback.
* PLAY_NEXT: insert track after currently playing track.
* PLAY_NOW: add the track at the current queue position and
* start playback immediately.
* PLAY_NEXT: insert track after the reference track, if 'index'
* is provided, or after the current track otherwise.
* ADD_THIS_BOTTOM: add track to bottom of tracklist.
* ADD_ALL_BOTTOM: add all tracks in in the list to bottom of
* tracklist.
Expand All @@ -32,17 +34,19 @@
* @param {string} playlistUri - (Optional) The URI of the playlist containing the tracks
* to be played. If no URI is provided then the 'list' attribute
* of the popup DIV is assumed to contain the playlist URI.
* @param {string} index - (Optional) The tracklist index of the reference track that the
* action should be performed on. Defaults to the index of the currently
* playing track.
*/

playTracks: function (action, mopidy, trackUri, playlistUri) {
$('#popupTracks').popup('close')
toast('Loading...')
playTracks: function (action, mopidy, trackUri, playlistUri, index) {
toast('Updating queue...')

trackUri = trackUri || $('#popupTracks').data('track')
trackUri = trackUri || $('#popupTracks').data('track') || $('#popupQueue').data('track')
if (typeof trackUri === 'undefined') {
throw new Error('No track URI provided for playback.')
}
playlistUri = playlistUri || $('#popupTracks').data('list')
playlistUri = playlistUri || $('#popupTracks').data('list') || $('#popupQueue').data('list')
if (typeof playlistUri === 'undefined') {
throw new Error('No playlist URI provided for playback.')
}
Expand All @@ -58,17 +62,15 @@
switch (action) {
case PLAY_NOW:
case PLAY_NEXT:
// Find track that is currently playing.
mopidy.tracklist.index().then(function (currentIndex) {
// Add browsed track just below it.
mopidy.tracklist.add({at_position: currentIndex + 1, uris: trackUris}).then(function (tlTracks) {
if (action === PLAY_NOW) { // Start playback immediately.
mopidy.playback.stop().then(function () {
mopidy.playback.play({tlid: tlTracks[0].tlid})
})
}
if (action === PLAY_NOW || typeof index === 'undefined' || index === '') {
// Use current track as reference point for insertion.
mopidy.tracklist.index().then(function (currentIndex) {
controls._addTrackAtIndex(action, mopidy, trackUris, currentIndex)
})
})
} else {
// Use provided index for insertion.
controls._addTrackAtIndex(action, mopidy, trackUris, index)
}
break
case ADD_THIS_BOTTOM:
case ADD_ALL_BOTTOM:
Expand All @@ -95,6 +97,9 @@
updatePlayIcons('', '', controls.getIconForAction(action))
}
}

$('#popupTracks').popup('close')
$('#popupQueue').popup('close')
},

/* Getter function for 'action' variable. Also checks config settings and cookies if required. */
Expand Down Expand Up @@ -153,6 +158,29 @@
return trackUris
},

_addTrackAtIndex: function (action, mopidy, trackUris, index) {
var pos
if (index !== null) {
if (action === PLAY_NOW) {
// Insert at provided index.
pos = index
} else if (action === PLAY_NEXT) {
// Insert after provided index.
pos = index + 1
}
} else {
// Insert at top of queue
pos = 0
}
mopidy.tracklist.add({at_position: pos, uris: trackUris}).then(function (tlTracks) {
if (action === PLAY_NOW) { // Start playback immediately.
mopidy.playback.stop().then(function () {
mopidy.playback.play({tlid: tlTracks[0].tlid})
})
}
})
},

/** ******************************************************
* play an uri from the queue
*********************************************************/
Expand All @@ -165,39 +193,81 @@
playQueueTrack: function (tlid) {
// Stop directly, for user feedback
mopidy.playback.stop()
$('#popupQueue').popup('close')
toast('Loading...')

tlid = tlid || $('#popupQueue').data('tlid')
mopidy.playback.play({'tlid': parseInt(tlid)})
$('#popupQueue').popup('close')
},

/** *********************************
* remove a track from the queue *
***********************************/
removeTrack: function (tlid) {
$('#popupQueue').popup('close')
toast('Deleting...')

tlid = tlid || $('#popupQueue').data('tlid')
mopidy.tracklist.remove({'tlid': [parseInt(tlid)]})
$('#popupQueue').popup('close')
},

clearQueue: function () {
mopidy.tracklist.clear().then(
resetSong()
)
mopidy.tracklist.clear()
return false
},

savePressed: function (key) {
checkDefaultButtonClick: function (key, parentElement) {
// Click the default button on parentElement when the user presses the enter key.
if (key === 13) {
controls.saveQueue()
return false
$(parentElement).find('button' + '[data-default-btn="true"]').click()
}
return true
},

showInsertTrackPopup: function (tlid) {
$('#insertTrackInput').val('')
tlid = tlid || $('#popupQueue').data('tlid')
if (typeof tlid !== 'undefined' && tlid !== '') {
// Store the tlid of the track after which we want to perform the insert
$('#popupInsertTrack').data('tlid', $('#popupQueue').data('tlid'))
$('#popupInsertTrack').one('popupafterclose', function (event, ui) {
// Ensure that popup attributes are reset when the popup is closed.
$(this).removeData('tlid')
})
}
$('#popupQueue').popup('close')
$('#popupInsertTrack').popup('open')
},

insertTrack: function (trackUri) {
if (typeof trackUri !== 'undefined' && trackUri !== '') {
var tlid = $('#popupInsertTrack').data('tlid')
if (typeof tlid !== 'undefined' && tlid !== '') {
mopidy.tracklist.index({tlid: parseInt(tlid)}).then(function (index) {
controls.playTracks(PLAY_NEXT, mopidy, trackUri, 'undefined', index)
})
} else {
// No tlid provided, insert after current track.
controls.playTracks(PLAY_NEXT, mopidy, trackUri, 'undefined')
}
$('#popupInsertTrack').popup('close')
}
return false
},

showAddTrackPopup: function () {
$('#addTrackInput').val('')
$('#popupAddTrack').popup('open')
},

addTrack: function (trackUri) {
if (typeof trackUri !== 'undefined' && trackUri !== '') {
controls.playTracks(ADD_THIS_BOTTOM, mopidy, trackUri, 'undefined')
$('#popupAddTrack').popup('close')
}
return false
},

showSavePopup: function () {
mopidy.tracklist.getTracks().then(function (tracks) {
if (tracks.length > 0) {
Expand Down
19 changes: 12 additions & 7 deletions mopidy_musicbox_webclient/static/js/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,6 @@ function setSongInfo (data) {
/** ****************
* display popups *
******************/
function closePopups () {
$('#popupTracks').popup('close')
$('#artistpopup').popup('close')
$('#coverpopup').popup('close')
$('#popupQueue').popup('close')
}

function popupTracks (e, listuri, trackuri, tlid) {
if (!e) {
e = window.event
Expand Down Expand Up @@ -205,6 +198,7 @@ function popupTracks (e, listuri, trackuri, tlid) {
popupName = '#popupTracks'
}

// Set playlist, trackUri, and tlid of clicked item.
if (typeof tlid !== 'undefined' && tlid !== '') {
$(popupName).data('list', listuri).data('track', trackuri).data('tlid', tlid).popup('open', {
x: e.pageX,
Expand All @@ -217,6 +211,11 @@ function popupTracks (e, listuri, trackuri, tlid) {
})
}

$(popupName).one('popupafterclose', function (event, ui) {
// Ensure that popup attributes are reset when the popup is closed.
$(this).removeData('list').removeData('track').removeData('tlid')
})

return false
}

Expand Down Expand Up @@ -297,6 +296,12 @@ function initSocketevents () {

mopidy.on('event:tracklistChanged', function (data) {
library.getCurrentPlaylist()
mopidy.tracklist.getTracks().then(function (tracks) {
if (tracks.length === 0) {
// Last track in queue was deleted, reset UI.
resetSong()
}
})
})

mopidy.on('event:seeked', function (data) {
Expand Down
2 changes: 1 addition & 1 deletion mopidy_musicbox_webclient/static/mb.appcache
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CACHE MANIFEST

# 2016-12-11:v1
# 2016-12-11:v2

NETWORK:
*
Expand Down
2 changes: 1 addition & 1 deletion tests/js/dummy_tracklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
// Always just assume that the second track is playing
return $.when(1)
} else {
return $.when(0)
return $.when(null)
}
}
for (var i = 0; i < this._tlTracks.length; i++) {
Expand Down
Loading

0 comments on commit 9bb9521

Please sign in to comment.