diff --git a/README.rst b/README.rst index 2635fb2..423ea19 100644 --- a/README.rst +++ b/README.rst @@ -75,6 +75,10 @@ v2.3.0 (UNRELEASED) - Enhance build workflow to include style checks and syntax validation for HTML, CSS, and Javascript. +**Fixes** + +- Don't create Mopidy models manually. (Fixes: `#172 `_). + v2.2.0 (2016-03-01) ------------------- diff --git a/mopidy_musicbox_webclient/static/js/functionsvars.js b/mopidy_musicbox_webclient/static/js/functionsvars.js index 9d82bf3..cad2ac4 100644 --- a/mopidy_musicbox_webclient/static/js/functionsvars.js +++ b/mopidy_musicbox_webclient/static/js/functionsvars.js @@ -176,185 +176,158 @@ function albumTracksToTable (pl, target, uri) { $(target).attr('data', uri) } -function renderSongLi (song, liID, uri) { - var name - if (!song.name || song.name === '') { - name = uri.split('/') - name = decodeURI(name[name.length - 1]) +function renderSongLi (song, liID, uri, tlid, renderAlbumInfo) { + var name, iconClass + var tlidString = '' + 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 { - name = song.name + iconClass = 'trackname' } - songLi = '
  • ' + - '' + + // Play by tlid if available. + if (tlid) { + tlidString = '" tlid="' + tlid + tlidParameter = '\',\'' + tlid + onClick = 'return playTrackQueueByTlid(\'' + song.uri + '\',\'' + tlid + '\');' + } else { + onClick = 'return playTrackByUri(\'' + song.uri + '\',\'' + uri + '\');' + } + songLi = '
  • ' + + '' + '' + - '' + - '

    ' + name + '

    ' + - '
  • ' + '' + + '

    ' + song.name + '

    ' + if (renderAlbumInfo) { + songLi += '

    ' + songLi += renderSongLiTrackArtists(song) + if (song.album && song.album.name) { + songLi += ' - ' + songLi += '' + song.album.name + '

    ' + } + } + songLi += '
    ' return songLi } -function renderQueueSongLi (song, liID, uri, tlid) { - var name - if (!song.name || song.name === '') { - name = uri.split('/') - name = decodeURI(name[name.length - 1]) - } else { - name = song.name +function renderSongLiTrackArtists (track) { + var html = '' + if (track.artists) { + for (var i = 0; i < track.artists.length; i++) { + html += track.artists[i].name + html += (i === track.artists.length - 1) ? '' : ' / ' + // Stop after 3 + if (i > 2) { + html += '...' + break + } + } } - songLi = '
  • ' + - '' + - '' + - '' + - '

    ' + name + '

    ' + - '
  • ' - return songLi + 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 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 validateTrackName (track, trackNumber) { + // Create name if there is none + var name = '' + if (!track.name || track.name === '') { + name = track.uri.split('/') + name = decodeURI(name[name.length - 1]) || 'Track ' + String(trackNumber) + } else { + name = track.name + } + return name } function resultsToTables (results, target, uri) { if (!results) { return } - var tlids = [] - if (target === CURRENT_PLAYLIST_TABLE) { - for (i = 0; i < results.length; i++) { - tlids[i] = results[i].tlid - results[i] = results[i].track - } - } - - var newalbum = [] - var newtlids = [] - // keep a list of track URIs for retrieving of covers - var coversList = [] - var nextname = '' - var count = 0 $(target).html('') - - // break into albums and put in tables - var html = '' - var tableid, j, artistname, alburi, name, iconClass - var targetmin = target.substr(1) $(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++) { - // create album if none extists - if (!results[i].album) { - results[i].album = {'__model__': 'Album'} + previousTrack = track + track = results[i] + tlid = '' + if (i < length - 1) { + nextTrack = results[i + 1] } - // create album uri if there is none - if (!results[i].album.uri) { - results[i].album.uri = 'x' + if ('tlid' in results[i]) { + // Get track information from TlTrack instance + track = results[i].track + tlid = results[i].tlid + if (i < length - 1) { + nextTrack = results[i + 1].track + } } - if (!results[i].album.name) { - results[i].album.name = '' + track.name = validateTrackName(track, i) + // Leave out unplayable items + if (track.name.substring(0, 12) === '[unplayable]') { + continue } - // create name if there is no one - if (!results[i].name || results[i].name === '') { - name = results[i].uri.split('/') - results[i].name = decodeURI(name[name.length - 1]) || 'Track ' + String(i) + // Streams + if (track.length === -1) { + html += '
  • ' + track.name + ' [Stream]

  • ' + continue } - // leave out unplayable items - if (results[i].name.substring(0, 12) === '[unplayable]') continue - - newalbum.push(results[i]) - newtlids.push(tlids[i]) - nextname = '' - if ((i < length - 1) && results[i + 1].album && results[i + 1].album.name) { - nextname = results[i + 1].album.name - } - if (results[i].length === -1) { - html += '
  • ' + results[i].name + ' [Stream]

  • ' - newalbum = [] - newtlids = [] - nextname = '' - } else { - if ((results[i].album.name !== nextname) || (nextname === '')) { - tableid = 'art' + i - // render differently if only one track in the album - if (newalbum.length === 1) { - var liID = '' - if (i !== 0) { - html += '
  •  
  • ' - } - iconClass = getMediaClass(newalbum[0].uri) - liID = targetmin + '-' + newalbum[0].uri - if (target === CURRENT_PLAYLIST_TABLE) { - html += '
  • ' + - '' + - '' + - '' + - '

    ' + newalbum[0].name + '

    ' - } else { - html += '

  • ' + - '' + - '' + - '' + - '

    ' + newalbum[0].name + '

    ' - } - - if (newalbum[0].artists) { - for (j = 0; j < newalbum[0].artists.length; j++) { - html += newalbum[0].artists[j].name - html += (j === newalbum[0].artists.length - 1) ? '' : ' / ' - // stop after 3 - if (j > 2) { - html += '...' - break - } - } - } - if (newalbum[0].album.name !== '') { - html += ' / ' - } - html += '' + newalbum[0].album.name + '

    ' - html += '
  • ' - - popupData[newalbum[0].uri] = newalbum[0] - newalbum = [] - newtlids = [] - } else { // newalbum length - if (results[i].album.uri && results[i].album.name) { - iconClass = getMediaClass(newalbum[0].uri) - html += '
  • ' - html += '

    ' + results[i].album.name + '

    ' - } - if (results[i].album.artists) { - for (j = 0; j < results[i].album.artists.length; j++) { - html += results[i].album.artists[j].name - html += (j === results[i].album.artists.length - 1) ? '' : ' / ' - // stop after 3 - if (j > 2) { - child += '...' - break - } - } - } - html += '

  • ' - for (j = 0; j < newalbum.length; j++) { - popupData[newalbum[j].uri] = newalbum[j] - // hERE! - liID = targetmin + '-' + newalbum[j].uri - if (target === CURRENT_PLAYLIST_TABLE) { - html += renderQueueSongLi(newalbum[j], liID, uri, newtlids[j]) - } else { - html += renderSongLi(newalbum[j], liID, uri) - } - } - newalbum = [] - newtlids = [] - if (results[i].album) { - coversList.push([results[i].uri, i]) - } - } // newalbum length - } // albums name + 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 += '
  • ' + html += '' + + '' + + '

    ' + track.album.name + '

    ' + html += renderSongLiTrackArtists(track) + html += '

  • ' + coversList.push([track.uri, i]) + } else { + renderAlbumInfo = true + if (i > 0) { + // Small divider + html += '
  •  
  • ' + } + } + albumTrackSeen = 0 } + popupData[track.uri] = track + liID = targetmin + '-' + track.uri + html += renderSongLi(track, liID, uri, tlid, renderAlbumInfo) + albumTrackSeen += 1 } tableid = '#' + tableid $(target).html(html) - $(target).attr('data', uri) - // retrieve albumcovers + // Retrieve album covers for (i = 0; i < coversList.length; i++) { getCover(coversList[i][0], target + '-cover-' + coversList[i][1], 'small') } diff --git a/mopidy_musicbox_webclient/static/js/gui.js b/mopidy_musicbox_webclient/static/js/gui.js index 1654123..dba4241 100644 --- a/mopidy_musicbox_webclient/static/js/gui.js +++ b/mopidy_musicbox_webclient/static/js/gui.js @@ -164,7 +164,9 @@ function popupTracks (e, listuri, trackuri, tlid) { e = window.event } $('.popupTrackName').html(popupData[trackuri].name) - $('.popupAlbumName').html(popupData[trackuri].album.name) + if (popupData[trackuri].album && popupData[trackuri].album.name) { + $('.popupAlbumName').html(popupData[trackuri].album.name) + } var child = '' if (popupData[trackuri].artists) { diff --git a/mopidy_musicbox_webclient/static/mb.appcache b/mopidy_musicbox_webclient/static/mb.appcache index 27d0536..8501ba9 100644 --- a/mopidy_musicbox_webclient/static/mb.appcache +++ b/mopidy_musicbox_webclient/static/mb.appcache @@ -1,6 +1,6 @@ CACHE MANIFEST -# 2016-03-05:v1 +# 2016-03-06:v2 NETWORK: *