fix:Display album / artist information when browsing tracks.

Fixes #99. Fixes #126.
This commit is contained in:
jcass 2016-03-08 06:53:03 +02:00
parent c15c3fefd8
commit 21f16fb17b
9 changed files with 240 additions and 240 deletions

View File

@ -74,10 +74,12 @@ v2.3.0 (UNRELEASED)
-------------------
- Enhance build workflow to include style checks and syntax validation for HTML, CSS, and Javascript.
- Now displays album and artist info when browsing tracks. (Addresses: `#99 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/99>`_).
**Fixes**
- Don't create Mopidy models manually. (Fixes: `#172 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/172>`_).
- Context menu is now available for all tracks in browse pane. (Fixes: `#126 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/126>`_).
v2.2.0 (2016-03-01)
-------------------

View File

@ -36,7 +36,7 @@
margin-left: 10px;
}
#playlisttracksback {
.backnav-optional {
display: none;
}
@ -74,7 +74,7 @@
width: 100%;
}
#playlisttracksback {
.backnav-optional {
display: block;
}
@ -300,6 +300,10 @@
line-height: 100%;
}
.backnav {
background-color: #ccc !important;
}
/**********************
* Now Playing area *
@ -369,12 +373,14 @@
}
#popupTracksLv li,
#popupQueueLv li {
#popupQueueLv li,
#popupBrowseLv li {
border-bottom: 1px solid #aaa;
}
#popupTracksLv,
#popupQueueLv {
#popupQueueLv,
#popupBrowseLv li {
border: 1px solid #aaa;
}

View File

@ -56,7 +56,6 @@
<div data-role="page" id="page" class="ui-responsive-panel" data-theme="c">
<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="reveal" data-position-fixed="true">
<ul class="ui-listview mainNav" data-role="listview" data-theme="a">
<li id="navhome" data-icon="false">
<a href="#home" onclick="switchContent('home' ); return false;">
@ -164,8 +163,7 @@
<a href="#" onclick="return playTrack(ADD_THIS_BOTTOM);">Add Track to Bottom of Queue</a>
</li>
<li class="addqueue">
<a href="#" onclick="return playTrack(ADD_ALL_BOTTOM);" id="liaddtobottom">Add all to Bottom of
Queue</a>
<a href="#" onclick="return playTrack(ADD_ALL_BOTTOM);" id="liaddtobottom">Add all to Bottom of Queue</a>
</li>
<li>
<a href="#" onclick="showAlbumPopup('#popupTracks')">Show Album <span class="popupAlbumName"></span></a>
@ -206,7 +204,6 @@
</div>
</div>
<div data-role="popup" data-theme="b" id="popupSave" class="popupDialog">
<form>
<p>Save current queue to a playlist.
@ -224,7 +221,6 @@
</div>
<!--/save queue to playlist-->
<div data-role="popup" data-theme="b" id="popupOverwrite" class="popupDialog">
<form>
<p>Overwrite existing playlist with same name?
@ -307,12 +303,10 @@
</div>
<!--/homepane-->
<div id="nowPlayingpane" data-role="content" class="pane">
<img id="controlspopupimage" src="images/default_cover.png" alt="Album cover"/>
<div class="nowPlaying-artistInfo">
<h3 id="modalname"></h3>
<p class="artistAlbumLine"><span id="modalartist"></span> - <span id="modalalbum"></span></p>
@ -343,9 +337,6 @@
<ul id="playlistslist" class="table"></ul>
</div>
<div class="ui-block-b scroll" id="playlisttracksdiv">
<div id="playlisttracksback" style="height: 30px; margin: 2px; padding-top: 2px; background-color: #aaa;">
<a style="display:block; padding: 5px;" href="#" onclick="return togglePlaylists();"><i class="fa fa-arrow-circle-left"></i> Back</a>
</div>
<div>
<ul class="table" id="playlisttracks"></ul>
</div>
@ -356,8 +347,9 @@
<div data-role="content" id="browsepane" class="pane">
<h4>Browse</h4>
<h5 id="browsepath"></h5>
<ul id="browselist" class="table"></ul>
<div class="ui-grid">
<ul id="browsetable" class="table"></ul>
</div>
</div>
<!--/browsepane-->
@ -385,7 +377,7 @@
<h3 id="h_albumname"></h3>
<h5 id="h_albumartist"></h5>
<div id="albumstable"></div>
<ul class="table" id="albumstable"></ul>
</div>
@ -477,7 +469,6 @@
</div>
</div>
<div data-role="footer" data-tap-toggle="false" data-position="fixed" id="normalFooter">
<div class="footerControls">
<div class="songinfo" id="songinfo">
@ -492,6 +483,7 @@
</div>
</div>
</div>
<div data-role="footer" data-tap-toggle="false" data-position="fixed" id="nowPlayingFooter">
<div class="footerControls" style="padding-left: 10px;">
<div style="float: left;">
@ -507,11 +499,9 @@
<a href="#" onclick="doShuffle(); return false"><span id="shufflebt" title="Shuffle"><i class="fa fa-arrows-v"></i></span></a>
</div>
</div>
</div>
<!-- /footer -->
</div>
<!-- /page one -->
<script type="text/javascript" src="vendors/mopidy/mopidy.min.js"></script>

View File

@ -52,6 +52,7 @@ var isWebkit = /WebKit/.test(ua)
PROGRAM_NAME = 'MusicBox'
ARTIST_TABLE = '#artiststable'
ALBUM_TABLE = '#albumstable'
BROWSE_TABLE = '#browsetable'
PLAYLIST_TABLE = '#playlisttracks'
CURRENT_PLAYLIST_TABLE = '#currenttable'
SEARCH_ALL_TABLE = '#allresulttable'
@ -162,54 +163,69 @@ function artistsToString (artists, max) {
* break up results and put them in album tables
*********************************************************/
function albumTracksToTable (pl, target, uri) {
var tmp = '<ul class="songsOfAlbum table" >'
var liId = ''
var targetmin = target.substr(1)
var track, previousTrack, nextTrack
$(target).empty()
for (var i = 0; i < pl.length; i++) {
popupData[pl[i].uri] = pl[i]
liID = targetmin + '-' + pl[i].uri
tmp += renderSongLi(pl[i], liID, uri)
}
tmp += '</ul>'
$(target).html(tmp)
$(target).attr('data', uri)
for (var i = 0; i < pl.length; i++) {
previousTrack = track || undefined
nextTrack = i < pl.length - 1 ? pl[i + 1] : undefined
track = pl[i]
popupData[track.uri] = track
renderSongLi(previousTrack, track, nextTrack, uri, '', ALBUM_TABLE, i, pl.length)
}
updatePlayIcons(songdata.track.uri, songdata.tlid)
}
function renderSongLi (song, liID, uri, tlid, renderAlbumInfo) {
var name, iconClass
var tlidString = ''
function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, currentIndex, listLength) {
var name
var tlidParameter = ''
var onClick = ''
// Determine if the song line item will be rendered as part of an album.
if (!song.album || !song.album.name) {
iconClass = getMediaClass(song.uri)
} else {
iconClass = 'trackname'
var targetmin = target.substr(1)
track.name = validateTrackName(track, currentIndex)
// Leave out unplayable items
if (track.name.substring(0, 12) === '[unplayable]') {
return
}
// Streams
if (track.length === -1) {
$(target).append('<li class="albumli"><a href="#"><h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.name + ' [Stream]</h1></a></li>')
return
}
// Play by tlid if available.
if (tlid) {
tlidString = '" tlid="' + tlid
// TODO: Need to consolidate all of the 'play...' functions
if (tlid && target === BROWSE_TABLE) {
onClick = 'return playBrowsedTracks(PLAY_ALL, ' + tlid + ');'
} else if (tlid) {
tlidParameter = '\',\'' + tlid
onClick = 'return playTrackQueueByTlid(\'' + song.uri + '\',\'' + tlid + '\');'
onClick = 'return playTrackQueueByTlid(\'' + track.uri + '\',\'' + tlid + '\');'
} else {
onClick = 'return playTrackByUri(\'' + song.uri + '\',\'' + uri + '\');'
onClick = 'return playTrackByUri(\'' + track.uri + '\',\'' + uri + '\');'
}
songLi = '<li class="song albumli" id="' + liID + tlidString + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + song.uri + tlidParameter + '\');">' +
$(target).append(
'<li class="song albumli" id="' + getjQueryID(targetmin + '-', track.uri) + '" tlid="' + tlid + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\',\'' + track.uri + tlidParameter + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" onclick="' + onClick + '">' +
'<h1><i class="' + iconClass + '"></i>' + song.name + '</h1>'
if (renderAlbumInfo) {
songLi += '</p>'
songLi += renderSongLiTrackArtists(song)
if (song.album && song.album.name) {
songLi += ' - '
songLi += '<em>' + song.album.name + '</em></p>'
'<a href="#" onclick="' + onClick + '"><h1><i></i> ' + track.name + '</h1></a></li>'
)
if (listLength === 1 || !hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack)) {
renderSongLiAlbumInfo(track, target)
}
// TODO: remove this hard-coded condition for 'ALBUM_TABLE'
if (target !== ALBUM_TABLE && !hasSameAlbum(previousTrack, track)) {
// Starting to render a new album in the list.
renderSongLiDivider(track, nextTrack, currentIndex, target)
}
}
songLi += '</a></li>'
return songLi
function renderSongLiAlbumInfo (track, target) {
var html = '</p>'
html += renderSongLiTrackArtists(track)
if (track.album && track.album.name) {
html += ' - <em>' + track.album.name + '</em></p>'
}
target = getjQueryID(target.substr(1) + '-', track.uri, true)
$(target).children('a').eq(1).append(html)
$(target + ' a h1 i').addClass(getMediaClass(track.uri))
}
function renderSongLiTrackArtists (track) {
@ -228,15 +244,49 @@ function renderSongLiTrackArtists (track) {
return html
}
function isNewAlbumSection (track, previousTrack) {
// 'true' if album name is either not defined or has changed from the previous track.
return !track.album || !track.album.name || !previousTrack || !previousTrack.album || !previousTrack.album.name ||
track.album.name !== previousTrack.album.name
function renderSongLiDivider (track, nextTrack, currentIndex, target) {
targetmin = target.substr(1)
target = getjQueryID(targetmin + '-', track.uri, true)
// Render differently if part of an album
if (hasSameAlbum(track, nextTrack)) {
// Large divider with album cover
$(target).before(
'<li class="albumdivider"><a href="#" onclick="return showAlbum(\'' + track.album.uri + '\');">' +
'<img id="' + getjQueryID(targetmin + '-cover-', track.uri) + '" class="artistcover" width="30" height="30"/>' +
'<h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.album.name + '</h1><p>' +
renderSongLiTrackArtists(track) + '</p></a></li>'
)
// Retrieve album covers
getCover(track.uri, getjQueryID(targetmin + '-cover-', track.uri, true), 'small')
} else if (currentIndex > 0) {
// Small divider
$(target).before('<li class="smalldivider"> &nbsp;</li>')
}
}
function isMultiTrackAlbum (track, nextTrack) {
// 'true' if there are more tracks of the same album after this one.
return nextTrack.album && nextTrack.album.name && track.album && track.album.name && track.album.name === nextTrack.album.name
function renderSongLiBackButton (results, target, onClick, optional) {
if (onClick && onClick.length > 0) {
if (!results || results.length === 0) {
$(target).empty()
$(target).append(
'<li class="song albumli"><a href="#" onclick="' + onClick + '"><h1><i></i>No tracks found...</h1></a></li>'
)
}
var opt = ''
if (optional) {
opt = ' backnav-optional'
}
$(target).prepend(
'<li class="backnav' + opt + '"><a href="#" onclick="' + onClick + '"><h1><i class="fa fa-arrow-circle-left"></i> Back</h1></a></li>'
)
}
}
function hasSameAlbum (track1, track2) {
// 'true' if album for each track exists and has the same name
var name1 = track1 ? (track1.album ? track1.album.name : undefined) : undefined
var name2 = track2 ? (track2.album ? track2.album.name : undefined) : undefined
return name1 && name2 && (name1 === name2)
}
function validateTrackName (track, trackNumber) {
@ -251,86 +301,33 @@ function validateTrackName (track, trackNumber) {
return name
}
function resultsToTables (results, target, uri) {
if (!results) {
function resultsToTables (results, target, uri, onClickBack, backIsOptional) {
$(target).empty()
renderSongLiBackButton(results, target, onClickBack, backIsOptional)
if (!results || results.length === 0) {
return
}
$(target).html('')
$(target).attr('data', uri)
var track, previousTrack, nextTrack, tlid
var albumTrackSeen = 0
var renderAlbumInfo = true
var liID = ''
// Keep a list of track URIs for retrieving of covers
var coversList = []
var html = ''
var tableid, artistname, name, iconClass
var targetmin = target.substr(1)
var length = 0 || results.length
// Break into albums and put in tables
for (i = 0; i < length; i++) {
previousTrack = track
for (i = 0; i < results.length; i++) {
previousTrack = track || undefined
nextTrack = i < results.length - 1 ? results[i + 1] : undefined
track = results[i]
tlid = ''
if (i < length - 1) {
nextTrack = results[i + 1]
}
if ('tlid' in results[i]) {
if (track) {
if ('tlid' in track) {
// Get track information from TlTrack instance
track = results[i].track
tlid = results[i].tlid
if (i < length - 1) {
nextTrack = results[i + 1].track
}
}
track.name = validateTrackName(track, i)
// Leave out unplayable items
if (track.name.substring(0, 12) === '[unplayable]') {
continue
}
// Streams
if (track.length === -1) {
html += '<li class="albumli"><a href="#"><h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.name + ' [Stream]</h1></a></li>'
continue
}
if (isNewAlbumSection(track, previousTrack)) {
// Starting to render a new album in the list.
tableid = 'art' + i
// Render differently if part of an album
if (i < length - 1 && isMultiTrackAlbum(track, nextTrack)) {
// Large divider with album cover
renderAlbumInfo = false
html += '<li class="albumdivider">'
html += '<a href="#" onclick="return showAlbum(\'' + track.album.uri + '\');">' +
'<img id="' + targetmin + '-cover-' + i + '" class="artistcover" width="30" height="30" />' +
'<h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.album.name + '</h1><p>'
html += renderSongLiTrackArtists(track)
html += '</p></a></li>'
coversList.push([track.uri, i])
} else {
renderAlbumInfo = true
if (i > 0) {
// Small divider
html += '<li class="smalldivider"> &nbsp;</li>'
}
}
albumTrackSeen = 0
tlid = track.tlid
track = track.track
nextTrack = nextTrack ? nextTrack.track : undefined
}
popupData[track.uri] = track
liID = targetmin + '-' + track.uri
html += renderSongLi(track, liID, uri, tlid, renderAlbumInfo)
albumTrackSeen += 1
renderSongLi(previousTrack, track, nextTrack, uri, tlid, target, i, results.length)
}
tableid = '#' + tableid
$(target).html(html)
// Retrieve album covers
for (i = 0; i < coversList.length; i++) {
getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small')
}
updatePlayIcons(songdata.track.uri, songdata.tlid)
}
// process updated playlist to gui
@ -519,3 +516,32 @@ function isSpotifyStarredPlaylist (playlist) {
var starredRegex = /spotify:user:.*:starred/g
return (starredRegex.test(playlist.uri) && playlist.name === 'Starred')
}
/**
* Converts a URI to a jQuery-safe identifier. jQuery identifiers need to be
* unique per page and cannot contain special characters.
*
* @param {string} identifier - Identifier string to prefix to the URI. Can
* be used to ensure that the generated ID will be unique for the page that
* it will be included on. Can be any string (e.g. ID of parent element).
*
* @param {string} uri - URI to encode, usually the URI of a Mopidy track.
*
* @param {boolean} includePrefix - Will prefix the generated identifier
* with the '#' character if set to 'true', ready to be passed to $() or
* jQuery().
*
* @return {string} - a string in the format '[#]identifier-encodedURI' that
* is safe to use as a jQuery identifier.
*/
function getjQueryID (identifier, uri, includePrefix) {
var prefix = includePrefix ? '#' : ''
return prefix + identifier + fixedEncodeURIComponent(uri).replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '')
}
// Strict URI encoding as per https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
function fixedEncodeURIComponent (str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16)
})
}

View File

@ -413,7 +413,6 @@ function locationHashChanged () {
break
case 'current':
$('#navcurrent a').addClass('ui-state-active ui-state-persist ui-btn-active')
getCurrentPlaylist()
break
case 'playlists':
$('#navplaylists a').addClass('ui-state-active ui-state-persist ui-btn-active')
@ -622,55 +621,29 @@ $(document).ready(function (event) {
})
function updatePlayIcons (uri, tlid) {
// update styles of listviews
$('#currenttable li').each(function () {
// Update styles of listviews
var listviews = [PLAYLIST_TABLE, SEARCH_TRACK_TABLE, ARTIST_TABLE, ALBUM_TABLE, BROWSE_TABLE]
var target = CURRENT_PLAYLIST_TABLE.substr(1)
$(CURRENT_PLAYLIST_TABLE).children('li').each(function () {
var eachTlid = $(this).attr('tlid')
if (typeof eachTlid !== 'undefined') {
eachTlid = parseInt(eachTlid)
}
if (this.id === 'currenttable-' + uri && eachTlid === tlid) {
if (this.id === getjQueryID(target + '-', uri) && eachTlid === tlid) {
$(this).addClass('currenttrack')
} else {
$(this).removeClass('currenttrack')
}
})
$('#playlisttracks li').each(function () {
if (this.id === 'playlisttracks-' + uri) {
$(this).addClass('currenttrack2')
} else {
$(this).removeClass('currenttrack2')
}
})
$('#trackresulttable li').each(function () {
if (this.id === 'trackresulttable-' + uri) {
$(this).addClass('currenttrack2')
} else {
$(this).removeClass('currenttrack2')
}
})
$('#artiststable li').each(function () {
if (this.id === 'artiststable-' + uri) {
$(this).addClass('currenttrack2')
} else {
$(this).removeClass('currenttrack2')
}
})
$('#albumstable li').each(function () {
if (this.id === 'albumstable-' + uri) {
$(this).addClass('currenttrack2')
} else {
$(this).removeClass('currenttrack2')
}
})
$('#browselist li').each(function () {
if (this.id === 'browselisttracks-' + uri) {
for (var i = 0; i < listviews.length; i++) {
target = listviews[i].substr(1)
$(listviews[i]).children('li').each(function () {
if (this.id === getjQueryID(target + '-', uri)) {
$(this).addClass('currenttrack2')
} else {
$(this).removeClass('currenttrack2')
}
})
}
}

View File

@ -77,7 +77,7 @@ function getCoverFromLastFm (track, images, size) {
}
}
}
})
}, $(images).attr('src', defUrl))
}
function getArtistImage (nwartist, image, size) {
@ -88,5 +88,5 @@ function getArtistImage (nwartist, image, size) {
$(image).attr('src', data.artist.image[i]['#text'] || defUrl)
}
}
}})
}}, $(images).attr('src', defUrl))
}

View File

@ -106,6 +106,10 @@ function processSearchResults (resultArr) {
customTracklists[URI_SCHEME + ':trackresultscache'] = results.tracks
if (emptyResult) {
$('#searchtracks').show()
$(SEARCH_TRACK_TABLE).append(
'<li class="song albumli"><a href="#"><h1><i></i>No tracks found...</h1></a></li>'
)
toast('No results')
showLoading(false)
return false
@ -193,8 +197,6 @@ function processSearchResults (resultArr) {
// Inject list items, refresh listview and hide superfluous items.
$(SEARCH_ALBUM_TABLE).html(child).listview('refresh').find('.overflow').hide()
$('#expandsearch').show()
// Track results
resultsToTables(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME + ':trackresultscache')
@ -250,12 +252,13 @@ function togglePlaylists () {
}
function showTracklist (uri) {
showLoading(true)
$(PLAYLIST_TABLE).empty()
togglePlaylists()
var tracks = getPlaylistTracks(uri).then(function (tracks) {
resultsToTables(tracks, PLAYLIST_TABLE, uri)
})
resultsToTables(tracks, PLAYLIST_TABLE, uri, 'return togglePlaylists();', true)
showLoading(false)
})
updatePlayIcons(uri)
$('#playlistslist li a').each(function () {
$(this).removeClass('playlistactive')

View File

@ -76,78 +76,78 @@ function processPlaystate (data) {
* process results of a browse list
*********************************************************/
function processBrowseDir (resultArr) {
var backHtml = '<li style="background-color:#ccc"><a href="#" onclick="return getBrowseDir();"><h1 class="trackname"><i class="fa fa-arrow-circle-left"></i> Back</h1></a></li>'
if ((!resultArr) || (resultArr === '') || (resultArr.length === 0)) {
$('#browsepath').html('No tracks found...')
$('#browselist').html(backHtml)
$(BROWSE_TABLE).empty()
if (browseStack.length > 0) {
renderSongLiBackButton(resultArr, BROWSE_TABLE, 'return getBrowseDir();')
}
if (!resultArr || resultArr.length === 0) {
showLoading(false)
return
}
$('#browselist').empty()
var child = ''
var rooturi = ''
var uri = resultArr[0].uri
// check root uri
// find last : or / (spltting the result)
// do it twice, since.
var colonindex = uri.lastIndexOf(':')
var slashindex = uri.lastIndexOf('/')
var lastindex = (colonindex > slashindex) ? colonindex : slashindex
rooturi = uri.slice(0, lastindex)
if (resultArr[0].type === 'track') {
rooturi = rooturi.replace(':track:', ':directory:')
}
colonindex = rooturi.lastIndexOf(':')
slashindex = rooturi.lastIndexOf('/')
lastindex = (colonindex > slashindex) ? colonindex : slashindex
rooturi = rooturi.slice(0, lastindex)
if (browseStack.length > 0) {
child += backHtml
}
browseTracks = []
uris = []
var ref, track, previousTrack, nextTrack
var uri = resultArr[0].uri
var length = 0 || resultArr.length
for (var i = 0, index = 0; i < resultArr.length; i++) {
iconClass = getMediaClass(resultArr[i].uri)
if (resultArr[i].type === 'track') {
// console.log(resultArr[i]);
mopidy.library.lookup({'uris': [resultArr[i].uri]}).then(function (resultDict) {
var lookupUri = Object.keys(resultDict)[0]
popupData[lookupUri] = resultDict[lookupUri][0]
browseTracks.push(resultDict[lookupUri][0])
}, console.error)
child += '<li class="song albumli" id="browselisttracks-' + resultArr[i].uri + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\', \'' + resultArr[i].uri + '\', \'' + index + '\');">' +
ref = resultArr[i]
popupData[ref.uri] = ref
browseTracks.push(ref)
uris.push(ref.uri)
$(BROWSE_TABLE).append(
'<li class="song albumli" id="' + getjQueryID(BROWSE_TABLE.substr(1) + '-', ref.uri) + '">' +
'<a href="#" class="moreBtn" onclick="return popupTracks(event, \'' + uri + '\', \'' + ref.uri + '\', \'' + index + '\');">' +
'<i class="fa fa-ellipsis-v"></i></a>' +
'<a href="#" class="browsetrack" onclick="return playBrowsedTracks(PLAY_ALL, ' + index + ');" id="' + resultArr[i].uri +
'"><h1 class="trackname"><i class="' + iconClass + '"></i> ' + resultArr[i].name + '</h1></a></li>'
'<a href="#" class="browsetrack" onclick="return playBrowsedTracks(PLAY_ALL, ' + index + ');">' +
'<h1><i></i> ' + ref.name + '</h1></a></li>'
)
index++
} else {
var iconClass = ''
if (browseStack.length > 0) {
iconClass = 'fa fa-folder-o'
}
child += '<li><a href="#" onclick="return getBrowseDir(this.id);" id="' + resultArr[i].uri +
'""><h1 class="trackname"><i class="' + iconClass + '"></i> ' + resultArr[i].name + '</h1></a></li>'
}
}
$('#browselist').html(child)
if (browseStack.length > 0) {
child = getMediaHuman(uri)
iconClass = getMediaClass(uri)
$('#browsepath').html('<i class="' + iconClass + '"></i> ' + child)
} else {
$('#browsepath').html('')
iconClass = getMediaClass(resultArr[i].uri)
}
$(BROWSE_TABLE).append(
'<li><a href="#" onclick="return getBrowseDir(this.id);" id="' + resultArr[i].uri + '">' +
'<h1><i class="' + iconClass + '"></i> ' + resultArr[i].name + '</h1></a></li>'
)
}
}
updatePlayIcons(songdata.track.uri, songdata.tlid)
if (uris.length > 0) {
mopidy.library.lookup({'uris': uris}).then(function (resultDict) {
// Break into albums and put in tables
var track, previousTrack, nextTrack, uri
$.each(resultArr, function (i, ref) {
if (ref.type === 'track') {
previousTrack = track || undefined
if (i < resultArr.length - 1 && resultDict[resultArr[i + 1].uri]) {
nextTrack = resultDict[resultArr[i + 1].uri][0]
} else {
nextTrack = undefined
}
track = resultDict[ref.uri][0]
if (uris.length === 1 || (previousTrack && !hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack))) {
renderSongLiAlbumInfo(track, BROWSE_TABLE)
}
if (!hasSameAlbum(previousTrack, track)) {
// Starting to render a new album in the list.
renderSongLiDivider(track, nextTrack, i, BROWSE_TABLE)
}
}
})
showLoading(false)
}, console.error)
} else {
showLoading(false)
}
}
/** ******************************************************

View File

@ -1,6 +1,6 @@
CACHE MANIFEST
# 2016-03-06:v2
# 2016-03-14:v1
NETWORK:
*