From 739c4de0ef44b503f7a6612b79303523412e16f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Fri, 7 Mar 2014 17:52:32 +0000 Subject: [PATCH 1/4] Add a isNicklistEmpty method to buffer model, speed up nicklist decision Flattening the nicklist is really unnecessary. This method is 10x faster for short nicklists, and much faster for buffers with lots of users. --- js/glowingbear.js | 4 ++-- js/models.js | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/js/glowingbear.js b/js/glowingbear.js index ecb121a..7b21ed5 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -975,8 +975,8 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', if ($scope.nonicklist) { return false; } - // Use flat nicklist to check if empty - if (ab.flatNicklist().length === 0) { + // Check if nicklist is empty + if (ab.isNicklistEmpty()) { return false; } return true; diff --git a/js/models.js b/js/models.js index 427aa79..db330bd 100644 --- a/js/models.js +++ b/js/models.js @@ -147,6 +147,13 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) } }; + var isNicklistEmpty = function() { + for (var obj in nicklist) { + return false; + } + return true; + }; + return { id: pointer, fullName: fullName, @@ -171,7 +178,8 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) history: history, addToHistory: addToHistory, getHistoryUp: getHistoryUp, - getHistoryDown: getHistoryDown + getHistoryDown: getHistoryDown, + isNicklistEmpty: isNicklistEmpty }; }; From ac548777fc93e28e27ef3659df8729a1cf3fd0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Fri, 7 Mar 2014 17:56:48 +0000 Subject: [PATCH 2/4] Defer nicklist loading until buffer is opened Drastically improves startup time for users with buffers that have thousands of users --- js/glowingbear.js | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/js/glowingbear.js b/js/glowingbear.js index 7b21ed5..97aabfc 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -275,13 +275,6 @@ function($rootScope, ); }; - var _requestNicklist = function() { - return ngWebsockets.send( - weeChat.Protocol.formatNicklist({ - }) - ); - }; - var _requestBufferInfos = function() { return ngWebsockets.send( weeChat.Protocol.formatHdata({ @@ -322,10 +315,6 @@ function($rootScope, handlers.handleHotlistInfo(hotlist); }); - _requestNicklist().then(function(nicklist) { - handlers.handleNicklist(nicklist); - }); - _requestSync(); $log.info("Connected to relay"); $rootScope.connected = true; @@ -412,6 +401,22 @@ function($rootScope, })); }; + + var requestNicklist = function(bufferId, callback) { + bufferId = bufferId || null; + ngWebsockets.send( + weeChat.Protocol.formatNicklist({ + buffer: bufferId + }) + ).then(function(nicklist) { + handlers.handleNicklist(nicklist); + if (callback !== undefined) { + callback(); + } + }); + }; + + var fetchMoreLines = function(numLines) { var buffer = models.getActiveBuffer(); // Calculate number of lines to fetch, at least as many as the parameter @@ -468,7 +473,8 @@ function($rootScope, disconnect: disconnect, sendMessage: sendMessage, sendCoreCommand: sendCoreCommand, - fetchMoreLines: fetchMoreLines + fetchMoreLines: fetchMoreLines, + requestNicklist: requestNicklist }; }]); @@ -641,15 +647,23 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', }; $rootScope.$on('activeBufferChanged', function() { - $rootScope.scrollWithBuffer(true); - var ab = models.getActiveBuffer(); + + if (ab.isNicklistEmpty()) { + var bufferId = '0x' + ab.id; // WeeChat needs the 0x prefix + connection.requestNicklist(bufferId, function() { + $scope.showNicklist = $scope.updateShowNicklist(); + }); + } + 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.updateTitle(ab); + $rootScope.scrollWithBuffer(true); + // If user wants to sync hotlist with weechat // we will send a /buffer bufferName command every time // the user switches a buffer. This will ensure that notifications From 730c7dab8d4fb452e7860aba56ca3e15feb563ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Sat, 8 Mar 2014 21:26:15 +0000 Subject: [PATCH 3/4] Load lines before nicklist Nicklist is not nearly as important as the actual lines, load them first for better perceived performance. Parsing the nicklist can take a noticeable amount of time for channels with thousands of occupants. This also improves/fixes the nicklist emptiness check --- js/glowingbear.js | 23 +++++++++++++---------- js/models.js | 17 +++++++++++++++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/js/glowingbear.js b/js/glowingbear.js index 97aabfc..b8975ff 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -649,19 +649,25 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', $rootScope.$on('activeBufferChanged', function() { var ab = models.getActiveBuffer(); - if (ab.isNicklistEmpty()) { - var bufferId = '0x' + ab.id; // WeeChat needs the 0x prefix - connection.requestNicklist(bufferId, function() { - $scope.showNicklist = $scope.updateShowNicklist(); - }); - } - 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.updateTitle(ab); + // Send a request for the nicklist if it hasn't been loaded yet + if (!ab.nicklistRequested()) { + var bufferId = '0x' + ab.id; // WeeChat needs the 0x prefix + connection.requestNicklist(bufferId, function() { + $scope.showNicklist = $scope.updateShowNicklist(); + // Scroll after nicklist has been loaded, as it may break long lines + $rootScope.scrollWithBuffer(true); + }); + } else { + // Check if we should show nicklist or not + $scope.showNicklist = $scope.updateShowNicklist(); + } + $rootScope.scrollWithBuffer(true); // If user wants to sync hotlist with weechat @@ -675,9 +681,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // Clear search term on buffer change $scope.search = ''; - // Check if we should show nicklist or not - $scope.showNicklist = $scope.updateShowNicklist(); - if (!$rootScope.isMobileDevice()) { $('#sendMessage').focus(); } diff --git a/js/models.js b/js/models.js index db330bd..67e8345 100644 --- a/js/models.js +++ b/js/models.js @@ -147,13 +147,25 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) } }; + + // Check if the nicklist is empty, i.e., no nicks present + // This checks for the presence of people, not whether a + // request for the nicklist has been made var isNicklistEmpty = function() { for (var obj in nicklist) { - return false; + if (obj !== 'root') { + return false; + } } return true; }; + var nicklistRequested = function() { + // If the nicklist has been requested but is empty, it + // still has a 'root' property. Check for its existence. + return nicklist.hasOwnProperty('root'); + }; + return { id: pointer, fullName: fullName, @@ -179,7 +191,8 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) addToHistory: addToHistory, getHistoryUp: getHistoryUp, getHistoryDown: getHistoryDown, - isNicklistEmpty: isNicklistEmpty + isNicklistEmpty: isNicklistEmpty, + nicklistRequested: nicklistRequested }; }; From dc0ce33bea8e155db6b260dd6dae59f658a6df8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenz=20H=C3=BCbschle-Schneider?= Date: Sat, 8 Mar 2014 21:30:14 +0000 Subject: [PATCH 4/4] Fetch nicklist by buffer name, not pointer An invalid pointer will crash WeeChat, while an invalid name will not. A pointer becomes invalid e.g. if the buffer is closed by another client, g-b not updated, and the buffer then selected in g-b. --- js/glowingbear.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/glowingbear.js b/js/glowingbear.js index b8975ff..4de2c77 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -657,8 +657,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // Send a request for the nicklist if it hasn't been loaded yet if (!ab.nicklistRequested()) { - var bufferId = '0x' + ab.id; // WeeChat needs the 0x prefix - connection.requestNicklist(bufferId, function() { + connection.requestNicklist(ab.fullName, function() { $scope.showNicklist = $scope.updateShowNicklist(); // Scroll after nicklist has been loaded, as it may break long lines $rootScope.scrollWithBuffer(true);