Merge pull request #484 from ailin-nemui/scrolling-poll2

[Please test] some scrolling updates via polling
This commit is contained in:
Tor Hveem 2014-10-28 01:31:35 +01:00
commit 84c425cb41
3 changed files with 67 additions and 24 deletions

View file

@ -279,7 +279,7 @@ $ openssl req -nodes -newkey rsa:4096 -keyout relay.pem -x509 -days 365 -out rel
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table><span id="end-of-buffer"></span>
</div> </div>
<div class="footer" ng-class="{'withnicklist': showNicklist}"> <div class="footer" ng-class="{'withnicklist': showNicklist}">
<div input-bar input-id="sendMessage" command="command"></div> <div input-bar input-id="sendMessage" command="command"></div>

View file

@ -149,16 +149,33 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// Most relevant when first connecting to properly initalise // Most relevant when first connecting to properly initalise
function() { function() {
$timeout(function() { $timeout(function() {
var bufferlines = document.getElementById("bufferlines"); var bl = document.getElementById("bufferlines");
$rootScope.originalBufferlinesPosition = bufferlines.scrollTop + bufferlines.scrollHeight; var lastScrollHeight = bl.scrollHeight;
var scrollHeightObserver = function() {
if (bl) {
var newScrollHeight = bl.scrollHeight;
if (newScrollHeight !== lastScrollHeight) {
$rootScope.updateBufferBottom($rootScope.bufferBottom);
lastScrollHeight = newScrollHeight;
}
setTimeout(scrollHeightObserver, 500);
}
};
$rootScope.updateBufferBottom(true);
$rootScope.scrollWithBuffer(true);
bl.onscroll = _.debounce(function() {
$rootScope.updateBufferBottom();
}, 80);
setTimeout(scrollHeightObserver, 500);
}); });
} }
); );
} }
notifications.updateTitle(ab); notifications.updateTitle(ab);
$rootScope.scrollWithBuffer(true); $timeout(function() {
$rootScope.scrollWithBuffer(true);
});
// If user wants to sync hotlist with weechat // If user wants to sync hotlist with weechat
// we will send a /buffer bufferName command every time // we will send a /buffer bufferName command every time
// the user switches a buffer. This will ensure that notifications // the user switches a buffer. This will ensure that notifications
@ -405,6 +422,9 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
}; };
$scope.calculateNumLines(); $scope.calculateNumLines();
// get animationframe method
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
// Recalculate number of lines on resize // Recalculate number of lines on resize
window.addEventListener("resize", _.debounce(function() { window.addEventListener("resize", _.debounce(function() {
// Recalculation fails when not connected // Recalculation fails when not connected
@ -419,17 +439,16 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// if we're scrolled to the bottom, scroll down to the same position after the resize // if we're scrolled to the bottom, scroll down to the same position after the resize
// most common use case: opening the keyboard on a mobile device // most common use case: opening the keyboard on a mobile device
var bufferlines = document.getElementById("bufferlines"); if ($rootScope.bufferBottom) {
if ($rootScope.originalBufferlinesPosition === bufferlines.scrollHeight + bufferlines.scrollTop) { var rescroll = function(){
$timeout(function() { $rootScope.updateBufferBottom(true);
bufferlines.scrollTop = bufferlines.scrollHeight; };
}, 100); $timeout(rescroll, 500);
window.requestAnimationFrame(rescroll);
} }
$rootScope.originalBufferlinesPosition = bufferlines.scrollTop + bufferlines.scrollHeight;
} }
}, 100)); }, 100));
$rootScope.loadingLines = false; $rootScope.loadingLines = false;
$scope.fetchMoreLines = function(numLines) { $scope.fetchMoreLines = function(numLines) {
if (!numLines) { if (!numLines) {
@ -438,6 +457,14 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
return connection.fetchMoreLines(numLines); return connection.fetchMoreLines(numLines);
}; };
$rootScope.updateBufferBottom = function(bottom) {
var eob = document.getElementById("end-of-buffer");
var bl = document.getElementById('bufferlines');
if (bottom) {
eob.scrollIntoView();
}
$rootScope.bufferBottom = eob.offsetTop <= bl.scrollTop + bl.clientHeight;
};
$rootScope.scrollWithBuffer = function(scrollToReadmarker, moreLines) { $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
@ -460,15 +487,15 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
bl.scrollTop = bl.scrollHeight - bl.clientHeight - sVal; 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; var eob = document.getElementById("end-of-buffer");
eob.scrollIntoView();
} }
$rootScope.updateBufferBottom();
} }
}; };
// Here be scrolling dragons // Here be scrolling dragons
$timeout(scroll); $timeout(scroll);
$timeout(scroll, 100); window.requestAnimationFrame(scroll);
$timeout(scroll, 300);
$timeout(scroll, 500);
}; };
@ -477,6 +504,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$rootScope.sslError = false; $rootScope.sslError = false;
$rootScope.securityError = false; $rootScope.securityError = false;
$rootScope.errorMessage = false; $rootScope.errorMessage = false;
$rootScope.bufferBottom = true;
$scope.connectbutton = 'Connecting ...'; $scope.connectbutton = 'Connecting ...';
connection.connect($scope.host, $scope.port, $scope.password, $scope.ssl); connection.connect($scope.host, $scope.port, $scope.password, $scope.ssl);
}; };
@ -563,6 +591,12 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// Watch model and update show setting when it changes // Watch model and update show setting when it changes
$scope.$watch('nonicklist', function() { $scope.$watch('nonicklist', function() {
$scope.showNicklist = $scope.updateShowNicklist(); $scope.showNicklist = $scope.updateShowNicklist();
// restore bottom view
if ($rootScope.connected && $rootScope.bufferBottom) {
$timeout(function(){
$rootScope.updateBufferBottom(true);
}, 500);
}
}); });
$scope.showNicklist = false; $scope.showNicklist = false;
// Utility function that template can use to check if nicklist should // Utility function that template can use to check if nicklist should

View file

@ -33,7 +33,7 @@ weechat.directive('plugin', ['$rootScope', function($rootScope) {
$scope.plugin.visible = false; $scope.plugin.visible = false;
}; };
$scope.showContent = function() { $scope.showContent = function(automated) {
/* /*
* Shows the plugin content. * Shows the plugin content.
* displayedContent is bound to the DOM. * displayedContent is bound to the DOM.
@ -56,16 +56,25 @@ weechat.directive('plugin', ['$rootScope', function($rootScope) {
$scope.plugin.visible = true; $scope.plugin.visible = true;
// Scroll embed content into view // Scroll embed content into view
var scroll = function() { var scroll;
if (embed && embed.scrollIntoViewIfNeeded !== undefined) { if (automated) {
embed.scrollIntoViewIfNeeded(); var wasBottom = $rootScope.bufferBottom;
} scroll = function() {
}; $rootScope.updateBufferBottom(wasBottom);
setTimeout(scroll, 100); };
} else {
scroll = function() {
if (embed && embed.scrollIntoViewIfNeeded !== undefined) {
embed.scrollIntoViewIfNeeded();
$rootScope.updateBufferBottom();
}
};
}
setTimeout(scroll, 500);
}; };
if ($scope.plugin.visible) { if ($scope.plugin.visible) {
$scope.showContent(); $scope.showContent(true);
} }
}] }]
}; };