Skip to content

Commit

Permalink
Merge pull request #194 from jcass77/enhance/optimize_tracklist_rende…
Browse files Browse the repository at this point in the history
…ring

Reduce number of DOM manipulations to improve performance.
  • Loading branch information
jcass77 committed Apr 27, 2016
2 parents fd7ad26 + 4474658 commit 64eda54
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 36 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -19,3 +19,5 @@ npm-debug.log
.project
*.pbxproj
*.egg-info
.cache
.eggs
3 changes: 3 additions & 0 deletions README.rst
Expand Up @@ -85,6 +85,7 @@ v2.3.0 (UNRELEASED)
(Addresses: `#133 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/133>`_).
- Optimized updating of 'now playing' icons in tracklists.
(Addresses: `#184 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/184>`_).
- Optimized rendering of large lists of tracks to make UI more responsive.

**Fixes**

Expand All @@ -93,6 +94,8 @@ v2.3.0 (UNRELEASED)
- last.fm artist image lookups should now always return the correct image for similarly named artists.
- Ensure that browsed tracks are always added to the queue using the track URI rather than the track's position in the folder.
(Fixes: `#124 <https://github.com/pimusicbox/mopidy-musicbox-webclient/issues/124>`_).
- Fixed an issue where searches would be performed as soon as the user switches to the 'Search' pane,
instead of waiting for the 'Search!' button to be clicked.

v2.2.0 (2016-03-01)
-------------------
Expand Down
67 changes: 39 additions & 28 deletions mopidy_musicbox_webclient/static/js/functionsvars.js
Expand Up @@ -175,31 +175,34 @@ function artistsToString (artists, max) {
*********************************************************/
function albumTracksToTable (pl, target, uri) {
var track, previousTrack, nextTrack
var html = ''
$(target).empty()
$(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, '', target, i, pl.length)
html += renderSongLi(previousTrack, track, nextTrack, uri, '', target, i, pl.length)
}
$(target).append(html)
updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction())
}

function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, currentIndex, listLength) {
var name
var tlidParameter = ''
var onClick = ''
var html = ''
track.name = validateTrackName(track, currentIndex)
// Leave out unplayable items
if (track.name.substring(0, 12) === '[unplayable]') {
return
return html
}
// 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
html += '<li class="albumli"><a href="#"><h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.name + ' [Stream]</h1></a></li>'
return html
}

if (target === CURRENT_PLAYLIST_TABLE && typeof tlid === 'number' && tlid >= 0) { // Current queue: Show popup menu icon. onClick plays track.
Expand All @@ -209,33 +212,33 @@ function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, curre
onClick = 'return controls.playTracks(\'\', mopidy, \'' + track.uri + '\', \'' + uri + '\');'
}

$(target).append(
html +=
'<li class="song albumli" id="' + getjQueryID(target, 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></i> ' + track.name + '</h1></a></li>'
)
'<a href="#" onclick="' + onClick + '"><h1><i class="' + getMediaClass(track.uri) + '"></i> ' + track.name + '</h1>'

if (listLength === 1 || !hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack)) {
renderSongLiAlbumInfo(track, target)
}
// TODO: remove this hard-coded conditions for 'ALBUM_TABLE' and 'BROWSE_TABLE'
if (target !== ALBUM_TABLE && target !== BROWSE_TABLE && !hasSameAlbum(previousTrack, track)) {
// Starting to render a new album in the list.
renderSongLiDivider(track, nextTrack, currentIndex, target)
html += renderSongLiAlbumInfo(track)
}
html += '</a></li>'
return html
}

/* Tracklist renderer for track artist and album name. */
function renderSongLiAlbumInfo (track, target) {
var html = '</p>'
html += renderSongLiTrackArtists(track)
var html = renderSongLiTrackArtists(track)
if (track.album && track.album.name) {
html += ' - <em>' + track.album.name + '</em></p>'
}
target = getjQueryID(target, track.uri, true)
$(target).children('a').eq(1).append(html)
$(target + ' a h1 i').addClass(getMediaClass(track.uri))
if (typeof target !== 'undefined' && target.length > 0) {
target = getjQueryID(target, track.uri, true)
$(target).children('a').eq(1).append(html)
}
return html
}

/* Tracklist renderer for track artist information. */
function renderSongLiTrackArtists (track) {
var html = ''
if (track.artists) {
Expand All @@ -252,23 +255,28 @@ function renderSongLiTrackArtists (track) {
return html
}

function renderSongLiDivider (track, nextTrack, currentIndex, target) {
target = getjQueryID(target, track.uri, true)
// Render differently if part of an album
if (hasSameAlbum(track, nextTrack)) {
// Large divider with album cover
$(target).before(
/* Tracklist renderer to insert dividers between albums. */
function renderSongLiDivider (previousTrack, track, nextTrack, currentIndex, target) {
var html = ''
// Render differently if part of an album.
if (!hasSameAlbum(previousTrack, track) && hasSameAlbum(track, nextTrack)) {
// Large divider with album cover.
html +=
'<li class="albumdivider"><a href="#" onclick="return library.showAlbum(\'' + track.album.uri + '\');">' +
'<img id="' + getjQueryID(target + '-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
images.setAlbumImage(track.uri, getjQueryID(target + '-cover', track.uri, true), mopidy, 'small')
} else if (currentIndex > 0) {
} else if (!hasSameAlbum(track, nextTrack) && currentIndex > 0) {
// Small divider
$(target).before('<li class="smalldivider"> &nbsp;</li>')
html += '<li class="smalldivider"> &nbsp;</li>'
}
if (typeof target !== 'undefined' && target.length > 0) {
target = getjQueryID(target, track.uri, true)
$(target).before(html)
}
return html
}

function renderSongLiBackButton (results, target, onClick, optional) {
Expand Down Expand Up @@ -317,6 +325,7 @@ function resultsToTables (results, target, uri, onClickBack, backIsOptional) {
$(target).attr('data', uri)

var track, previousTrack, nextTrack, tlid
var html = ''

// Break into albums and put in tables
for (i = 0; i < results.length; i++) {
Expand All @@ -331,9 +340,11 @@ function resultsToTables (results, target, uri, onClickBack, backIsOptional) {
nextTrack = nextTrack ? nextTrack.track : undefined
}
popupData[track.uri] = track
renderSongLi(previousTrack, track, nextTrack, uri, tlid, target, i, results.length)
html += renderSongLiDivider(previousTrack, track, nextTrack, i, target)
html += renderSongLi(previousTrack, track, nextTrack, uri, tlid, target, i, results.length)
}
}
$(target).append(html)
updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction())
}

Expand Down
1 change: 0 additions & 1 deletion mopidy_musicbox_webclient/static/js/gui.js
Expand Up @@ -419,7 +419,6 @@ function locationHashChanged () {
case 'search':
$('#navsearch a').addClass($.mobile.activeBtnClass)
$('#searchinput').focus()
library.initSearch($('#searchinput').val())
break
case 'stream':
$('#navstream a').addClass('ui-state-active ui-state-persist ui-btn-active')
Expand Down
13 changes: 7 additions & 6 deletions mopidy_musicbox_webclient/static/js/process_ws.js
Expand Up @@ -89,6 +89,7 @@ function processBrowseDir (resultArr) {
var uri = resultArr[0].uri
var length = 0 || resultArr.length
customTracklists[BROWSE_TABLE] = []
var html = ''

for (var i = 0, index = 0; i < resultArr.length; i++) {
if (resultArr[i].type === 'track') {
Expand All @@ -100,7 +101,7 @@ function processBrowseDir (resultArr) {
customTracklists[BROWSE_TABLE].push(ref)
uris.push(ref.uri)

renderSongLi(previousRef, ref, nextRef, BROWSE_TABLE, '', BROWSE_TABLE, index, resultArr.length)
html += renderSongLi(previousRef, ref, nextRef, BROWSE_TABLE, '', BROWSE_TABLE, index, resultArr.length)

index++
} else {
Expand All @@ -110,13 +111,13 @@ function processBrowseDir (resultArr) {
} else {
iconClass = getMediaClass(resultArr[i].uri)
}
$(BROWSE_TABLE).append(
'<li><a href="#" onclick="return library.getBrowseDir(this.id);" id="' + resultArr[i].uri + '">' +
'<h1><i class="' + iconClass + '"></i> ' + resultArr[i].name + '</h1></a></li>'
)
html += '<li><a href="#" onclick="return library.getBrowseDir(this.id);" id="' + resultArr[i].uri + '">' +
'<h1><i class="' + iconClass + '"></i> ' + resultArr[i].name + '</h1></a></li>'
}
}

$(BROWSE_TABLE).append(html)

updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction())

if (uris.length > 0) {
Expand All @@ -138,7 +139,7 @@ function processBrowseDir (resultArr) {
}
if (!hasSameAlbum(previousTrack, track)) {
// Starting to render a new album in the list.
renderSongLiDivider(track, nextTrack, i, BROWSE_TABLE)
renderSongLiDivider(previousTrack, track, nextTrack, i, BROWSE_TABLE)
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion mopidy_musicbox_webclient/static/mb.appcache
@@ -1,6 +1,6 @@
CACHE MANIFEST

# 2016-04-26:v2
# 2016-04-27:v1

NETWORK:
*
Expand Down

0 comments on commit 64eda54

Please sign in to comment.