Add feature to allow insertion of track URI at any point in the queue.
Fixes #75.
This commit is contained in:
parent
f3a45d0780
commit
a9c998c8a5
@ -106,12 +106,17 @@ 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>`_).
|
||||
- Add 'Show Track Info' popup which can be activated from any context menu. The popup includes the URI of the track,
|
||||
which can be inserted into various lists elsewhere in the player.
|
||||
|
||||
**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.
|
||||
- Use correct icons for folders, audio, and other files when browsing local files.
|
||||
|
||||
v2.3.0 (2016-05-15)
|
||||
|
||||
@ -221,6 +221,17 @@ span.hostInfo {
|
||||
#homerows div i {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.ui-block-a-min {
|
||||
float: left !important;
|
||||
width: initial !important;
|
||||
}
|
||||
|
||||
.ui-block-b-min {
|
||||
float:right !important;
|
||||
width: initial !important;
|
||||
}
|
||||
|
||||
/***************
|
||||
* listviews *
|
||||
***************/
|
||||
@ -249,6 +260,21 @@ span.hostInfo {
|
||||
border-bottom: 1px solid #CECECE;
|
||||
}
|
||||
|
||||
.info-table td {
|
||||
color: #555 !important;
|
||||
padding: 2px;
|
||||
padding-right: 4px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.info-table td.label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-table td.label-center {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.albumdivider h1, .table li h1 {
|
||||
font-size: 120% !important;
|
||||
}
|
||||
@ -327,7 +353,6 @@ span.hostInfo {
|
||||
/**********************
|
||||
* Now Playing area *
|
||||
**********************/
|
||||
|
||||
#nowPlayingFooter {
|
||||
height: 50px;
|
||||
line-height: 48px;
|
||||
@ -406,6 +431,7 @@ span.hostInfo {
|
||||
.ui-icon-playAll:after,
|
||||
.ui-icon-play:after,
|
||||
.ui-icon-playNext:after,
|
||||
.ui-icon-insert:after,
|
||||
.ui-icon-add:after,
|
||||
.ui-icon-addAll:after,
|
||||
.ui-icon-remove:after {
|
||||
@ -425,6 +451,10 @@ span.hostInfo {
|
||||
content: '\f149';
|
||||
}
|
||||
|
||||
.ui-icon-insert:after {
|
||||
content: '\f177';
|
||||
}
|
||||
|
||||
.ui-icon-add:after {
|
||||
content: '\f196';
|
||||
}
|
||||
@ -461,7 +491,6 @@ span.hostInfo {
|
||||
/****************
|
||||
* Common use *
|
||||
****************/
|
||||
|
||||
#playlistspane {
|
||||
margin: 0 !important;
|
||||
}
|
||||
@ -545,7 +574,6 @@ a {
|
||||
}
|
||||
|
||||
/*helper*/
|
||||
|
||||
.ui-loader h1 {
|
||||
color: #efefef;
|
||||
}
|
||||
@ -570,6 +598,7 @@ a {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*smartphones*/
|
||||
@media (max-width: 35em) {
|
||||
#nowPlayingpane {
|
||||
|
||||
@ -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"> </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">
|
||||
@ -150,6 +150,9 @@
|
||||
<h2>Artists</h2>
|
||||
<ul data-icon="false" data-inset="false" data-role="listview" class="popupArtistsLv"></ul>
|
||||
</div>
|
||||
<li>
|
||||
<a href="#" onclick="return controls.showInfoPopup('#popupTracks');">Show Track Info...</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -160,8 +163,11 @@
|
||||
<li data-icon="play">
|
||||
<a href="#" onclick="return controls.playQueueTrack();">Play <span class="popupTrackName"></span></a>
|
||||
</li>
|
||||
<li data-icon="insert">
|
||||
<a href="#" onclick="return controls.showAddTrackPopup();">Add a Track Below <span class="popupTrackName"></span></a>
|
||||
</li>
|
||||
<li data-icon="remove">
|
||||
<a href="#" onclick="return controls.removeTrack();">Remove from Queue</a>
|
||||
<a href="#" onclick="return controls.removeTrack('', mopidy);">Remove from Queue</a>
|
||||
</li>
|
||||
<li class="popupAlbumLi">
|
||||
<a href="#" onclick="showAlbumPopup('#popupQueue')">Show Album <span class="popupAlbumName"></span></a>
|
||||
@ -174,26 +180,50 @@
|
||||
<h2>Artists</h2>
|
||||
<ul data-icon="false" data-inset="false" data-role="listview" class="popupArtistsLv"></ul>
|
||||
</div>
|
||||
<li>
|
||||
<a href="#" onclick="return controls.showInfoPopup('#popupQueue');">Show Track Info...</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-role="popup" data-theme="b" id="popupAddTrack" class="popupDialog">
|
||||
<form>
|
||||
<p>Add a Track to the Queue
|
||||
<button class="btn" type="button" id="getPlayingBtn" title="Use URI of currently playing track" onclick="return controls.getCurrentlyPlaying('addTrackInput');">
|
||||
Get Currently Playing URI
|
||||
</button>
|
||||
<input id="addTrackInput" placeholder="Track URI" class="span2" data-clear-btn="true"
|
||||
onkeypress="return controls.checkDefaultButtonClick(event.keyCode, '#popupAddTrack');" type="text"/>
|
||||
<div class="ui-field-contain">
|
||||
<select name="select-add" id="select-add"></select>
|
||||
</div>
|
||||
<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(), mopidy);">
|
||||
Add
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div><!--/add track to 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>
|
||||
@ -223,6 +253,50 @@
|
||||
</form>
|
||||
</div><!--/confirm delete stream-->
|
||||
|
||||
<div data-role="popup" data-theme="b" id="popupShowInfo" class="popupDialog">
|
||||
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
|
||||
<form>
|
||||
<table data-role="table" data-mode="reflow" class="ui-responsive table-stroke info-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-priority="persist"></th>
|
||||
<th data-priority="persist"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="label">Name:</td>
|
||||
<td id="name-cell"></td>
|
||||
</tr>
|
||||
<tr id="album-row">
|
||||
<td class="label">Album:</td>
|
||||
<td id="album-cell"></td>
|
||||
</tr>
|
||||
<tr id="artist-row">
|
||||
<td class="label">Artist(s):</td>
|
||||
<td id="artist-cell"></td>
|
||||
</tr>
|
||||
<tr id="track-no-row">
|
||||
<td class="label">Track #:</td>
|
||||
<td id="track-no-cell"></td>
|
||||
</tr>
|
||||
<tr id="length-row">
|
||||
<td class="label">Length:</td>
|
||||
<td id="length-cell"></td>
|
||||
</tr>
|
||||
<tr id="bitrate-row">
|
||||
<td class="label">Bitrate:</td>
|
||||
<td id="bitrate-cell"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label label-center">URI:</td>
|
||||
<td><input type="text" id="uri-cell"></input></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div><!--/show track info-->
|
||||
|
||||
<div data-role="header" data-tap-toggle="false" id="header" data-position="fixed" class="header-breakpoint headerbtn">
|
||||
<a id="headermenubtn" href="#panel"><i class="fa fa-align-justify"></i></a>
|
||||
<h1 id="contentHeadline">Initializing...</h1>
|
||||
@ -343,10 +417,14 @@
|
||||
|
||||
<div data-role="content" class="pane" id="currentpane">
|
||||
<div class="ui-grid-a">
|
||||
<div class="ui-block-a">
|
||||
<div class="ui-block-a ui-block-a-min">
|
||||
<h4>Play Queue</h4>
|
||||
</div>
|
||||
<div align="right" class="ui-block-b" data-role="controlgroup" data-type="horizontal">
|
||||
<div align="right" class="ui-block-b ui-block-b-min">
|
||||
<div data-role="controlgroup" data-type="horizontal">
|
||||
<button class="btn" type="button" title="Add a track to the queue" onclick="return controls.showAddTrackPopup();">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
<button class="btn" type="button" title="Save queue to playlist" onclick="return controls.showSavePopup();">
|
||||
<i class="fa fa-bookmark-o"></i>
|
||||
</button>
|
||||
@ -355,6 +433,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-grid">
|
||||
<ul class="table" id="currenttable"></ul>
|
||||
</div>
|
||||
@ -430,7 +509,7 @@
|
||||
<div class="ui-block-a" style="padding: 5px">
|
||||
<form>
|
||||
<p>Play a specific stream/track and optionally save it to your favourites.
|
||||
<button class="btn" type="button" onclick="return controls.getCurrentlyPlaying();">
|
||||
<button class="btn" type="button" onclick="return controls.getCurrentlyPlaying('streamuriinput', 'streamnameinput');">
|
||||
Get currently playing
|
||||
</button>
|
||||
<input id="streamuriinput" placeholder="URI" class="span2" data-clear-btn="true"
|
||||
|
||||
219
mopidy_musicbox_webclient/static/js/controls.js
vendored
219
mopidy_musicbox_webclient/static/js/controls.js
vendored
@ -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.
|
||||
@ -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.')
|
||||
}
|
||||
@ -58,17 +62,16 @@
|
||||
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 (currentIndex === null && action === PLAY_NEXT) {
|
||||
// Tracklist is empty, start playing new tracks immediately.
|
||||
action = PLAY_NOW
|
||||
}
|
||||
controls._addTrackAtIndex(action, mopidy, trackUris, currentIndex)
|
||||
})
|
||||
})
|
||||
break
|
||||
case INSERT_AT_INDEX:
|
||||
controls._addTrackAtIndex(action, mopidy, trackUris, index)
|
||||
break
|
||||
case ADD_THIS_BOTTOM:
|
||||
case ADD_ALL_BOTTOM:
|
||||
@ -87,6 +90,7 @@
|
||||
throw new Error('Unexpected tracklist action identifier: ' + action)
|
||||
}
|
||||
|
||||
if (action !== INSERT_AT_INDEX) { // TODO: Add support for 'INSERT_AT_INDEX' to allow user to insert tracks in any playlist.
|
||||
if (window[$(document.body).data('on-track-click')] === DYNAMIC) {
|
||||
// Save last 'action' - will become default for future 'onClick' events
|
||||
var previousAction = $.cookie('onTrackClick')
|
||||
@ -95,6 +99,10 @@
|
||||
updatePlayIcons('', '', controls.getIconForAction(action))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#popupTracks').popup('close')
|
||||
$('#popupQueue').popup('close')
|
||||
},
|
||||
|
||||
/* Getter function for 'action' variable. Also checks config settings and cookies if required. */
|
||||
@ -120,6 +128,8 @@
|
||||
return 'fa fa-play-circle'
|
||||
case PLAY_NOW:
|
||||
return 'fa fa-play-circle-o'
|
||||
case INSERT_AT_INDEX:
|
||||
return 'fa fa-long-arrow-left'
|
||||
case PLAY_NEXT:
|
||||
return 'fa fa-level-down'
|
||||
case ADD_THIS_BOTTOM:
|
||||
@ -138,6 +148,7 @@
|
||||
switch (parseInt(action)) {
|
||||
case PLAY_NOW:
|
||||
case PLAY_NEXT:
|
||||
case INSERT_AT_INDEX:
|
||||
case ADD_THIS_BOTTOM:
|
||||
// Process single track
|
||||
trackUris.push(trackUri)
|
||||
@ -153,6 +164,27 @@
|
||||
return trackUris
|
||||
},
|
||||
|
||||
_addTrackAtIndex: function (action, mopidy, trackUris, index) {
|
||||
if (typeof index === 'undefined' || index === '') {
|
||||
throw new Error('No index provided for insertion.')
|
||||
}
|
||||
|
||||
var pos = index
|
||||
if (pos === null) {
|
||||
pos = 0
|
||||
} else {
|
||||
pos += 1
|
||||
}
|
||||
|
||||
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
|
||||
*********************************************************/
|
||||
@ -165,39 +197,107 @@
|
||||
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')
|
||||
removeTrack: function (tlid, mopidy) {
|
||||
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
|
||||
},
|
||||
|
||||
showAddTrackPopup: function (tlid) {
|
||||
$('#addTrackInput').val('')
|
||||
$('#select-add').empty()
|
||||
tlid = tlid || $('#popupQueue').data('tlid')
|
||||
if (typeof tlid !== 'undefined' && tlid !== '') {
|
||||
// Store the tlid of the track after which we want to perform the insert
|
||||
$('#popupAddTrack').data('tlid', $('#popupQueue').data('tlid'))
|
||||
$('#popupAddTrack').one('popupafterclose', function (event, ui) {
|
||||
// Ensure that popup attributes are reset when the popup is closed.
|
||||
$(this).removeData('tlid')
|
||||
})
|
||||
var trackName = popupData[$('#popupQueue').data('track')].name
|
||||
$('#select-add').append('<option value="6" selected="selected">Add Track Below \'' + trackName + '\'</option>')
|
||||
}
|
||||
if (typeof songdata.track.uri !== 'undefined' && songdata.track.uri !== '') {
|
||||
$('#getPlayingBtn').button('enable')
|
||||
} else {
|
||||
$('#getPlayingBtn').button('disable')
|
||||
}
|
||||
|
||||
$('#select-add').append('<option value="1">Play Added Track Next</option>') // PLAY_NEXT
|
||||
$('#select-add').append('<option value="2">Add Track to Bottom of Queue</option>') // ADD_THIS_BOTTOM
|
||||
$('#select-add').trigger('change')
|
||||
|
||||
$('#popupQueue').popup('close')
|
||||
$('#popupAddTrack').popup('open')
|
||||
},
|
||||
|
||||
addTrack: function (trackUri, mopidy) {
|
||||
var selection = parseInt($('#select-add').val())
|
||||
|
||||
if (selection === ADD_THIS_BOTTOM) {
|
||||
controls.addTrackToBottom(trackUri, mopidy)
|
||||
} else if (selection === PLAY_NEXT) {
|
||||
controls.insertTrack(trackUri, mopidy)
|
||||
} else if (selection === INSERT_AT_INDEX) {
|
||||
var tlid = $('#popupAddTrack').data('tlid')
|
||||
controls.insertTrack(trackUri, mopidy, tlid)
|
||||
} else {
|
||||
throw new Error('Unkown tracklist action selection option: ' + selection)
|
||||
}
|
||||
},
|
||||
|
||||
insertTrack: function (trackUri, mopidy, tlid) {
|
||||
if (typeof trackUri === 'undefined' || trackUri === '') {
|
||||
throw new Error('No track URI provided to insert.')
|
||||
}
|
||||
|
||||
if (typeof tlid !== 'undefined' && tlid !== '') {
|
||||
mopidy.tracklist.index({tlid: parseInt(tlid)}).then(function (index) {
|
||||
controls.playTracks(INSERT_AT_INDEX, mopidy, trackUri, CURRENT_PLAYLIST_TABLE, index)
|
||||
})
|
||||
} else {
|
||||
// No tlid provided, insert after current track.
|
||||
controls.playTracks(PLAY_NEXT, mopidy, trackUri, CURRENT_PLAYLIST_TABLE)
|
||||
}
|
||||
$('#popupAddTrack').popup('close')
|
||||
return false
|
||||
},
|
||||
|
||||
addTrackToBottom: function (trackUri, mopidy) {
|
||||
if (typeof trackUri === 'undefined' || trackUri === '') {
|
||||
throw new Error('No track URI provided to add.')
|
||||
}
|
||||
|
||||
controls.playTracks(ADD_THIS_BOTTOM, mopidy, trackUri, CURRENT_PLAYLIST_TABLE)
|
||||
$('#popupAddTrack').popup('close')
|
||||
return false
|
||||
},
|
||||
|
||||
showSavePopup: function () {
|
||||
mopidy.tracklist.getTracks().then(function (tracks) {
|
||||
if (tracks.length > 0) {
|
||||
@ -238,6 +338,71 @@
|
||||
})
|
||||
},
|
||||
|
||||
showInfoPopup: function (popupId) {
|
||||
showLoading(true)
|
||||
var uri = $(popupId).data('track')
|
||||
$(popupId).popup('close')
|
||||
mopidy.library.lookup({'uris': [uri]}).then(function (resultDict) {
|
||||
var uri = Object.keys(resultDict)[0]
|
||||
var track = resultDict[uri][0]
|
||||
$('#popupShowInfo #name-cell').text(track.name)
|
||||
if (track.album && track.album.name) {
|
||||
$('#popupShowInfo #album-cell').text(track.album.name)
|
||||
} else {
|
||||
$('#popupShowInfo #album-cell').text('(Not available)')
|
||||
}
|
||||
var artistNames = ''
|
||||
if (track.artists && track.artists.length > 0) {
|
||||
for (var i = 0; i < track.artists.length; i++) {
|
||||
if (i > 0) {
|
||||
artistNames = artistNames + ', '
|
||||
}
|
||||
artistNames = artistNames + track.artists[i].name
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to album artists.
|
||||
if (artistNames.length === 0 && track.album.artists && track.album.artists.length > 0) {
|
||||
for (i = 0; i < track.album.artists.length; i++) {
|
||||
if (i > 0) {
|
||||
artistNames = artistNames + ', '
|
||||
}
|
||||
artistNames = artistNames + track.album.artists[i].name
|
||||
}
|
||||
}
|
||||
if (artistNames.length > 0) {
|
||||
$('#popupShowInfo #artist-cell').text(artistNames)
|
||||
$('#popupShowInfo #artist-row').show()
|
||||
} else {
|
||||
$('#popupShowInfo #artist-row').hide()
|
||||
}
|
||||
if (track.track_no) {
|
||||
$('#popupShowInfo #track-no-cell').text(track.track_no)
|
||||
$('#popupShowInfo #track-no-row').show()
|
||||
} else {
|
||||
$('#popupShowInfo #track-no-row').hide()
|
||||
}
|
||||
if (track.duration) {
|
||||
var duration = new Date(track.length)
|
||||
$('#popupShowInfo #length-cell').text(duration.getUTCMinutes() + ':' + duration.getUTCSeconds())
|
||||
$('#popupShowInfo #length-row').show()
|
||||
} else {
|
||||
$('#popupShowInfo #length-row').hide()
|
||||
}
|
||||
if (track.bitrate) {
|
||||
$('#popupShowInfo #bitrate-cell').text(track.bitrate)
|
||||
$('#popupShowInfo #bitrate-row').show()
|
||||
} else {
|
||||
$('#popupShowInfo #bitrate-row').hide()
|
||||
}
|
||||
$('#popupShowInfo #uri-cell').val(uri)
|
||||
showLoading(false)
|
||||
$('#popupShowInfo').popup('open')
|
||||
$('#popupShowInfo #uri-cell').focus()
|
||||
$('#popupShowInfo #uri-cell').select()
|
||||
}, console.error)
|
||||
},
|
||||
|
||||
refreshPlaylists: function () {
|
||||
mopidy.playlists.refresh().then(function () {
|
||||
playlists = {}
|
||||
@ -448,8 +613,8 @@
|
||||
return false
|
||||
},
|
||||
|
||||
getCurrentlyPlaying: function () {
|
||||
$('#streamuriinput').val(songdata.track.uri)
|
||||
getCurrentlyPlaying: function (uriInput, nameInput) {
|
||||
$('#' + uriInput).val(songdata.track.uri)
|
||||
var name = songdata.track.name
|
||||
if (songdata.track.artists) {
|
||||
var artistStr = artistsToString(songdata.track.artists)
|
||||
@ -457,7 +622,7 @@
|
||||
name = artistStr + ' - ' + name
|
||||
}
|
||||
}
|
||||
$('#streamnameinput').val(name)
|
||||
$('#' + nameInput).val(name)
|
||||
return true
|
||||
},
|
||||
|
||||
|
||||
@ -69,6 +69,7 @@ ADD_THIS_BOTTOM = 2
|
||||
ADD_ALL_BOTTOM = 3
|
||||
PLAY_ALL = 4
|
||||
DYNAMIC = 5
|
||||
INSERT_AT_INDEX = 6
|
||||
|
||||
// the first part of Mopidy extensions which serve radio streams
|
||||
var radioExtensionsList = ['somafm', 'tunein', 'dirble', 'audioaddict']
|
||||
|
||||
@ -76,7 +76,6 @@ function setSongTitle (title, refresh_ui) {
|
||||
}
|
||||
|
||||
function setSongInfo (data) {
|
||||
// console.log(data, songdata);
|
||||
if (!data) { return }
|
||||
if (data.tlid === songdata.tlid) { return }
|
||||
if (!data.track.name || data.track.name === '') {
|
||||
@ -148,13 +147,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
|
||||
@ -205,6 +197,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,
|
||||
@ -217,6 +210,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
|
||||
}
|
||||
|
||||
@ -256,6 +254,11 @@ function initSocketevents () {
|
||||
controls.setPlayState(true)
|
||||
})
|
||||
|
||||
mopidy.on('event:trackPlaybackResumed', function (data) {
|
||||
setSongInfo(data.tl_track)
|
||||
controls.setPlayState(true)
|
||||
})
|
||||
|
||||
mopidy.on('event:playlistsLoaded', function (data) {
|
||||
showLoading(true)
|
||||
library.getPlaylists()
|
||||
@ -297,6 +300,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) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
CACHE MANIFEST
|
||||
|
||||
# 2017-01-06:v1
|
||||
# 2017-01-07:v1
|
||||
|
||||
NETWORK:
|
||||
*
|
||||
|
||||
@ -31,10 +31,13 @@
|
||||
throw new Error('DummyTracklist.add does not support deprecated "tracks" and "uri" parameters.')
|
||||
}
|
||||
|
||||
var position = params.at_position
|
||||
// Add tracks to end of tracklist if no position is provided
|
||||
params.at_position = params.at_position || this._tlTracks.length
|
||||
if (typeof position === 'undefined') {
|
||||
position = Math.max(0, this._tlTracks.length)
|
||||
}
|
||||
|
||||
var tlTrack
|
||||
var tlTracks = []
|
||||
for (var i = 0; i < params.uris.length; i++) {
|
||||
tlTrack = {
|
||||
tlid: this._nextTlid++,
|
||||
@ -42,11 +45,10 @@
|
||||
uri: params.uris[i]
|
||||
}
|
||||
}
|
||||
tlTracks.push(tlTrack)
|
||||
this._tlTracks.splice(params.at_position + i, 0, tlTrack)
|
||||
this._tlTracks.splice(position++, 0, tlTrack)
|
||||
}
|
||||
|
||||
return $.when(tlTracks)
|
||||
return $.when(this._tlTracks)
|
||||
}
|
||||
|
||||
/* Clears the tracklist */
|
||||
@ -54,6 +56,21 @@
|
||||
this._tlTracks = []
|
||||
}
|
||||
|
||||
/* Remove the matching tracks from the tracklist */
|
||||
DummyTracklist.prototype.remove = function (criteria) {
|
||||
this.filter(criteria).then( function (matches) {
|
||||
for (var i = 0; i < matches.length; i++) {
|
||||
for (var j = 0; j < this._tlTracks.length; j++) {
|
||||
if (this._tlTracks[j].track.uri === matches[i].track.uri) {
|
||||
this._tlTracks.splice(j, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
return $.when(this._tlTracks)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retuns a list containing tlTracks that contain the provided
|
||||
* criteria.uri or has ID criteria.tlid.
|
||||
@ -89,11 +106,11 @@
|
||||
/* Retuns index of the currently 'playing' track. */
|
||||
DummyTracklist.prototype.index = function (params) {
|
||||
if (!params) {
|
||||
if (this._tlTracks.length > 1) {
|
||||
// Always just assume that the second track is playing
|
||||
return $.when(1)
|
||||
} else {
|
||||
if (this._tlTracks.length > 0) {
|
||||
// Always just assume that the first track is playing
|
||||
return $.when(0)
|
||||
} else {
|
||||
return $.when(null)
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < this._tlTracks.length; i++) {
|
||||
@ -101,7 +118,17 @@
|
||||
return $.when(i)
|
||||
}
|
||||
}
|
||||
return $.when(0)
|
||||
return $.when(null)
|
||||
}
|
||||
|
||||
/* Returns the tracks in the tracklist */
|
||||
DummyTracklist.prototype.get_tl_tracks = function () {
|
||||
return $.when(this._tlTracks)
|
||||
}
|
||||
|
||||
/* Returns the length of the tracklist */
|
||||
DummyTracklist.prototype.get_length = function () {
|
||||
return $.when(this._tlTracks.length)
|
||||
}
|
||||
|
||||
return DummyTracklist
|
||||
|
||||
@ -13,7 +13,7 @@ describe('controls', function () {
|
||||
var mopidy
|
||||
var div_element
|
||||
var QUEUE_TRACKS = [ // Simulate an existing queue with three tracks loaded.
|
||||
{uri: 'track:tlTrackMock1'},
|
||||
{uri: 'track:tlTrackMock1'}, // <-- Currently playing track
|
||||
{uri: 'track:tlTrackMock2'},
|
||||
{uri: 'track:tlTrackMock3'}
|
||||
]
|
||||
@ -48,11 +48,8 @@ describe('controls', function () {
|
||||
mopidy.tracklist.clear()
|
||||
clearSpy.reset()
|
||||
mopidy.tracklist.add({uris: getUris(QUEUE_TRACKS)})
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
mopidy.playback.play.reset()
|
||||
addSpy.reset()
|
||||
mopidy.playback.play.reset()
|
||||
})
|
||||
|
||||
after(function () {
|
||||
@ -62,62 +59,62 @@ describe('controls', function () {
|
||||
|
||||
describe('#playTracks()', function () {
|
||||
it('PLAY_ALL should clear tracklist first before populating with tracks', function () {
|
||||
customTracklists[BROWSE_TABLE] = NEW_TRACKS
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, BROWSE_TABLE)
|
||||
customTracklists[CURRENT_PLAYLIST_TABLE] = NEW_TRACKS
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(clearSpy.called)
|
||||
})
|
||||
|
||||
it('should not clear tracklist for events other than PLAY_ALL', function () {
|
||||
customTracklists[BROWSE_TABLE] = NEW_TRACKS
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri, BROWSE_TABLE)
|
||||
customTracklists[CURRENT_PLAYLIST_TABLE] = NEW_TRACKS
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(clearSpy.notCalled)
|
||||
})
|
||||
|
||||
it('should raise exception if trackUri parameter is not provided and "track" data attribute is empty', function () {
|
||||
assert.throw(function () { controls.playTracks('', mopidy) }, Error)
|
||||
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, BROWSE_TABLE)
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(mopidy.playback.play.calledWithMatch({tlid: mopidy.tracklist._tlTracks[0].tlid}))
|
||||
})
|
||||
|
||||
it('should raise exception if playListUri parameter is not provided and "track" data attribute is empty', function () {
|
||||
assert.throw(function () { controls.playTracks('', mopidy, NEW_TRACKS[0].uri) }, Error)
|
||||
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, BROWSE_TABLE)
|
||||
controls.playTracks(PLAY_ALL, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(mopidy.playback.play.calledWithMatch({tlid: mopidy.tracklist._tlTracks[0].tlid}))
|
||||
})
|
||||
|
||||
it('should raise exception if unknown tracklist action is provided', function () {
|
||||
var getTrackURIsForActionStub = sinon.stub(controls, '_getTrackURIsForAction') // Stub to bypass earlier exception
|
||||
assert.throw(function () { controls.playTracks('99', mopidy, NEW_TRACKS[0].uri, BROWSE_TABLE) }, Error)
|
||||
assert.throw(function () { controls.playTracks('99', mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE) }, Error)
|
||||
getTrackURIsForActionStub.restore()
|
||||
})
|
||||
|
||||
it('should use "track" and "list" data attributes as fallback if parameters are not provided', function () {
|
||||
$('#popupTracks').data('track', 'track:trackMock1') // Simulate 'track:trackMock1' being clicked.
|
||||
$('#popupTracks').data('list', BROWSE_TABLE)
|
||||
customTracklists[BROWSE_TABLE] = NEW_TRACKS
|
||||
$('#popupTracks').data('list', CURRENT_PLAYLIST_TABLE)
|
||||
customTracklists[CURRENT_PLAYLIST_TABLE] = NEW_TRACKS
|
||||
|
||||
controls.playTracks(PLAY_ALL, mopidy)
|
||||
assert(mopidy.playback.play.calledWithMatch({tlid: mopidy.tracklist._tlTracks[0].tlid}))
|
||||
})
|
||||
|
||||
it('PLAY_NOW, PLAY_NEXT, and ADD_THIS_BOTTOM should only add one track to the tracklist', function () {
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 2, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NOW did not add correct track')
|
||||
addSpy.reset()
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(addSpy.calledWithMatch({at_position: 1, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NOW did not add correct track')
|
||||
|
||||
mopidy.tracklist.clear()
|
||||
mopidy.tracklist.add({uris: getUris(QUEUE_TRACKS)})
|
||||
|
||||
controls.playTracks(PLAY_NEXT, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 2, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not add correct track')
|
||||
addSpy.reset()
|
||||
|
||||
controls.playTracks(PLAY_NEXT, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(addSpy.calledWithMatch({at_position: 1, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not add correct track')
|
||||
|
||||
mopidy.tracklist.clear()
|
||||
mopidy.tracklist.add({uris: getUris(QUEUE_TRACKS)})
|
||||
addSpy.reset()
|
||||
|
||||
controls.playTracks(ADD_THIS_BOTTOM, mopidy, NEW_TRACKS[0].uri)
|
||||
controls.playTracks(ADD_THIS_BOTTOM, mopidy, NEW_TRACKS[0].uri, CURRENT_PLAYLIST_TABLE)
|
||||
assert(addSpy.calledWithMatch({uris: [NEW_TRACKS[0].uri]}), 'ADD_THIS_BOTTOM did not add correct track')
|
||||
})
|
||||
|
||||
@ -133,21 +130,36 @@ describe('controls', function () {
|
||||
assert(addSpy.calledWithMatch({uris: getUris(NEW_TRACKS)}), 'ADD_ALL_BOTTOM did not add correct tracks')
|
||||
})
|
||||
|
||||
it('PLAY_NOW and PLAY_NEXT should insert track after currently playing track', function () {
|
||||
it('PLAY_NEXT should insert track after currently playing track by default', function () {
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 2, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NOW did not insert track at correct position')
|
||||
assert(addSpy.calledWithMatch({at_position: 1, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not insert track at correct position')
|
||||
})
|
||||
|
||||
it('PLAY_NEXT should insert track after reference track index, if provided', function () {
|
||||
controls.playTracks(PLAY_NEXT, mopidy, NEW_TRACKS[0].uri, '', 0)
|
||||
assert(addSpy.calledWithMatch({at_position: 1, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not insert track at correct position')
|
||||
})
|
||||
|
||||
it('PLAY_NEXT should insert track even if queue is empty', function () {
|
||||
mopidy.tracklist.clear()
|
||||
controls.playTracks(PLAY_NEXT, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 0, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not insert track at correct position')
|
||||
})
|
||||
|
||||
it('PLAY_NOW should always insert track at current index', function () {
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 1, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NOW did not insert track at correct position')
|
||||
addSpy.reset()
|
||||
|
||||
mopidy.tracklist.clear()
|
||||
mopidy.tracklist.add({uris: getUris(QUEUE_TRACKS)})
|
||||
|
||||
controls.playTracks(PLAY_NEXT, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 2, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NEXT did not insert track at correct position')
|
||||
controls.playTracks(PLAY_NOW, mopidy, NEW_TRACKS[0].uri)
|
||||
assert(addSpy.calledWithMatch({at_position: 0, uris: [NEW_TRACKS[0].uri]}), 'PLAY_NOW did not insert track at correct position')
|
||||
})
|
||||
|
||||
it('only PLAY_NOW and PLAY_ALL should trigger playback', function () {
|
||||
controls.playTracks(PLAY_NOW, mopidy, 2)
|
||||
assert(mopidy.playback.play.calledWithMatch({tlid: mopidy.tracklist._tlTracks[2].tlid}), 'PLAY_NOW did not start playback of correct track')
|
||||
controls.playTracks(PLAY_NOW, mopidy)
|
||||
assert(mopidy.playback.play.calledWithMatch({tlid: mopidy.tracklist._tlTracks[0].tlid}), 'PLAY_NOW did not start playback of correct track')
|
||||
mopidy.playback.play.reset()
|
||||
|
||||
mopidy.tracklist.clear()
|
||||
@ -182,12 +194,12 @@ describe('controls', function () {
|
||||
it('should store last action in cookie if on-track-click mode is set to "DYNAMIC"', function () {
|
||||
$(document.body).data('on-track-click', 'DYNAMIC')
|
||||
var cookieStub = sinon.stub($, 'cookie')
|
||||
controls.playTracks(PLAY_NOW, mopidy, 2)
|
||||
controls.playTracks(PLAY_NOW, mopidy)
|
||||
assert(cookieStub.calledWithMatch('onTrackClick', PLAY_NOW, {expires: 365}))
|
||||
cookieStub.reset()
|
||||
|
||||
$(document.body).data('on-track-click', 'PLAY_NOW')
|
||||
controls.playTracks(PLAY_NOW, mopidy, 2)
|
||||
controls.playTracks(PLAY_NOW, mopidy)
|
||||
assert(cookieStub.notCalled)
|
||||
cookieStub.restore()
|
||||
})
|
||||
@ -245,9 +257,9 @@ describe('controls', function () {
|
||||
})
|
||||
|
||||
it('should get tracks from "playlistUri" for PLAY_ALL, and ADD_ALL_BOTTOM', function () {
|
||||
customTracklists[BROWSE_TABLE] = NEW_TRACKS
|
||||
customTracklists[CURRENT_PLAYLIST_TABLE] = NEW_TRACKS
|
||||
|
||||
var tracks = controls._getTrackURIsForAction(PLAY_ALL, NEW_TRACKS[0], BROWSE_TABLE)
|
||||
var tracks = controls._getTrackURIsForAction(PLAY_ALL, NEW_TRACKS[0], CURRENT_PLAYLIST_TABLE)
|
||||
assert.equal(tracks.length, NEW_TRACKS.length)
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
assert.equal(tracks[i], NEW_TRACKS[i].uri)
|
||||
@ -262,4 +274,90 @@ describe('controls', function () {
|
||||
assert.equal(controls._getTrackURIsForAction('0', 'mockUri')[0], 'mockUri')
|
||||
})
|
||||
})
|
||||
|
||||
describe('#insertTrack()', function () {
|
||||
it('should raise exception if no uri is provided', function () {
|
||||
assert.throw(function () { controls.insertTrack() }, Error)
|
||||
})
|
||||
|
||||
it('should insert track after currently playing track by default', function () {
|
||||
var tracklistLength = QUEUE_TRACKS.length
|
||||
var insertUri = NEW_TRACKS[0].uri
|
||||
|
||||
controls.insertTrack(insertUri, mopidy)
|
||||
|
||||
mopidy.tracklist.get_length().then(function (length) {
|
||||
assert.equal(length, tracklistLength + 1)
|
||||
})
|
||||
|
||||
mopidy.tracklist.index().then(function (index) {
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
assert.equal(tlTracks[index + 1].track.uri, insertUri)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('should insert track at provided index', function () {
|
||||
var tracklistLength = QUEUE_TRACKS.length
|
||||
var insertUri = NEW_TRACKS[0].uri
|
||||
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
controls.insertTrack(insertUri, mopidy, tlTracks[1].tlid)
|
||||
})
|
||||
|
||||
mopidy.tracklist.get_length().then(function (length) {
|
||||
assert.equal(length, tracklistLength + 1)
|
||||
})
|
||||
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
assert.equal(tlTracks[2].track.uri, insertUri)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#addTrackToBottom()', function () {
|
||||
it('should raise exception if no uri is provided', function () {
|
||||
assert.throw(function () { controls.addTrackToBottom() }, Error)
|
||||
})
|
||||
|
||||
it('should add track at bottom of tracklist', function () {
|
||||
var tracklistLength = QUEUE_TRACKS.length
|
||||
var insertUri = NEW_TRACKS[0].uri
|
||||
|
||||
controls.addTrackToBottom(insertUri, mopidy)
|
||||
|
||||
mopidy.tracklist.get_length().then(function (length) {
|
||||
assert.equal(length, tracklistLength + 1)
|
||||
})
|
||||
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
assert.equal(tlTracks[tlTracks.length - 1].track.uri, insertUri)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#removeTrack()', function () {
|
||||
it('should remove track', function () {
|
||||
var tracklistLength = QUEUE_TRACKS.length
|
||||
var deleteUri = QUEUE_TRACKS[1].uri
|
||||
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
controls.removeTrack(tlTracks[1].tlid, mopidy)
|
||||
})
|
||||
|
||||
mopidy.tracklist.get_length().then(function (length) {
|
||||
assert.equal(length, tracklistLength - 1)
|
||||
})
|
||||
|
||||
mopidy.tracklist.get_tl_tracks().then(function (tlTracks) {
|
||||
var found = false
|
||||
for (var i = 0; i < tlTracks.length; i++) {
|
||||
if (tlTracks[i].track.uri === deleteUri) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
assert(!found)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user