diff --git a/README.rst b/README.rst index bc14847..58c12b0 100644 --- a/README.rst +++ b/README.rst @@ -75,6 +75,8 @@ 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 `_). +- Now remembers which backend was searched previously, and automatically selects that backend as the default search target. + (Addresses: `#130 `_). **Fixes** diff --git a/karma.conf.js b/karma.conf.js index 6104b24..c64ba37 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -74,7 +74,7 @@ module.exports = function (config) { dir: 'coverage/', reporters: [ { type: 'lcov', subdir: '.' }, - { type: 'text'} + { type: 'text' } ] } }) diff --git a/mopidy_musicbox_webclient/static/index.html b/mopidy_musicbox_webclient/static/index.html index 02e92db..225ae79 100644 --- a/mopidy_musicbox_webclient/static/index.html +++ b/mopidy_musicbox_webclient/static/index.html @@ -395,14 +395,10 @@

Search for artists, albums, or specific tracks. - + -

diff --git a/mopidy_musicbox_webclient/static/js/functionsvars.js b/mopidy_musicbox_webclient/static/js/functionsvars.js index 89ee24b..525809d 100644 --- a/mopidy_musicbox_webclient/static/js/functionsvars.js +++ b/mopidy_musicbox_webclient/static/js/functionsvars.js @@ -95,9 +95,9 @@ var uriClassList = [ var uriHumanList = [ ['spotify', 'Spotify'], - ['spotifytunigo', 'Spotify Browse'], - ['local', 'Local Files'], - ['m3u', 'Local Playlists'], + ['spotifytunigo', 'Spotify browse'], + ['local', 'Local files'], + ['m3u', 'Local playlists'], ['podcast', 'Podcasts'], ['dirble', 'Dirble'], ['tunein', 'TuneIn'], @@ -249,7 +249,7 @@ function renderSongLiDivider (track, nextTrack, currentIndex, target) { if (hasSameAlbum(track, nextTrack)) { // Large divider with album cover $(target).before( - '
  • ' + + '
  • ' + '' + '

    ' + track.album.name + '

    ' + renderSongLiTrackArtists(track) + '

  • ' @@ -482,11 +482,11 @@ function getMediaClass (uri) { function getMediaHuman (uri) { var scheme = getScheme(uri) for (var i = 0; i < uriHumanList.length; i++) { - if (scheme === uriHumanList[i][0]) { + if (scheme.toLowerCase() === uriHumanList[i][0].toLowerCase()) { return uriHumanList[i][1] } } - return '' + return uri } function isServiceUri (uri) { diff --git a/mopidy_musicbox_webclient/static/js/gui.js b/mopidy_musicbox_webclient/static/js/gui.js index 7eff64c..57fedd5 100644 --- a/mopidy_musicbox_webclient/static/js/gui.js +++ b/mopidy_musicbox_webclient/static/js/gui.js @@ -117,7 +117,7 @@ function setSongInfo (data) { if (data.track.artists) { for (var j = 0; j < data.track.artists.length; j++) { - artistshtml += '' + data.track.artists[j].name + '' + artistshtml += '' + data.track.artists[j].name + '' artiststext += data.track.artists[j].name if (j !== data.track.artists.length - 1) { artistshtml += ', ' @@ -127,7 +127,7 @@ function setSongInfo (data) { arttmp = artistshtml } if (data.track.album && data.track.album.name) { - $('#modalalbum').html('' + data.track.album.name + '') + $('#modalalbum').html('' + data.track.album.name + '') coverArt.getCover(data.track.uri, '#infocover, #controlspopupimage', 'extralarge') } else { $('#modalalbum').html('') @@ -171,14 +171,14 @@ function popupTracks (e, listuri, trackuri, tlid) { if (popupData[trackuri].artists) { if (popupData[trackuri].artists.length === 1) { - child = 'Show Artist' + child = 'Show Artist' $('.popupArtistName').html(popupData[trackuri].artists[0].name) - $('.popupArtistHref').attr('onclick', 'showArtist("' + popupData[trackuri].artists[0].uri + '");') + $('.popupArtistHref').attr('onclick', 'library.showArtist("' + popupData[trackuri].artists[0].uri + '");') $('.popupArtistsDiv').hide() $('.popupArtistsLi').show() } else { for (var j = 0; j < popupData[trackuri].artists.length; j++) { - child += '
  • ' + popupData[trackuri].artists[j].name + '
  • ' + child += '
  • ' + popupData[trackuri].artists[j].name + '
  • ' } $('.popupArtistsLi').hide() $('.popupArtistsLv').html(child).show() @@ -222,7 +222,7 @@ function popupTracks (e, listuri, trackuri, tlid) { function showAlbumPopup (popupId) { uri = $(popupId).data('track') - showAlbum(popupData[uri].album.uri) + library.showAlbum(popupData[uri].album.uri) } /** ******************** @@ -232,14 +232,14 @@ function showAlbumPopup (popupId) { function initSocketevents () { mopidy.on('state:online', function () { showOffline(false) - getCurrentPlaylist() + library.getCurrentPlaylist() updateStatusOfAll() - getPlaylists() + library.getPlaylists() getUriSchemes().then(function () { showFavourites() }) - getBrowseDir() - getSearchSchemes() + library.getBrowseDir() + library.getSearchSchemes() showLoading(false) $(window).hashchange() }) @@ -258,21 +258,21 @@ function initSocketevents () { mopidy.on('event:playlistsLoaded', function (data) { showLoading(true) - getPlaylists() + library.getPlaylists() }) mopidy.on('event:playlistChanged', function (data) { $('#playlisttracksdiv').hide() $('#playlistslistdiv').show() delete playlists[data.playlist.uri] - getPlaylists() + library.getPlaylists() }) mopidy.on('event:playlistDeleted', function (data) { $('#playlisttracksdiv').hide() $('#playlistslistdiv').show() delete playlists[data.uri] - getPlaylists() + library.getPlaylists() }) mopidy.on('event:volumeChanged', function (data) { @@ -296,7 +296,7 @@ function initSocketevents () { }) mopidy.on('event:tracklistChanged', function (data) { - getCurrentPlaylist() + library.getCurrentPlaylist() }) mopidy.on('event:seeked', function (data) { @@ -424,7 +424,7 @@ function locationHashChanged () { $('#navsearch a').addClass($.mobile.activeBtnClass) $('#searchinput').focus() if (customTracklists['mbw:allresultscache'] === '') { - initSearch($('#searchinput').val()) + library.initSearch($('#searchinput').val()) } break case 'stream': @@ -432,12 +432,12 @@ function locationHashChanged () { break case 'artists': if (uri !== '') { - showArtist(uri) + library.showArtist(uri) } break case 'albums': if (uri !== '') { - showAlbum(uri) + library.showAlbum(uri) } break } diff --git a/mopidy_musicbox_webclient/static/js/images.js b/mopidy_musicbox_webclient/static/js/images.js index 0a1b531..7da092b 100644 --- a/mopidy_musicbox_webclient/static/js/images.js +++ b/mopidy_musicbox_webclient/static/js/images.js @@ -77,7 +77,7 @@ var coverArt = { } } }, error: function (code, message) { - console.log('Error retrieving album info from last.fm', code, message) + console.error('Error retrieving album info from last.fm', code, message) }}) }, @@ -94,7 +94,7 @@ var coverArt = { } } }, error: function (code, message) { - console.log('Error retrieving artist info from last.fm', code, message) + console.error('Error retrieving artist info from last.fm', code, message) }}) } } diff --git a/mopidy_musicbox_webclient/static/js/library.js b/mopidy_musicbox_webclient/static/js/library.js index 5047c5d..4bf0387 100644 --- a/mopidy_musicbox_webclient/static/js/library.js +++ b/mopidy_musicbox_webclient/static/js/library.js @@ -1,348 +1,344 @@ +var library = { + /** ******************************* * Search *********************************/ -function searchPressed (key) { - var value = $('#searchinput').val() - switchContent('search') + searchPressed: function (key) { + var value = $('#searchinput').val() + switchContent('search') - if (key === 13) { - initSearch() - return false - } - return true -} - -// init search -function initSearch () { - var value = $('#searchinput').val() - var searchService = $('#selectSearchService').val() - - if ((value.length < 100) && (value.length > 0)) { - showLoading(true) - // hide ios/android keyboard - document.activeElement.blur() - $('input').blur() - - delete customTracklists[URI_SCHEME + ':allresultscache'] - delete customTracklists[URI_SCHEME + ':artistresultscache'] - delete customTracklists[URI_SCHEME + ':albumresultscache'] - delete customTracklists[URI_SCHEME + ':trackresultscache'] - $('#searchartists').hide() - $('#searchalbums').hide() - $('#searchtracks').hide() - - if (searchService !== 'all') { - mopidy.library.search({'query': {any: [value]}, 'uris': [searchService + ':']}).then(processSearchResults, console.error) - } else { - mopidy.getUriSchemes().then(function (schemes) { - var query = {} - var uris = [] - - var regexp = $.map(schemes, function (scheme) { - return '^' + scheme + ':' - }).join('|') - - var match = value.match(regexp) - if (match) { - var scheme = match[0] - query = {uri: [value]} - uris = [scheme] - } else { - query = {any: [value]} - } - mopidy.library.search({'query': query, 'uris': uris}).then(processSearchResults, console.error) - }) + if (key === 13) { + library.initSearch() + return false } - } -} + return true + }, + + // init search + initSearch: function () { + var value = $('#searchinput').val() + var searchService = $('#selectSearchService').val() + $.cookie('searchScheme', searchService, { expires: 365 }) + + if ((value.length < 100) && (value.length > 0)) { + showLoading(true) + // hide ios/android keyboard + document.activeElement.blur() + $('input').blur() + + delete customTracklists[URI_SCHEME + ':allresultscache'] + delete customTracklists[URI_SCHEME + ':artistresultscache'] + delete customTracklists[URI_SCHEME + ':albumresultscache'] + delete customTracklists[URI_SCHEME + ':trackresultscache'] + $('#searchartists').hide() + $('#searchalbums').hide() + $('#searchtracks').hide() + + if (searchService !== 'all') { + mopidy.library.search({'query': {any: [value]}, 'uris': [searchService + ':']}).then(library.processSearchResults, console.error) + } else { + mopidy.getUriSchemes().then(function (schemes) { + var query = {} + var uris = [] + + var regexp = $.map(schemes, function (scheme) { + return '^' + scheme + ':' + }).join('|') + + var match = value.match(regexp) + if (match) { + var scheme = match[0] + query = {uri: [value]} + uris = [scheme] + } else { + query = {any: [value]} + } + mopidy.library.search({'query': query, 'uris': uris}).then(library.processSearchResults, console.error) + }) + } + } + }, /** ****************************************************** * process results of a search *********************************************************/ + processSearchResults: function (resultArr) { + $(SEARCH_TRACK_TABLE).empty() + $(SEARCH_ARTIST_TABLE).empty() + $(SEARCH_ALBUM_TABLE).empty() -// # speed clone http://jsperf.com/cloning-an-object/2 -function clone (obj) { - var target = {} - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - target[i] = obj[i] - } - } - return target -} + // Merge results from different backends. + // TODO should of coures have multiple tables + var results = {'tracks': [], 'artists': [], 'albums': []} + var i, j + var emptyResult = true -function processSearchResults (resultArr) { - $(SEARCH_TRACK_TABLE).empty() - $(SEARCH_ARTIST_TABLE).empty() - $(SEARCH_ALBUM_TABLE).empty() - - // Merge results from different backends. - // TODO should of coures have multiple tables - var results = {'tracks': [], 'artists': [], 'albums': []} - var i, j - var emptyResult = true - - for (i = 0; i < resultArr.length; i++) { - if (resultArr[i].tracks) { - for (j = 0; j < resultArr[i].tracks.length; j++) { - results.tracks.push(resultArr[i].tracks[j]) - emptyResult = false + for (i = 0; i < resultArr.length; i++) { + if (resultArr[i].tracks) { + for (j = 0; j < resultArr[i].tracks.length; j++) { + results.tracks.push(resultArr[i].tracks[j]) + emptyResult = false + } } - } - if (resultArr[i].artists) { - for (j = 0; j < resultArr[i].artists.length; j++) { - results.artists.push(resultArr[i].artists[j]) - emptyResult = false + if (resultArr[i].artists) { + for (j = 0; j < resultArr[i].artists.length; j++) { + results.artists.push(resultArr[i].artists[j]) + emptyResult = false + } } - } - if (resultArr[i].albums) { - for (j = 0; j < resultArr[i].albums.length; j++) { - results.albums.push(resultArr[i].albums[j]) - emptyResult = false - } - } - } - - customTracklists[URI_SCHEME + ':trackresultscache'] = results.tracks - - if (emptyResult) { - $('#searchtracks').show() - $(SEARCH_TRACK_TABLE).append( - '
  • No tracks found...

  • ' - ) - toast('No results') - showLoading(false) - return false - } - - if (results.artists.length > 0) { - $('#searchartists').show() - } - - if (results.albums.length > 0) { - $('#searchalbums').show() - } - - if (results.tracks.length > 0) { - $('#searchtracks').show() - } - - // Returns a string where {x} in template is replaced by tokens[x]. - function theme (template, tokens) { - return template.replace(/{[^}]+}/g, function (match) { - return tokens[match.slice(1, -1)] - }) - } - - // 'Show more' pattern - var showMorePattern = '
  • Show {count} more
  • ' - - // Artist results - var child = '' - var pattern = '
  • {name}
  • ' - var tokens - - for (i = 0; i < results.artists.length; i++) { - tokens = { - 'id': results.artists[i].uri, - 'name': results.artists[i].name, - 'class': getMediaClass(results.artists[i].uri) - } - - // Add 'Show all' item after a certain number of hits. - if (i === 4 && results.artists.length > 5) { - child += theme(showMorePattern, {'count': results.artists.length - i}) - pattern = pattern.replace('
  • ', '
  • ') - } - - child += theme(pattern, tokens) - } - - // Inject list items, refresh listview and hide superfluous items. - $(SEARCH_ARTIST_TABLE).html(child).listview('refresh').find('.overflow').hide() - - // Album results - child = '' - pattern = '
  • ' - pattern += '
    {albumName}
    ' - pattern += '

    {artistName}

    ' - pattern += '
  • ' - - for (i = 0; i < results.albums.length; i++) { - tokens = { - 'albumId': results.albums[i].uri, - 'albumName': results.albums[i].name, - 'artistName': '', - 'albumYear': results.albums[i].date, - 'class': getMediaClass(results.albums[i].uri) - } - if (results.albums[i].artists) { - for (j = 0; j < results.albums[i].artists.length; j++) { - if (results.albums[i].artists[j].name) { - tokens.artistName += results.albums[i].artists[j].name + ' ' + if (resultArr[i].albums) { + for (j = 0; j < resultArr[i].albums.length; j++) { + results.albums.push(resultArr[i].albums[j]) + emptyResult = false } } } - if (tokens.albumYear) { - tokens.artistName += '(' + tokens.albumYear + ')' - } - // Add 'Show all' item after a certain number of hits. - if (i === 4 && results.albums.length > 5) { - child += theme(showMorePattern, {'count': results.albums.length - i}) - pattern = pattern.replace('
  • ', '
  • ') + + customTracklists[URI_SCHEME + ':trackresultscache'] = results.tracks + + if (emptyResult) { + $('#searchtracks').show() + $(SEARCH_TRACK_TABLE).append( + '
  • No tracks found...

  • ' + ) + toast('No results') + showLoading(false) + return false } - child += theme(pattern, tokens) - } - // Inject list items, refresh listview and hide superfluous items. - $(SEARCH_ALBUM_TABLE).html(child).listview('refresh').find('.overflow').hide() + if (results.artists.length > 0) { + $('#searchartists').show() + } - // Track results - resultsToTables(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME + ':trackresultscache') + if (results.albums.length > 0) { + $('#searchalbums').show() + } - showLoading(false) -} + if (results.tracks.length > 0) { + $('#searchtracks').show() + } -function toggleSearch () { - $('#albumresulttable tr').removeClass('hidden') - $('#artistresulttable tr').removeClass('hidden') -} + // Returns a string where {x} in template is replaced by tokens[x]. + function theme (template, tokens) { + return template.replace(/{[^}]+}/g, function (match) { + return tokens[match.slice(1, -1)] + }) + } + + // 'Show more' pattern + var showMorePattern = '
  • Show {count} more
  • ' + + // Artist results + var child = '' + var pattern = '
  • {name}
  • ' + var tokens + + for (i = 0; i < results.artists.length; i++) { + tokens = { + 'id': results.artists[i].uri, + 'name': results.artists[i].name, + 'class': getMediaClass(results.artists[i].uri) + } + + // Add 'Show all' item after a certain number of hits. + if (i === 4 && results.artists.length > 5) { + child += theme(showMorePattern, {'count': results.artists.length - i}) + pattern = pattern.replace('
  • ', '
  • ') + } + + child += theme(pattern, tokens) + } + + // Inject list items, refresh listview and hide superfluous items. + $(SEARCH_ARTIST_TABLE).html(child).listview('refresh').find('.overflow').hide() + + // Album results + child = '' + pattern = '
  • ' + pattern += '
    {albumName}
    ' + pattern += '

    {artistName}

    ' + pattern += '
  • ' + + for (i = 0; i < results.albums.length; i++) { + tokens = { + 'albumId': results.albums[i].uri, + 'albumName': results.albums[i].name, + 'artistName': '', + 'albumYear': results.albums[i].date, + 'class': getMediaClass(results.albums[i].uri) + } + if (results.albums[i].artists) { + for (j = 0; j < results.albums[i].artists.length; j++) { + if (results.albums[i].artists[j].name) { + tokens.artistName += results.albums[i].artists[j].name + ' ' + } + } + } + if (tokens.albumYear) { + tokens.artistName += '(' + tokens.albumYear + ')' + } + // Add 'Show all' item after a certain number of hits. + if (i === 4 && results.albums.length > 5) { + child += theme(showMorePattern, {'count': results.albums.length - i}) + pattern = pattern.replace('
  • ', '
  • ') + } + + child += theme(pattern, tokens) + } + // Inject list items, refresh listview and hide superfluous items. + $(SEARCH_ALBUM_TABLE).html(child).listview('refresh').find('.overflow').hide() + + // Track results + resultsToTables(results.tracks, SEARCH_TRACK_TABLE, URI_SCHEME + ':trackresultscache') + + showLoading(false) + }, /** ******************************* * Playlists & Browse *********************************/ + getPlaylists: function () { + // get playlists without tracks + mopidy.playlists.asList().then(processGetPlaylists, console.error) + }, -function getPlaylists () { - // get playlists without tracks - mopidy.playlists.asList().then(processGetPlaylists, console.error) -} + getBrowseDir: function (rootdir) { + // get directory to browse + showLoading(true) + if (!rootdir) { + browseStack.pop() + rootdir = browseStack[browseStack.length - 1] + } else { + browseStack.push(rootdir) + } + if (!rootdir) { + rootdir = null + } + mopidy.library.browse({'uri': rootdir}).then(processBrowseDir, console.error) + }, -function getBrowseDir (rootdir) { - // get directory to browse - showLoading(true) - if (!rootdir) { - browseStack.pop() - rootdir = browseStack[browseStack.length - 1] - } else { - browseStack.push(rootdir) - } - if (!rootdir) { - rootdir = null - } - mopidy.library.browse({'uri': rootdir}).then(processBrowseDir, console.error) -} - -function getCurrentPlaylist () { - mopidy.tracklist.getTlTracks().then(processCurrentPlaylist, console.error) -} + getCurrentPlaylist: function () { + mopidy.tracklist.getTlTracks().then(processCurrentPlaylist, console.error) + }, /** ****************************************************** * Show tracks of playlist ********************************************************/ -function togglePlaylists () { - if ($(window).width() <= 960) { - $('#playlisttracksdiv').toggle(); - // Hide other div - ($('#playlisttracksdiv').is(':visible')) ? $('#playlistslistdiv').hide() : $('#playlistslistdiv').show() - } else { - $('#playlisttracksdiv').show() - $('#playlistslistdiv').show() - } - return true -} - -function showTracklist (uri) { - showLoading(true) - $(PLAYLIST_TABLE).empty() - togglePlaylists() - var tracks = getPlaylistTracks(uri).then(function (tracks) { - resultsToTables(tracks, PLAYLIST_TABLE, uri, 'return togglePlaylists();', true) - showLoading(false) - }) - updatePlayIcons(uri) - $('#playlistslist li a').each(function () { - $(this).removeClass('playlistactive') - if (this.id === uri) { - $(this).addClass('playlistactive') + togglePlaylists: function () { + if ($(window).width() <= 960) { + $('#playlisttracksdiv').toggle(); + // Hide other div + ($('#playlisttracksdiv').is(':visible')) ? $('#playlistslistdiv').hide() : $('#playlistslistdiv').show() + } else { + $('#playlisttracksdiv').show() + $('#playlistslistdiv').show() } - }) - return false -} + return true + }, -/** **** +/** ********** * Lookups - */ - -function showArtist (nwuri) { - $('#popupQueue').popup('close') - $('#popupTracks').popup('close') - $('#controlsmodal').popup('close') - $(ARTIST_TABLE).empty() - -// TODO cache - $('#h_artistname').html('') - showLoading(true) - mopidy.library.lookup({'uris': [nwuri]}).then(function (resultDict) { - var resultArr = resultDict[nwuri] - resultArr.uri = nwuri - processArtistResults(resultArr) - }, console.error) - switchContent('artists', nwuri) - scrollToTop() - return false -} - -function showAlbum (uri) { - $('#popupQueue').popup('close') - $('#popupTracks').popup('close') - $('#controlsmodal').popup('close') - $(ALBUM_TABLE).empty() - // fill from cache - var pl = getTracksFromUri(uri, true) - if (pl.length > 0) { - albumTracksToTable(pl, ALBUM_TABLE, uri) - var albumname = getAlbum(pl) - var artistname = getArtist(pl) - $('#h_albumname').html(albumname) - $('#h_albumartist').html(artistname) - $('#coverpopupalbumname').html(albumname) - $('#coverpopupartist').html(artistname) - showLoading(false) - mopidy.library.lookup({'uris': [uri]}).then(function (resultDict) { - var resultArr = resultDict[uri] - resultArr.uri = uri - processAlbumResults(resultArr) - }, console.error) - } else { + ************/ + showTracklist: function (uri) { showLoading(true) - $('#h_albumname').html('') - $('#h_albumartist').html('') - mopidy.library.lookup({'uris': [uri]}).then(function (resultDict) { - var resultArr = resultDict[uri] - resultArr.uri = uri - processAlbumResults(resultArr) + $(PLAYLIST_TABLE).empty() + library.togglePlaylists() + var tracks = getPlaylistTracks(uri).then(function (tracks) { + resultsToTables(tracks, PLAYLIST_TABLE, uri, 'return library.togglePlaylists();', true) + showLoading(false) + }) + updatePlayIcons(uri) + $('#playlistslist li a').each(function () { + $(this).removeClass('playlistactive') + if (this.id === uri) { + $(this).addClass('playlistactive') + } + }) + return false + }, + + showArtist: function (nwuri) { + $('#popupQueue').popup('close') + $('#popupTracks').popup('close') + $('#controlsmodal').popup('close') + $(ARTIST_TABLE).empty() + + // TODO cache + $('#h_artistname').html('') + showLoading(true) + mopidy.library.lookup({'uris': [nwuri]}).then(function (resultDict) { + var resultArr = resultDict[nwuri] + resultArr.uri = nwuri + processArtistResults(resultArr) + }, console.error) + switchContent('artists', nwuri) + scrollToTop() + return false + }, + + showAlbum: function (uri) { + $('#popupQueue').popup('close') + $('#popupTracks').popup('close') + $('#controlsmodal').popup('close') + $(ALBUM_TABLE).empty() + // fill from cache + var pl = getTracksFromUri(uri, true) + if (pl.length > 0) { + albumTracksToTable(pl, ALBUM_TABLE, uri) + var albumname = getAlbum(pl) + var artistname = getArtist(pl) + $('#h_albumname').html(albumname) + $('#h_albumartist').html(artistname) + $('#coverpopupalbumname').html(albumname) + $('#coverpopupartist').html(artistname) + showLoading(false) + mopidy.library.lookup({'uris': [uri]}).then(function (resultDict) { + var resultArr = resultDict[uri] + resultArr.uri = uri + processAlbumResults(resultArr) + }, console.error) + } else { + showLoading(true) + $('#h_albumname').html('') + $('#h_albumartist').html('') + mopidy.library.lookup({'uris': [uri]}).then(function (resultDict) { + var resultArr = resultDict[uri] + resultArr.uri = uri + processAlbumResults(resultArr) + }, console.error) + } + // show page + switchContent('albums', uri) + scrollToTop() + return false + }, + + getSearchSchemes: function () { + var backendName + var searchScheme = $.cookie('searchScheme') + if (searchScheme) { + searchScheme = searchScheme.replace(/"/g, '') + } else { + searchScheme = 'all' + } + $('#selectSearchService').empty() + $('#selectSearchService').append(new Option('All backends', 'all')) + mopidy.getUriSchemes().then(function (schemesArray) { + for (var i = 0; i < schemesArray.length; i++) { + backendName = getMediaHuman(schemesArray[i]) + backendName = backendName.charAt(0).toUpperCase() + backendName.slice(1) + $('#selectSearchService').append(new Option(backendName, schemesArray[i])) + } + $('#selectSearchService').val(searchScheme) + $('#selectSearchService').selectmenu('refresh', true) }, console.error) } - // show page - switchContent('albums', uri) - scrollToTop() - return false } -function getSearchSchemes () { - mopidy.getUriSchemes().then( - function (schemesArray) { - var humanIndex - $('#selectSearchService').children().remove().end() - $('#selectSearchService').append(new Option('All services', 'all')) - for (var i = 0; i < schemesArray.length; i++) { - for (var j = 0; j < uriHumanList.length; j++) { - if (uriHumanList[j][0] === schemesArray[i].toLowerCase()) { - $('#selectSearchService').append(new Option(uriHumanList[j][1], schemesArray[i])) - } - } - } - $('#selectSearchService').selectmenu('refresh', true) - }, console.error - ) +// TODO: Remove this once JavaScript codebase has been completely modularized +// in favour of bundling everything using 'browserify'. +if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + module.exports = library + } } diff --git a/mopidy_musicbox_webclient/static/js/process_ws.js b/mopidy_musicbox_webclient/static/js/process_ws.js index 4c0d287..bbbb7d4 100644 --- a/mopidy_musicbox_webclient/static/js/process_ws.js +++ b/mopidy_musicbox_webclient/static/js/process_ws.js @@ -78,7 +78,7 @@ function processPlaystate (data) { function processBrowseDir (resultArr) { $(BROWSE_TABLE).empty() if (browseStack.length > 0) { - renderSongLiBackButton(resultArr, BROWSE_TABLE, 'return getBrowseDir();') + renderSongLiBackButton(resultArr, BROWSE_TABLE, 'return library.getBrowseDir();') } if (!resultArr || resultArr.length === 0) { showLoading(false) @@ -113,7 +113,7 @@ function processBrowseDir (resultArr) { iconClass = getMediaClass(resultArr[i].uri) } $(BROWSE_TABLE).append( - '
  • ' + + '
  • ' + '

    ' + resultArr[i].name + '

  • ' ) } @@ -163,7 +163,7 @@ function processGetPlaylists (resultArr) { var starred = '' for (var i = 0; i < resultArr.length; i++) { - var li_html = '
  • ' + var li_html = '
  • ' if (isSpotifyStarredPlaylist(resultArr[i])) { starred = li_html + '★ Spotify Starred Tracks
  • ' + tmp } else if (isFavouritesPlaylist(resultArr[i])) { diff --git a/mopidy_musicbox_webclient/static/mb.appcache b/mopidy_musicbox_webclient/static/mb.appcache index 5844c18..a40ec97 100644 --- a/mopidy_musicbox_webclient/static/mb.appcache +++ b/mopidy_musicbox_webclient/static/mb.appcache @@ -1,6 +1,6 @@ CACHE MANIFEST -# 2016-03-14:v1 +# 2016-03-19:v1 NETWORK: * diff --git a/tests/test_images.js b/tests/test_images.js index 8d52232..0d8769f 100644 --- a/tests/test_images.js +++ b/tests/test_images.js @@ -12,12 +12,6 @@ var coverArt = require('../mopidy_musicbox_webclient/static/js/images.js') var images before(function () { - html = - '' + - '' - $(document).ready(function () { - $(document.body).add(html) - }) mopidy = sinon.stub(new Mopidy({callingConvention: 'by-position-or-by-name'})) images = $('') }) @@ -156,7 +150,7 @@ describe('CoverArt', function () { var getInfoStub = sinon.stub(coverArt.lastfm.album, 'getInfo') getInfoStub.yieldsTo('error', 'code', 'message') - var consoleSpy = sinon.spy(console, 'log') + var consoleSpy = sinon.spy(console, 'error') coverArt.getCoverFromLastFm(track, images, '') assert(consoleSpy.calledOnce) @@ -190,7 +184,7 @@ describe('CoverArt', function () { var getInfoStub = sinon.stub(coverArt.lastfm.artist, 'getInfo') getInfoStub.yieldsTo('error', 'code', 'message') - var consoleSpy = sinon.spy(console, 'log') + var consoleSpy = sinon.spy(console, 'error') coverArt.getArtistImage('mockArtist', images, 'small') assert(consoleSpy.calledOnce) diff --git a/tests/test_library.js b/tests/test_library.js new file mode 100644 index 0000000..7895cb2 --- /dev/null +++ b/tests/test_library.js @@ -0,0 +1,54 @@ +var chai = require('chai') +var should = chai.should() +var expect = chai.expect +var assert = chai.assert +chai.use(require('chai-string')) +chai.use(require('chai-jquery')) + +var sinon = require('sinon') + +var coverArt = require('../mopidy_musicbox_webclient/static/js/library.js') + +var selectID = '#selectSearchService' +var schemesArray + +before(function () { + $(document.body).append('') + $('#selectSearchService').selectmenu() +}) +describe('Library', function () { + describe('#getSearchSchemes()', function () { + beforeEach(function () { + schemesArray = ['mockScheme1', 'mockScheme2', 'mockScheme3'] + mopidy = { + getUriSchemes: function () { return $.when(schemesArray) } + } + $(selectID).empty() + }) + + it('should add human-readable options for backend schemes', function () { + uriHumanList = [['mockScheme2', 'mockUriHuman2']] + + library.getSearchSchemes() + assert($(selectID).children().length === schemesArray.length + 1) + $(selectID).children(':eq(2)').should.have.text('MockUriHuman2') + }) + + it('should get default value from cookie', function () { + $.cookie('searchScheme', 'mockScheme3') + library.getSearchSchemes() + $(selectID + ' option:selected').should.have.value('mockScheme3') + }) + + it('should default to "all" backends if no cookie is available', function () { + $.removeCookie('searchScheme') + library.getSearchSchemes() + $(selectID + ' option:selected').should.have.value('all') + }) + + it('should capitalize first character of backend schema', function () { + library.getSearchSchemes() + $(selectID).children(':eq(1)').should.have.text('MockScheme1') + }) + }) +})