diff --git a/README.rst b/README.rst index 9cdb8303..860c0525 100644 --- a/README.rst +++ b/README.rst @@ -123,6 +123,8 @@ v2.4.0 (UNRELEASED) - 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. +- The last scroll position is now always saved when navigating between pages or browsing the library. + (Fixes: `#73 `_, `#93 `_). v2.3.0 (2016-05-15) ------------------- diff --git a/mopidy_musicbox_webclient/static/js/custom_scripting.js b/mopidy_musicbox_webclient/static/js/custom_scripting.js index f8b6ca15..bcb97614 100644 --- a/mopidy_musicbox_webclient/static/js/custom_scripting.js +++ b/mopidy_musicbox_webclient/static/js/custom_scripting.js @@ -20,6 +20,17 @@ $(document).bind('mobileinit', configureJQueryMobile) + // Extension: timeout to detect end of scrolling action. + $.fn.scrollEnd = function (callback, timeout) { + $(this).scroll(function () { + var $this = $(this) + if ($this.data('scrollTimeout')) { + clearTimeout($this.data('scrollTimeout')) + } + $this.data('scrollTimeout', setTimeout(callback, timeout)) + }) + } + return configureJQueryMobile })) diff --git a/mopidy_musicbox_webclient/static/js/functionsvars.js b/mopidy_musicbox_webclient/static/js/functionsvars.js index 97525632..a2150768 100644 --- a/mopidy_musicbox_webclient/static/js/functionsvars.js +++ b/mopidy_musicbox_webclient/static/js/functionsvars.js @@ -28,8 +28,7 @@ var artiststext = '' var songname = '' var songdata = {'track': {}, 'tlid': -1} -var playlisttracksScroll -var playlistslistScroll +var pageScrollPos = {} var STREAMS_PLAYLIST_NAME = '[Radio Streams]' var STREAMS_PLAYLIST_SCHEME = 'm3u' @@ -159,9 +158,8 @@ var audioExt = [ ] function scrollToTop () { - var divtop = 0 $('body,html').animate({ - scrollTop: divtop + scrollTop: 0 }, 250) } diff --git a/mopidy_musicbox_webclient/static/js/gui.js b/mopidy_musicbox_webclient/static/js/gui.js index c61acd5c..19126800 100644 --- a/mopidy_musicbox_webclient/static/js/gui.js +++ b/mopidy_musicbox_webclient/static/js/gui.js @@ -23,48 +23,10 @@ function resizeMb () { $('#infoname').html(songdata.track.name) $('#infoartist').html(artiststext) - if ($(window).width() <= 960) { -// $('#playlisttracksdiv').hide(); -// $('#playlistslistdiv').show(); - } else { + if ($(window).width() > 960) { $('#playlisttracksdiv').show() $('#playlistslistdiv').show() } -// //set height of playlist scrollers -/* if ($(window).width() > 960) { - $('#playlisttracksdiv').show(); - $('#playlistslistdiv').show(); - $('.scroll').removeClass('height').removeClass('width'); - $('#playlistspane').removeClass('height').removeClass('width'); - } else { - if ( $('#playlisttracksdiv').is(':visible') == $('#playlistslistdiv').is(':visible')) { - $('#playlisttracksdiv').hide(); - $('#playlistslistdiv').show(); - $('.scroll').addClass('height', '99%').addClass('width', '99%'); - $('#playlistspane').addClass('height', '99%').addClass('width', '99%'); - } - } - - if ($('#playlisttracksdiv').is(':visible') && !$('#playlisttracksback').is(':visible') ) { - $('.scroll').height($(window).height() - 96); - //jqm added something which it shouldnt (at least in this case) I guess - // $('#playlistspane').removeClass('height').height($(window).height() - 110); - $('.scroll').removeClass('height').removeClass('width'); - $('#playlistspane').removeClass('height').removeClass('width'); - $('#playlisttracksdiv').show(); - $('#playlistslistdiv').show(); - } else { - $('.scroll').addClass('height', '99%').addClass('width', '99%'); - $('#playlistspane').addClass('height', '99%').addClass('width', '99%'); - $('#playlisttracksdiv').show(); - $('#playlistslistdiv').show(); - } - - if (isMobileWebkit && ($(window).width() > 480)) { - playlistslistScroll.refresh(); - playlisttracksScroll.refresh(); - } -*/ } function setSongTitle (title, refresh_ui) { @@ -400,42 +362,34 @@ function locationHashChanged () { var hash = document.location.hash.split('?') // remove # var divid = hash[0].substr(1) + var uri = hash[1] + setHeadline(divid) - var uri = hash[1] - $('.mainNav a').removeClass('ui-state-active ui-state-persist ui-btn-active') - // i don't know why some li elements have those classes, but they do, so we need to remove them - $('.mainNav li').removeClass('ui-state-active ui-state-persist ui-btn-active') if ($(window).width() < 560) { $('#panel').panel('close') } - $('.pane').hide() - $('#' + divid + 'pane').show() + $('.mainNav a').removeClass($.mobile.activeBtnClass) + // i don't know why some li elements have those classes, but they do, so we need to remove them + $('.mainNav li').removeClass($.mobile.activeBtnClass) + $('#nav' + divid + ' a').addClass($.mobile.activeBtnClass) // Update navigation pane + + $('.pane').hide() // Hide all pages + $('#' + divid + 'pane').show() // Switch to active pane + + if (typeof pageScrollPos[divid] !== 'undefined') { // Set scroll position + window.scrollTo(0, pageScrollPos[divid]) + } switch (divid) { - case 'home': - $('#navhome a').addClass('ui-state-active ui-state-persist ui-btn-active') - break - case 'nowPlaying': - $('#navnowPlaying a').addClass('ui-state-active ui-state-persist ui-btn-active') - break - case 'current': - $('#navcurrent a').addClass('ui-state-active ui-state-persist ui-btn-active') - break - case 'playlists': - $('#navplaylists a').addClass('ui-state-active ui-state-persist ui-btn-active') - break - case 'browse': - $('#navbrowse a').addClass('ui-state-active ui-state-persist ui-btn-active') + case 'nowPlaying': // Show 'now playing' footer + $('#normalFooter').hide() + $('#nowPlayingFooter').show() break case 'search': - $('#navsearch a').addClass($.mobile.activeBtnClass) $('#searchinput').focus() break - case 'stream': - $('#navstream a').addClass('ui-state-active ui-state-persist ui-btn-active') - break case 'artists': if (uri !== '') { library.showArtist(uri) @@ -446,15 +400,7 @@ function locationHashChanged () { library.showAlbum(uri) } break - } - - // switch the footer - switch (divid) { - case 'nowPlaying': - $('#normalFooter').hide() - $('#nowPlayingFooter').show() - break - default: + default: // Default footer $('#normalFooter').show() $('#nowPlayingFooter').hide() } @@ -483,6 +429,16 @@ $(document).ready(function (event) { } $(window).hashchange() + // Remember scroll position for each page and browsed folder + $(window).scrollEnd(function () { + var divid = document.location.hash.split('?')[0].substr(1) + if (divid === 'browse' && browseStack.length > 0) { + browseStack[browseStack.length - 1].scrollPos = window.pageYOffset + } else { + pageScrollPos[divid] = window.pageYOffset + } + }, 250) + initgui = false // only show backbutton if in UIWebview diff --git a/mopidy_musicbox_webclient/static/js/library.js b/mopidy_musicbox_webclient/static/js/library.js index 4c132e58..c1c57fbe 100644 --- a/mopidy_musicbox_webclient/static/js/library.js +++ b/mopidy_musicbox_webclient/static/js/library.js @@ -215,16 +215,18 @@ showLoading(true) if (!rootdir) { browseStack.pop() - rootdir = browseStack[browseStack.length - 1] || null - } else { - if (rootdir !== browseStack[browseStack.length - 1]) { - browseStack.push(rootdir) + if (browseStack.length > 0) { + rootdir = browseStack[browseStack.length - 1].uri // Navigated one level up + } else { + rootdir = null // Navigated to top of library } + } else if (browseStack.length === 0 || rootdir !== browseStack[browseStack.length - 1].uri) { + browseStack.push({'uri': rootdir, 'scrollPos': 0}) // Navigated one level down } mopidy.library.browse({'uri': rootdir}).then(function (resultArr) { processBrowseDir(resultArr) if (rootdir === null) { - $('.refreshLibraryBtnDiv').hide() + $('.refreshLibraryBtnDiv').hide() // Mopidy does not support refreshing list of backends. } else { $('.refreshLibraryBtnDiv').show() $('#refreshLibraryBtn').data('url', rootdir) diff --git a/mopidy_musicbox_webclient/static/js/process_ws.js b/mopidy_musicbox_webclient/static/js/process_ws.js index fa4f1920..da44feec 100644 --- a/mopidy_musicbox_webclient/static/js/process_ws.js +++ b/mopidy_musicbox_webclient/static/js/process_ws.js @@ -92,6 +92,7 @@ function processBrowseDir (resultArr) { var html = '' var i + // Render list of tracks for (i = 0, index = 0; i < resultArr.length; i++) { if (resultArr[i].type === 'track') { previousRef = ref || undefined @@ -112,9 +113,13 @@ function processBrowseDir (resultArr) { } $(BROWSE_TABLE).append(html) + if (browseStack.length > 0) { + window.scrollTo(0, browseStack[browseStack.length - 1].scrollPos || 0) // Restore scroll position + } updatePlayIcons(songdata.track.uri, songdata.tlid, controls.getIconForAction()) + // Look up track details and add album headers if (uris.length > 0) { mopidy.library.lookup({'uris': uris}).then(function (resultDict) { // Break into albums and put in tables diff --git a/mopidy_musicbox_webclient/static/mb.appcache b/mopidy_musicbox_webclient/static/mb.appcache index e0f40685..4abdbd8f 100644 --- a/mopidy_musicbox_webclient/static/mb.appcache +++ b/mopidy_musicbox_webclient/static/mb.appcache @@ -1,6 +1,6 @@ CACHE MANIFEST -# 2017-01-18:v2 +# 2017-01-22:v1 NETWORK: *