Scroll to correct position when fetching more lines

Fixes #406
This commit is contained in:
Lorenz Hübschle-Schneider 2014-09-13 17:58:31 +01:00
parent 8758cad336
commit 121c165a39
2 changed files with 19 additions and 18 deletions

View file

@ -234,9 +234,10 @@ weechat.factory('connection',
//XXX move to handlers? //XXX move to handlers?
// delete old lines and add new ones // delete old lines and add new ones
var oldLength = buffer.lines.length; var oldLength = buffer.lines.length;
// Whether to set the readmarker to the middle position // whether we already had all unread lines
// Don't do that if we didn't get any more lines than we already had var hadAllUnreadLines = buffer.lastSeen >= 0;
var setReadmarker = (buffer.lastSeen >= 0) && (oldLength !== buffer.lines.length);
// clear the old lines
buffer.lines.length = 0; buffer.lines.length = 0;
// We need to set the number of requested lines to 0 here, because parsing a line // 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 // increments it. This is needed to also count newly arriving lines while we're
@ -248,23 +249,19 @@ weechat.factory('connection',
// Parse the lines // Parse the lines
handlers.handleLineInfo(lineinfo, true); handlers.handleLineInfo(lineinfo, true);
if (setReadmarker) { // Correct the read marker for the lines that were counted twice
// Read marker was somewhere in the old lines - we don't need it any more, buffer.lastSeen -= oldLength;
// 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;
}
// We requested more lines than we got, no more lines. // We requested more lines than we got, no more lines.
if (linesReceivedCount < numLines) { if (linesReceivedCount < numLines) {
buffer.allLinesFetched = true; buffer.allLinesFetched = true;
} }
$rootScope.loadingLines = false; $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);
}); });
}; };

View file

@ -432,7 +432,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
return connection.fetchMoreLines(numLines); return connection.fetchMoreLines(numLines);
}; };
$rootScope.scrollWithBuffer = function(nonIncremental) { $rootScope.scrollWithBuffer = function(scrollToReadmarker, moreLines) {
// First, get scrolling status *before* modification // First, get scrolling status *before* modification
// This is required to determine where we were in the buffer pre-change // This is required to determine where we were in the buffer pre-change
var bl = document.getElementById('bufferlines'); var bl = document.getElementById('bufferlines');
@ -443,11 +443,15 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// Determine if we want to scroll at all // Determine if we want to scroll at all
// Give the check 3 pixels of slack so you don't have to hit // Give the check 3 pixels of slack so you don't have to hit
// the exact spot. This fixes a bug in some browsers // 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"); var readmarker = document.querySelector(".readmarker");
if (nonIncremental && readmarker) { if (scrollToReadmarker && readmarker) {
// Switching channels, scroll to read marker // Switching channels, scroll to read marker
bl.scrollTop = readmarker.offsetTop - readmarker.parentElement.scrollHeight + readmarker.scrollHeight; 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 { } else {
// New message, scroll with buffer (i.e. to bottom) // New message, scroll with buffer (i.e. to bottom)
bl.scrollTop = bl.scrollHeight - bl.clientHeight; bl.scrollTop = bl.scrollHeight - bl.clientHeight;