diff --git a/app/js/controllers.js b/app/js/controllers.js index c3bba611..5838bb36 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -1746,7 +1746,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.$on('user_update', angular.noop); }) - .controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, MtpApiFileManager) { + .controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, MtpApiFileManager) { $scope.$watch('curDialog.peer', resetDraft); $scope.$on('user_update', angular.noop); @@ -1757,6 +1757,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.draftMessage = {text: '', send: sendMessage, replyClear: replyClear}; $scope.mentions = {}; + $scope.commands = {}; $scope.$watch('draftMessage.text', onMessageChange); $scope.$watch('draftMessage.files', onFilesSelected); $scope.$watch('draftMessage.sticker', onStickerSelected); @@ -1831,8 +1832,52 @@ angular.module('myApp.controllers', ['myApp.i18n']) }); } + function updateCommands () { + var peerID = $scope.curDialog.peerID; + + AppProfileManager.getPeerBots(peerID).then(function (peerBots) { + if (!peerBots.length) { + safeReplaceObject($scope.commands, {}); + $scope.$broadcast('mentions_update'); + return; + } + + var needMentions = peerBots.length > 1; + var commandsList = []; + var commandsIndex = SearchIndexManager.createIndex(); + + angular.forEach(peerBots, function (peerBot) { + var mention = ''; + if (needMentions) { + var bot = AppUsersManager.getUser(peerBot.id); + if (bot && bot.username) { + mention += '@' + bot.username; + } + } + var botSearchText = AppUsersManager.getUserSearchText(peerBot.id); + angular.forEach(peerBot.commands, function (description, command) { + var value = '/' + command + mention; + commandsList.push({ + botID: peerBot.id, + value: value, + description: description + }); + SearchIndexManager.indexObject(value, botSearchText + ' ' + command + ' ' + description, commandsIndex); + }) + }); + + console.log(commandsList, commandsIndex); + safeReplaceObject($scope.commands, { + list: commandsList, + index: commandsIndex + }); + $scope.$broadcast('mentions_update'); + }); + } + function resetDraft (newPeer) { updateMentions(); + updateCommands(); replyClear(); if (newPeer) { diff --git a/app/js/directives.js b/app/js/directives.js index d16e3caa..6677f9ab 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -1295,7 +1295,8 @@ angular.module('myApp.directives', ['myApp.filters']) link: link, scope: { draftMessage: '=', - mentions: '=' + mentions: '=', + commands: '=' } }; @@ -1363,8 +1364,8 @@ angular.module('myApp.directives', ['myApp.filters']) getSendOnEnter: function () { return sendOnEnter; }, - getPeerImage: function (element, peerID) { - if (cachedPeerPhotos[peerID]) { + getPeerImage: function (element, peerID, noReplace) { + if (cachedPeerPhotos[peerID] && !noReplace) { element.replaceWith(cachedPeerPhotos[peerID]); return; } @@ -1376,6 +1377,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }, mentions: $scope.mentions, + commands: $scope.commands, onMessageSubmit: onMessageSubmit, onFilePaste: onFilePaste }); diff --git a/app/js/message_composer.js b/app/js/message_composer.js index e1e9d2a1..d9242a00 100644 --- a/app/js/message_composer.js +++ b/app/js/message_composer.js @@ -487,7 +487,13 @@ function MessageComposer (textarea, options) { this.setUpInput(); - this.autoCompleteEl = $('
').appendTo(document.body); + this.autoCompleteWrapEl = $('').appendTo(document.body); + this.autoCompleteScrollerEl = $('').appendTo(this.autoCompleteWrapEl); + this.autoCompleteEl = $(' ').appendTo(this.autoCompleteScrollerEl); + + if (!Config.Mobile) { + this.autoCompleteScrollerEl.nanoScroller({preventPageScrolling: true, tabIndex: -1}); + } var self = this; this.autoCompleteEl.on('mousedown', function (e) { @@ -517,6 +523,7 @@ function MessageComposer (textarea, options) { this.getSendOnEnter = options.getSendOnEnter; this.onFilePaste = options.onFilePaste; this.mentions = options.mentions; + this.commands = options.commands; this.getPeerImage = options.getPeerImage; } @@ -526,7 +533,7 @@ MessageComposer.prototype.setUpInput = function () { } else { this.setUpPlaintext(); } - this.autoCompleteRegEx = /(?:\s|^)(:|@)([A-Za-z0-9\-\+\*_]*)$/; + this.autoCompleteRegEx = /(?:\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/; } MessageComposer.prototype.setUpRich = function () { @@ -602,12 +609,18 @@ MessageComposer.prototype.onKeyEvent = function (e) { currentSelected.removeClass('composer_autocomplete_option_active'); if (nextWrap) { $(nextWrap).find('a').addClass('composer_autocomplete_option_active'); + if (!Config.Mobile) { + this.autoCompleteScrollerEl.nanoScroller({scrollTop: nextWrap.offsetTop}) + } return cancelEvent(e); } } var childNodes = this.autoCompleteEl[0].childNodes; var nextWrap = childNodes[next ? 0 : childNodes.length - 1]; + if (!Config.Mobile) { + this.autoCompleteScrollerEl.nanoScroller({scrollTop: nextWrap.offsetTop}) + } $(nextWrap).find('a').addClass('composer_autocomplete_option_active'); return cancelEvent(e); @@ -742,6 +755,30 @@ MessageComposer.prototype.checkAutocomplete = function () { this.hideSuggestions(); } } + else if (matches[1] == '/') { // commands + if (this.commands && this.commands.index) { + if (query.length) { + var foundObject = SearchIndexManager.search(query, this.commands.index); + var foundCommands = []; + var command; + for (var i = 0, length = this.commands.list.length; i < length; i++) { + command = this.commands.list[i]; + if (foundObject[command.value]) { + foundCommands.push(command); + } + } + } else { + var foundCommands = this.commands.list; + } + if (foundCommands.length) { + this.showCommandsSuggestions(foundCommands); + } else { + this.hideSuggestions(); + } + } else { + this.hideSuggestions(); + } + } else { // emoji EmojiHelper.getPopularEmoji((function (popular) { if (query.length) { @@ -1028,6 +1065,21 @@ MessageComposer.prototype.focus = function () { } } +MessageComposer.prototype.renderSuggestions = function (html) { + this.autoCompleteEl.html(html.join('')); + this.autoCompleteWrapEl.show(); + + var self = this; + if (!Config.Mobile) { + self.autoCompleteScrollerEl.nanoScroller({scroll: 'top'}); + setTimeout(function () { + self.autoCompleteScrollerEl.nanoScroller(); + }, 100); + } + + this.updatePosition(); + this.autocompleteShown = true; +} MessageComposer.prototype.showEmojiSuggestions = function (codes) { var html = []; @@ -1052,10 +1104,7 @@ MessageComposer.prototype.showEmojiSuggestions = function (codes) { } } - this.autoCompleteEl.html(html.join('')); - this.autoCompleteEl.show(); - this.updatePosition(); - this.autocompleteShown = true; + this.renderSuggestions(html); } MessageComposer.prototype.showMentionSuggestions = function (users) { @@ -1069,27 +1118,49 @@ MessageComposer.prototype.showMentionSuggestions = function (users) { html.push('