Merge pull request #133 from lorenzhs/fetchmorelines

Dynamically fetch lines
This commit is contained in:
David Cormier 2014-02-10 20:10:51 -05:00
commit 65a6ad1049
3 changed files with 75 additions and 23 deletions

View File

@ -78,11 +78,6 @@
</label> </label>
</div> </div>
</div> </div>
<div class="form-group">
<label class="control-label" for="port">Lines</label>
<input type="text" class="form-control monospace" id="lines" ng-model="lines" placeholder="40">
<p class="help-block">Enter number of lines to sync from WeeChat on connect</p>
</div>
<button class="btn btn-lg btn-primary" ng-click="connect()">Connect <i class="glyphicon glyphicon-chevron-right"></i></button> <button class="btn btn-lg btn-primary" ng-click="connect()">Connect <i class="glyphicon glyphicon-chevron-right"></i></button>
</form> </form>
</div> </div>
@ -282,6 +277,16 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
</ul> </ul>
</div> </div>
<table ng-class="{'notimestamp':notimestamp}"> <table ng-class="{'notimestamp':notimestamp}">
<tbody>
<tr class="bufferline">
<td class="time"><span class="date"> </span></td>
<td class="prefix"> </td>
<td class="message">
<a class="fetchmorelines" ng-click="fetchMoreLines()" ng-hide="loadingLines">Fetch more lines</a>
<span ng-show="loadingLines">Fetching more lines...</span>
</td>
</tr>
</tbody>
<tbody ng-repeat="bufferline in (bufferlines = activeBuffer().lines)"> <tbody ng-repeat="bufferline in (bufferlines = activeBuffer().lines)">
<tr class="bufferline"> <tr class="bufferline">
<td class="time"> <td class="time">

View File

@ -22,11 +22,12 @@ weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootSc
models.closeBuffer(buffer); models.closeBuffer(buffer);
}; };
var handleLine = function(line, initial) { var handleLine = function(line, initial, loadingMoreLines) {
var message = new models.BufferLine(line); var message = new models.BufferLine(line);
var buffer = models.getBuffer(message.buffer);
buffer.requestedLines++;
// Only react to line if its displayed // Only react to line if its displayed
if (message.displayed) { if (message.displayed) {
var buffer = models.getBuffer(message.buffer);
message = plugins.PluginManager.contentForMessage(message, $rootScope.visible); message = plugins.PluginManager.contentForMessage(message, $rootScope.visible);
buffer.addLine(message); buffer.addLine(message);
@ -34,7 +35,7 @@ weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootSc
buffer.lastSeen++; buffer.lastSeen++;
} }
if (buffer.active) { if (buffer.active && !initial && !loadingMoreLines) {
$rootScope.scrollWithBuffer(); $rootScope.scrollWithBuffer();
} }
@ -88,10 +89,11 @@ weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootSc
* *
* (lineinfo) messages are specified by this client. It is request after bufinfo completes * (lineinfo) messages are specified by this client. It is request after bufinfo completes
*/ */
var handleLineInfo = function(message) { var handleLineInfo = function(message, initial, loadingMoreLines) {
var lines = message.objects[0].content.reverse(); var lines = message.objects[0].content.reverse();
if (initial === undefined) initial = true;
lines.forEach(function(l) { lines.forEach(function(l) {
handleLine(l, true); handleLine(l, initial, loadingMoreLines);
}); });
}; };
@ -284,15 +286,6 @@ function($rootScope,
}); });
// Send all the other commands required for initialization // Send all the other commands required for initialization
ngWebsockets.send(
weeChat.Protocol.formatHdata({
path: "buffer:gui_buffers(*)/own_lines/last_line(-"+storage.get('lines')+")/data",
keys: []
})
).then(function(lineinfo) {
handlers.handleLineInfo(lineinfo);
});
ngWebsockets.send( ngWebsockets.send(
weeChat.Protocol.formatHdata({ weeChat.Protocol.formatHdata({
path: "hotlist:gui_hotlist(*)", path: "hotlist:gui_hotlist(*)",
@ -381,13 +374,48 @@ function($rootScope,
})); }));
}; };
var fetchMoreLines = function(numLines) {
var buffer = models.getActiveBuffer();
// Calculate number of lines to fetch, at least as many as the parameter
numLines = Math.max(numLines, buffer.requestedLines * 2);
// Indicator that we are loading lines, hides "load more lines" link
$rootScope.loadingLines = true;
// Send hdata request to fetch lines for this particular buffer
ngWebsockets.send(
weeChat.Protocol.formatHdata({
// "0x" is important, otherwise it won't work
path: "buffer:0x" + buffer.id + "/own_lines/last_line(-" + numLines + ")/data",
keys: []
})
).then(function(lineinfo) {
// delete old lines and add new ones
var oldLength = buffer.lines.length;
buffer.lines.length = 0;
buffer.requestedLines = 0;
handlers.handleLineInfo(lineinfo, false, true);
if (oldLength > 0) {
// We're not initially loading lines into the buffer.
// Set the read marker to the beginning of the newly loaded lines
buffer.lastSeen = buffer.lines.length - oldLength - 1;
} else {
// Initial buffer open, set correct read marker position
buffer.lastSeen += buffer.lines.length;
}
$rootScope.loadingLines = false;
// Scroll read marker to the center of the screen
$rootScope.scrollWithBuffer(true);
});
};
return { return {
// send: send,
connect: connect, connect: connect,
disconnect: disconnect, disconnect: disconnect,
sendMessage: sendMessage, sendMessage: sendMessage,
sendCoreCommand: sendCoreCommand sendCoreCommand: sendCoreCommand,
fetchMoreLines: fetchMoreLines
}; };
}]); }]);
@ -448,6 +476,10 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$rootScope.scrollWithBuffer(true); $rootScope.scrollWithBuffer(true);
var ab = models.getActiveBuffer(); var ab = models.getActiveBuffer();
if (ab.requestedLines < $scope.lines) {
// buffer has not been loaded, but some lines may already be present if they arrived after we connected
$scope.fetchMoreLines($scope.lines);
}
$rootScope.pageTitle = ab.shortName + ' | ' + ab.title; $rootScope.pageTitle = ab.shortName + ' | ' + ab.title;
// If user wants to sync hotlist with weechat // If user wants to sync hotlist with weechat
@ -503,7 +535,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$store.bind($scope, "port", "9001"); $store.bind($scope, "port", "9001");
$store.bind($scope, "proto", "weechat"); $store.bind($scope, "proto", "weechat");
$store.bind($scope, "ssl", false); $store.bind($scope, "ssl", false);
$store.bind($scope, "lines", "40");
$store.bind($scope, "savepassword", false); $store.bind($scope, "savepassword", false);
if ($scope.savepassword) { if ($scope.savepassword) {
$store.bind($scope, "password", ""); $store.bind($scope, "password", "");
@ -562,6 +593,20 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
} }
}; };
// Calculate number of lines to fetch
$scope.lines = function() {
var lineHeight = document.querySelector(".bufferline").clientHeight;
// I would have used document.querySelector("#bufferlines").clientHeight and added 5 to the total result, but that provides incorrect values on mobile
var areaHeight = document.body.clientHeight;
return Math.ceil(areaHeight/lineHeight);
}();
$rootScope.loadingLines = false;
$scope.fetchMoreLines = function() {
connection.fetchMoreLines($scope.lines);
};
$rootScope.scrollWithBuffer = function(nonIncremental) { $rootScope.scrollWithBuffer = function(nonIncremental) {
// 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
@ -577,7 +622,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
var readmarker = document.getElementById('readmarker'); var readmarker = document.getElementById('readmarker');
if (nonIncremental && readmarker) { if (nonIncremental && readmarker) {
// Switching channels, scroll to read marker // Switching channels, scroll to read marker
readmarker.scrollIntoView(); readmarker.scrollIntoViewIfNeeded();
} 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;

View File

@ -18,6 +18,7 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter)
var local_variables = message.local_vars; var local_variables = message.local_vars;
var notify = 3; // Default 3 == message var notify = 3; // Default 3 == message
var lines = []; var lines = [];
var requestedLines = 0;
var nicklist = {}; var nicklist = {};
var flatnicklist = []; var flatnicklist = [];
var history = []; var history = [];
@ -153,6 +154,7 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter)
number: number, number: number,
title: title, title: title,
lines: lines, lines: lines,
requestedLines: requestedLines,
addLine: addLine, addLine: addLine,
lastSeen: lastSeen, lastSeen: lastSeen,
unread: unread, unread: unread,