From 121c165a39bb533a1670b0be3e7a2311ca418f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Sat, 13 Sep 2014 17:58:31 +0100 Subject: [PATCH] Scroll to correct position when fetching more lines Fixes #406 --- js/connection.js | 27 ++++++++++++--------------- js/glowingbear.js | 10 +++++++--- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/js/connection.js b/js/connection.js index 2945d4a..f938783 100644 --- a/js/connection.js +++ b/js/connection.js @@ -234,9 +234,10 @@ weechat.factory('connection', //XXX move to handlers? // delete old lines and add new ones var oldLength = buffer.lines.length; - // Whether to set the readmarker to the middle position - // Don't do that if we didn't get any more lines than we already had - var setReadmarker = (buffer.lastSeen >= 0) && (oldLength !== buffer.lines.length); + // whether we already had all unread lines + var hadAllUnreadLines = buffer.lastSeen >= 0; + + // clear the old lines buffer.lines.length = 0; // We need to set the number of requested lines to 0 here, because parsing a line // increments it. This is needed to also count newly arriving lines while we're @@ -248,23 +249,19 @@ weechat.factory('connection', // Parse the lines handlers.handleLineInfo(lineinfo, true); - if (setReadmarker) { - // Read marker was somewhere in the old lines - we don't need it any more, - // set it to the boundary between old and new. This way, we stay at the exact - // same position in the text through the scrollWithBuffer below - buffer.lastSeen = buffer.lines.length - oldLength - 1; - } else { - // We are currently fetching at least some unread lines, so we need to keep - // the read marker position correct - buffer.lastSeen -= oldLength; - } + // Correct the read marker for the lines that were counted twice + buffer.lastSeen -= oldLength; + // We requested more lines than we got, no more lines. if (linesReceivedCount < numLines) { buffer.allLinesFetched = true; } $rootScope.loadingLines = false; - // Scroll read marker to the center of the screen - $rootScope.scrollWithBuffer(true); + + // Only scroll to read marker if we didn't have all unread lines previously, but have them now + var scrollToReadmarker = !hadAllUnreadLines && buffer.lastSeen >= 0; + // Scroll to correct position + $rootScope.scrollWithBuffer(scrollToReadmarker, true); }); }; diff --git a/js/glowingbear.js b/js/glowingbear.js index d307890..0b2a5b6 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -432,7 +432,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', return connection.fetchMoreLines(numLines); }; - $rootScope.scrollWithBuffer = function(nonIncremental) { + $rootScope.scrollWithBuffer = function(scrollToReadmarker, moreLines) { // First, get scrolling status *before* modification // This is required to determine where we were in the buffer pre-change var bl = document.getElementById('bufferlines'); @@ -443,11 +443,15 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // Determine if we want to scroll at all // Give the check 3 pixels of slack so you don't have to hit // the exact spot. This fixes a bug in some browsers - if ((nonIncremental && sTop < sVal) || (Math.abs(sTop - sVal) < 3)) { + if (((scrollToReadmarker || moreLines) && sTop < sVal) || (Math.abs(sTop - sVal) < 3)) { var readmarker = document.querySelector(".readmarker"); - if (nonIncremental && readmarker) { + if (scrollToReadmarker && readmarker) { // Switching channels, scroll to read marker bl.scrollTop = readmarker.offsetTop - readmarker.parentElement.scrollHeight + readmarker.scrollHeight; + } else if (moreLines) { + // We fetched more lines but the read marker is still out of view + // Keep the scroll position constant + bl.scrollTop = bl.scrollHeight - bl.clientHeight - sVal; } else { // New message, scroll with buffer (i.e. to bottom) bl.scrollTop = bl.scrollHeight - bl.clientHeight;