From 9856685a008711771c8825c1d2ab1c0ea946b7d4 Mon Sep 17 00:00:00 2001 From: John Cass Date: Sun, 22 Jan 2017 07:16:52 +0200 Subject: [PATCH] Add 'Refresh' button to update libraries (#222) Add 'Refresh' button to update libraries. Tweak folder icons and context menus. Fixes #136. --- README.rst | 2 + .../static/css/webclient.css | 5 +- mopidy_musicbox_webclient/static/index.html | 11 ++- .../static/js/controls.js | 8 ++ .../static/js/functionsvars.js | 80 ++++++++++++------- .../static/js/library.js | 25 ++++-- .../static/js/process_ws.js | 21 ++--- 7 files changed, 101 insertions(+), 51 deletions(-) diff --git a/README.rst b/README.rst index d672a33..9cdb830 100644 --- a/README.rst +++ b/README.rst @@ -111,6 +111,7 @@ v2.4.0 (UNRELEASED) - 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. - Updated icon set for font-awesome 4.7.0. +- Added 'Refresh' button for refreshing libraries. (Addresses: `#75 `_). **Fixes** @@ -121,6 +122,7 @@ v2.4.0 (UNRELEASED) - Use correct icons for folders, audio, and other files when browsing local files. - Now initializes the GUI properly, even if the user is offline or the Mopidy server cannot be reached. - Fixed `Alarm Clock `_ detection. +- When browsing the library using the local 'File' extension, only playable audio files will have context menu icons. v2.3.0 (2016-05-15) ------------------- diff --git a/mopidy_musicbox_webclient/static/css/webclient.css b/mopidy_musicbox_webclient/static/css/webclient.css index 89d554f..6d4efc8 100644 --- a/mopidy_musicbox_webclient/static/css/webclient.css +++ b/mopidy_musicbox_webclient/static/css/webclient.css @@ -118,7 +118,6 @@ /****************** * Track Slider * ******************/ - #trackslider { display: inline; width: 100%; @@ -366,6 +365,10 @@ span.hostInfo { background-color: #ccc !important; } +.refreshLibraryBtnDiv { + display: none; +} + /********************** * Now Playing area * diff --git a/mopidy_musicbox_webclient/static/index.html b/mopidy_musicbox_webclient/static/index.html index ca191f2..9dfc006 100644 --- a/mopidy_musicbox_webclient/static/index.html +++ b/mopidy_musicbox_webclient/static/index.html @@ -404,7 +404,16 @@
-

Browse

+
+
+

Browse

+
+
+ +
+
    diff --git a/mopidy_musicbox_webclient/static/js/controls.js b/mopidy_musicbox_webclient/static/js/controls.js index 55e87d2..d1114ab 100644 --- a/mopidy_musicbox_webclient/static/js/controls.js +++ b/mopidy_musicbox_webclient/static/js/controls.js @@ -416,6 +416,14 @@ return false }, + refreshLibrary: function () { + var uri = $('#refreshLibraryBtn').data('url') + mopidy.library.refresh({'uri': uri}).then(function () { + library.getBrowseDir(uri) + }) + return false + }, + /** *********** * Buttons * *************/ diff --git a/mopidy_musicbox_webclient/static/js/functionsvars.js b/mopidy_musicbox_webclient/static/js/functionsvars.js index 5b5d07b..9752563 100644 --- a/mopidy_musicbox_webclient/static/js/functionsvars.js +++ b/mopidy_musicbox_webclient/static/js/functionsvars.js @@ -75,8 +75,8 @@ var radioExtensionsList = ['somafm', 'tunein', 'dirble', 'audioaddict'] var uriClassList = [ ['spotify', 'fa-spotify'], ['spotifytunigo', 'fa-spotify'], - ['local', 'fa-file-sound-o'], - ['file', 'fa-file-o'], + ['local', 'fa-folder-o'], + ['file', 'fa-folder-o'], ['m3u', 'fa-file-sound-o'], ['podcast', 'fa-rss-square'], ['podcast+file', 'fa-rss-square'], @@ -240,13 +240,9 @@ function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, curre var onClick = '' var html = '' track.name = validateTrackName(track, currentIndex) - // Leave out unplayable items - if (track.name.substring(0, 12) === '[unplayable]') { - return html - } // Streams if (track.length === -1) { - html += '
  • ' + track.name + ' [Stream]

  • ' + html += '
  • ' + track.name + ' [Stream]

  • ' return html } @@ -257,11 +253,13 @@ function renderSongLi (previousTrack, track, nextTrack, uri, tlid, target, curre onClick = 'return controls.playTracks(\'\', mopidy, \'' + track.uri + '\', \'' + uri + '\');' } - html += - '
  • ' + - '' + - '' + - '

    ' + track.name + '

    ' + html += '
  • ' + if (isPlayable(track)) { + // Show popup icon for audio files or 'tracks' of other scheme types + html += '' + + '' + } + html += '

    ' + track.name + '

    ' if (listLength === 1 || (!hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack))) { html += renderSongLiAlbumInfo(track) @@ -309,7 +307,7 @@ function renderSongLiDivider (previousTrack, track, nextTrack, target) { html += '
  • ' + '' + - '

    ' + track.album.name + '

    ' + + '

    ' + track.album.name + '

    ' + renderSongLiTrackArtists(track) + '

  • ' // Retrieve album covers images.setAlbumImage(track.uri, getjQueryID(target + '-cover', track.uri, true), mopidy, 'small') @@ -317,7 +315,7 @@ function renderSongLiDivider (previousTrack, track, nextTrack, target) { // Small divider html += '
  •  
  • ' } - if (typeof target !== 'undefined' && target.length > 0) { + if (html.length > 0 && typeof target !== 'undefined' && target.length > 0) { target = getjQueryID(target, track.uri, true) $(target).before(html) } @@ -494,26 +492,52 @@ function getScheme (uri) { return uri.split(':')[0].toLowerCase() } -function isAudioFile (uri) { - var ext = uri.split('.').pop().toLowerCase() - return $.inArray(ext, audioExt) !== -1 +function isPlayable (track) { + if (typeof track.type === 'undefined' || track.type === 'track') { + if (getScheme(track.uri) === 'file') { + var ext = track.uri.split('.').pop().toLowerCase() + if ($.inArray(ext, audioExt) === -1) { + // Files must have the correct extension + return false + } + } + return true + } + return false } function isStreamUri (uri) { - var a = validUri(uri) - var b = radioExtensionsList.indexOf(getScheme(uri)) >= 0 - return a || b + return validUri(uri) || radioExtensionsList.indexOf(getScheme(uri)) >= 0 } -function getMediaClass (uri) { - var scheme = getScheme(uri) - if (scheme === 'file' && isAudioFile(uri)) { - return 'fa fa-file-sound-o' - } - for (var i = 0; i < uriClassList.length; i++) { - if (scheme === uriClassList[i][0]) { - return 'fa ' + uriClassList[i][1] +function getMediaClass (track) { + var type = track.type + if (typeof type === 'undefined' || type === 'track') { + if (isPlayable(track)) { + if (isStreamUri(track.uri)) { + return 'fa fa-rss' // Stream + } else { + return 'fa fa-file-sound-o' // Sound file (default) + } + } else { + return 'fa fa-file-o' // Unplayable file } + } else if (type === 'directory') { + for (var i = 0; i < uriClassList.length; i++) { + if (getScheme(track.uri) === uriClassList[i][0]) { + return 'fa ' + uriClassList[i][1] // Mapped service directory + } + } + return 'fa fa-folder-o' // Unmapped directory + } else if (type === 'album') { + // return 'fa fa-bullseye' // Album + return 'fa fa-folder-o' + } else if (type === 'artist') { + // return 'fa fa-user-circle-o' // Artist + return 'fa fa-folder-o' + } else if (type === 'playlist') { + // return 'fa fa-star' // Playlist + return '' } return '' } diff --git a/mopidy_musicbox_webclient/static/js/library.js b/mopidy_musicbox_webclient/static/js/library.js index 682174f..4c132e5 100644 --- a/mopidy_musicbox_webclient/static/js/library.js +++ b/mopidy_musicbox_webclient/static/js/library.js @@ -145,7 +145,7 @@ tokens = { 'id': results.artists[i].uri, 'name': results.artists[i].name, - 'class': getMediaClass(results.artists[i].uri) + 'class': getMediaClass(results.artists[i]) } // Add 'Show all' item after a certain number of hits. @@ -173,7 +173,7 @@ 'albumName': results.albums[i].name, 'artistName': '', 'albumYear': results.albums[i].date, - 'class': getMediaClass(results.albums[i].uri) + 'class': getMediaClass(results.albums[i]) } if (results.albums[i].artists) { for (j = 0; j < results.albums[i].artists.length; j++) { @@ -215,14 +215,23 @@ showLoading(true) if (!rootdir) { browseStack.pop() - rootdir = browseStack[browseStack.length - 1] + rootdir = browseStack[browseStack.length - 1] || null } else { - browseStack.push(rootdir) + if (rootdir !== browseStack[browseStack.length - 1]) { + browseStack.push(rootdir) + } } - if (!rootdir) { - rootdir = null - } - mopidy.library.browse({'uri': rootdir}).then(processBrowseDir, console.error) + mopidy.library.browse({'uri': rootdir}).then(function (resultArr) { + processBrowseDir(resultArr) + if (rootdir === null) { + $('.refreshLibraryBtnDiv').hide() + } else { + $('.refreshLibraryBtnDiv').show() + $('#refreshLibraryBtn').data('url', rootdir) + $('#refreshLibraryBtn').off('click') + $('#refreshLibraryBtn').one('click', controls.refreshLibrary) + } + }, console.error) }, getCurrentPlaylist: function () { diff --git a/mopidy_musicbox_webclient/static/js/process_ws.js b/mopidy_musicbox_webclient/static/js/process_ws.js index 504088d..fa4f192 100644 --- a/mopidy_musicbox_webclient/static/js/process_ws.js +++ b/mopidy_musicbox_webclient/static/js/process_ws.js @@ -90,8 +90,9 @@ function processBrowseDir (resultArr) { var length = 0 || resultArr.length customTracklists[BROWSE_TABLE] = [] var html = '' + var i - for (var i = 0, index = 0; i < resultArr.length; i++) { + for (i = 0, index = 0; i < resultArr.length; i++) { if (resultArr[i].type === 'track') { previousRef = ref || undefined nextRef = i < resultArr.length - 1 ? resultArr[i + 1] : undefined @@ -105,14 +106,8 @@ function processBrowseDir (resultArr) { index++ } else { - var iconClass = '' - if (browseStack.length > 0 && resultArr[i].type === 'directory') { - iconClass = 'fa fa-folder-o' - } else { - iconClass = getMediaClass(resultArr[i].uri) - } html += '
  • ' + - '

    ' + resultArr[i].name + '

  • ' + '

    ' + resultArr[i].name + '

    ' } } @@ -124,22 +119,22 @@ function processBrowseDir (resultArr) { 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') { + for (i = 0, index = 0; i < resultArr.length; i++) { + if (resultArr[i].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] + track = resultDict[resultArr[i].uri][0] popupData[track.uri] = track // Need full track info in popups in order to display albums and artists. if (uris.length === 1 || (previousTrack && !hasSameAlbum(previousTrack, track) && !hasSameAlbum(track, nextTrack))) { renderSongLiAlbumInfo(track, BROWSE_TABLE) } renderSongLiDivider(previousTrack, track, nextTrack, BROWSE_TABLE) } - }) + } showLoading(false) }, console.error) } else { @@ -166,7 +161,7 @@ function processGetPlaylists (resultArr) { } else if (isFavouritesPlaylist(resultArr[i])) { favourites = li_html + '♥ Musicbox Favourites' } else { - tmp = tmp + li_html + ' ' + resultArr[i].name + '' + tmp = tmp + li_html + ' ' + resultArr[i].name + '' } } // Prepend the user's Spotify "Starred" playlist and favourites to the results. (like Spotify official client).