diff --git a/js/glowingbear.js b/js/glowingbear.js index 54b38db..5a42194 100644 --- a/js/glowingbear.js +++ b/js/glowingbear.js @@ -666,6 +666,18 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', $scope.bufferlines = ab.lines; $scope.nicklist = ab.nicklist; + // Send a request for the nicklist if it hasn't been loaded yet + if (!ab.nicklistRequested()) { + connection.requestNicklist(ab.fullName, 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(); + } + if (ab.requestedLines < $scope.lines) { // buffer has not been loaded, but some lines may already be present if they arrived after we connected // try to determine how many lines to fetch @@ -679,18 +691,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', } $rootScope.updateTitle(ab); - // Send a request for the nicklist if it hasn't been loaded yet - if (!ab.nicklistRequested()) { - connection.requestNicklist(ab.fullName, 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 @@ -868,7 +868,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // get last word var lastSpace = trimmedValue.lastIndexOf(' ') + 1; var lastWord = trimmedValue.slice(lastSpace, trimmedValue.length - 1); - var nicklist = models.getActiveBuffer().flatNicklist(); + var nicklist = models.getActiveBuffer().getNicklistByTime(); // check against nicklist to see if it's a list of highlights if (nicklist.indexOf(lastWord) !== -1) { // It's another highlight! @@ -1230,12 +1230,12 @@ weechat.directive('inputBar', function() { // get current caret position var caretPos = inputNode.selectionStart; - // create flat array of nicks + // get current active buffer var activeBuffer = models.getActiveBuffer(); // complete nick var nickComp = IrcUtils.completeNick(inputText, caretPos, - $scope.iterCandidate, activeBuffer.flatNicklist(), ':'); + $scope.iterCandidate, activeBuffer.getNicklistByTime(), ':'); // remember iteration candidate $scope.iterCandidate = nickComp.iterCandidate; diff --git a/js/irc-utils.js b/js/irc-utils.js index ff4c488..11e2465 100644 --- a/js/irc-utils.js +++ b/js/irc-utils.js @@ -4,20 +4,17 @@ var IrcUtils = { /** - * Get a new version of a nick list, sorted alphabetically by lowercase nick. + * Get a new version of a nick list, sorted by last speaker * * @param nickList Original nick list - * @return Nick list sorted alphabetically by lowercase nick + * @return Sorted nick list */ - _ciSearchNickList: function(nickList) { - var newList = []; + _ciNickList: function(nickList) { - nickList.forEach(function(nick) { - newList.push(nick); - }); - newList.sort(function(a, b) { - return a.toLowerCase() < b.toLowerCase() ? -1 : 1; + var newList = _(nickList).sortBy(function(nickObj) { + return -nickObj.spokeAt; }); + newList = _(newList).pluck('name'); return newList; }, @@ -66,10 +63,13 @@ var IrcUtils = { if (lcCurrentNick === lcNick) { at = matchingNicks.length - 1; } - } else if (matchingNicks.length > 0) { + } + /* Since we aren't sorted any more torhve disabled this: + else if (matchingNicks.length > 0) { // end of group, no need to check after this - break; + //break; } + */ } if (at === null || matchingNicks.length === 0) { @@ -105,7 +105,7 @@ var IrcUtils = { } // new nick list to search in - var searchNickList = IrcUtils._ciSearchNickList(nickList); + var searchNickList = IrcUtils._ciNickList(nickList); // text before and after caret var beforeCaret = text.substring(0, caretPos); diff --git a/js/models.js b/js/models.js index 818695e..08af87d 100644 --- a/js/models.js +++ b/js/models.js @@ -20,7 +20,6 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) var lines = []; var requestedLines = 0; var nicklist = {}; - var flatnicklist = []; var history = []; var historyPos = 0; var active = false; @@ -43,6 +42,7 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) */ var addLine = function(line) { lines.push(line); + updateNickSpeak(line); }; /* @@ -50,8 +50,8 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) */ var addNick = function(group, nick) { if (nicklistRequested()) { + nick.spokeAt = Date.now(); nicklist[group].nicks.push(nick); - flatnicklist = getFlatNicklist(); } }; /* @@ -63,7 +63,6 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) return; } group.nicks = _.filter(group.nicks, function(n) { return n.name !== nick.name;}); - flatnicklist = getFlatNicklist(); /* for (i in group.nicks) { if (group.nicks[i].name == nick.name) { @@ -84,28 +83,55 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) break; } } - flatnicklist = getFlatNicklist(); }; /* - * Maintain a cached version of a flat sorted nicklist + * Update a nick with a fresh timestamp so tab completion + * can use time to complete recent speakers + */ + var updateNickSpeak = function(line) { + // Try to find nick from prefix + var prefix = line.prefix; + var nick = prefix[prefix.length - 1].text; + // Action / me, find the nick as the first word of the message + if (nick === " *") { + var match = line.text.match(/^(.+)\s/); + if (match) { + nick = match[1]; + } + } + else if (nick === "" || nick === "=!=") { + return; + } + _.each(nicklist, function(nickGroup) { + _.each(nickGroup.nicks, function(nickObj) { + if (nickObj.name === nick) { + // Use the order the line arrive in for simplicity + // instead of using weechat's own timestamp + nickObj.spokeAt = Date.now(); + } + }); + }); + }; + + /* + * Get a flat nicklist sorted by speaker time. This function is + * called for every tab key press by the user. * */ - var getFlatNicklist = function() { + var getNicklistByTime = function() { var newlist = []; _.each(nicklist, function(nickGroup) { _.each(nickGroup.nicks, function(nickObj) { - newlist.push(nickObj.name); + newlist.push(nickObj); }); }); - newlist.sort(function(a, b) { - return a.toLowerCase() < b.toLowerCase() ? -1 : 1; - }); - return newlist; - }; - var flatNicklist = function() { - return flatnicklist; + newlist.sort(function(a, b) { + return a.spokeAt < b.spokeAt; + }); + + return newlist; }; var addToHistory = function(line) { @@ -189,7 +215,7 @@ models.service('models', ['$rootScope', '$filter', function($rootScope, $filter) addNick: addNick, delNick: delNick, updateNick: updateNick, - flatNicklist: flatNicklist, + getNicklistByTime: getNicklistByTime, serverSortKey: serverSortKey, indent: indent, history: history,