From 1cee4855f5b2bb3c2eec38fa12e0c07fe428a1d6 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Mon, 18 Apr 2016 01:55:10 +0300 Subject: [PATCH] Improved inline bots --- app/js/controllers.js | 16 ++++ app/js/directives.js | 24 ++++-- app/js/lib/ng_utils.js | 1 - app/js/lib/utils.js | 6 +- app/js/message_composer.js | 12 ++- app/js/messages_manager.js | 36 ++++----- app/js/services.js | 104 ++++++++++++++++++------- app/partials/desktop/reply_markup.html | 4 +- 8 files changed, 137 insertions(+), 66 deletions(-) diff --git a/app/js/controllers.js b/app/js/controllers.js index 0bc57246..12d27efa 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -2348,6 +2348,22 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.$broadcast('ui_peer_draft'); }); } + else if (attachment._ == 'inline_query') { + var mention = attachment.mention; + var query = attachment.query; + forceDraft = $scope.curDialog.peer; + + $timeout(function () { + $scope.draftMessage.text = mention + ' ' + query; + $scope.$broadcast('ui_peer_draft', { + customSelection: [ + mention + " " + query, + '', + '' + ] + }); + }, 1000); + } } function replySelect(messageID) { diff --git a/app/js/directives.js b/app/js/directives.js index 662cd089..50300c9a 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -176,7 +176,7 @@ angular.module('myApp.directives', ['myApp.filters']) } }) - .directive('myMessageBody', function($compile, AppPeersManager, AppChatsManager, AppUsersManager, AppMessagesManager, RichTextProcessor) { + .directive('myMessageBody', function($compile, AppPeersManager, AppChatsManager, AppUsersManager, AppMessagesManager, AppInlineBotsManager, RichTextProcessor) { var messageMediaCompiled = $compile('
'); var messageKeyboardCompiled = $compile('
'); @@ -246,12 +246,20 @@ angular.module('myApp.directives', ['myApp.filters']) }); scope.$on('reply_inline_button_press', function (e, button) { - AppMessagesManager.replyMarkupButtonPress(message.mid, button); + switch (button._) { + case 'keyboardButtonSwitchInline': + AppInlineBotsManager.switchInlineButtonClick(message.mid, button); + break; + case 'keyboardButtonCallback': + AppInlineBotsManager.callbackButtonClick(message.mid, button); + break; + } }); } function link ($scope, element, attrs) { var message = $scope.message; + message.dir = true; var msgID = message.mid; updateMessageText($scope, element, message); @@ -268,14 +276,18 @@ angular.module('myApp.directives', ['myApp.filters']) } $scope.$on('message_edit', function (e, data) { - if (data.mid != msgID) { + // var message = $scope.message; + // message = $scope.$parent.$eval(attrs.myMessageBody); + message = AppMessagesManager.wrapForHistory(message.mid); + if (data.mid != message.mid) { return; } - console.log('after edit', message); + console.log('after edit', message.dir, message); updateMessageText($scope, element, message); updateMessageMedia($scope, element, message); updateMessageKeyboard($scope, element, message); $scope.$emit('ui_height'); + message.dir = true; }); } }) @@ -323,7 +335,7 @@ angular.module('myApp.directives', ['myApp.filters']) classPrefix: 'reply_markup', maxHeight: 170 }); - $scope.buttonSend = function (button) { + $scope.buttonClick = function (button) { $scope.$emit('reply_button_press', button); } @@ -458,7 +470,7 @@ angular.module('myApp.directives', ['myApp.filters']) }; function link ($scope, element, attrs) { - $scope.buttonSend = function (button) { + $scope.buttonClick = function (button) { $scope.$emit('reply_inline_button_press', button); } } diff --git a/app/js/lib/ng_utils.js b/app/js/lib/ng_utils.js index 60e15277..228683be 100644 --- a/app/js/lib/ng_utils.js +++ b/app/js/lib/ng_utils.js @@ -1742,7 +1742,6 @@ angular.module('izhukov.utils', []) } function wrapUrl(url, unsafe) { - var url = entity.url || entityText; if (!url.match(/^https?:\/\//i)) { url = 'http://' + url; } diff --git a/app/js/lib/utils.js b/app/js/lib/utils.js index b59eb0d8..6719426b 100644 --- a/app/js/lib/utils.js +++ b/app/js/lib/utils.js @@ -164,7 +164,10 @@ function getRichValue(field) { lines.push(line.join('')); } - return lines.join('\n'); + var value = lines.join('\n'); + value = value.replace(/\u00A0/g, ' '); + + return value; } function getRichValueWithCaret(field) { @@ -197,6 +200,7 @@ function getRichValueWithCaret(field) { if (caretPos != -1) { value = value.substr(0, caretPos) + value.substr(caretPos + 1); } + value = value.replace(/\u00A0/g, ' '); return [value, caretPos]; } diff --git a/app/js/message_composer.js b/app/js/message_composer.js index 530b361b..b88f4679 100644 --- a/app/js/message_composer.js +++ b/app/js/message_composer.js @@ -978,7 +978,6 @@ MessageComposer.prototype.checkAutocomplete = function (forceFull) { if (value && this.curInlineResults && this.curInlineResults.text == value) { - console.trace(dT(), value, this.curInlineResults); this.showInlineSuggestions(this.curInlineResults); return; }; @@ -1335,7 +1334,6 @@ MessageComposer.prototype.onChange = function (e) { if (this.richTextareaEl) { delete this.keyupStarted; var richValue = getRichValue(this.richTextareaEl[0]); - richValue = richValue.replace(/\u00A0/g, ' '); this.textareaEl.val(richValue).trigger('change'); } this.updateInlinePlaceholder(); @@ -1390,13 +1388,18 @@ MessageComposer.prototype.setFocusedValue = function (parts) { MessageComposer.prototype.getRichHtml = function (text) { - return $('
').text(text).html().replace(/\n/g, '
').replace(/:([A-Za-z0-9\-\+\*_]+?):/gi, (function (all, shortcut) { + var html = $('
').text(text).html(); + html = html.replace(/\n/g, '
'); + html = html.replace(/:([A-Za-z0-9\-\+\*_]+?):/gi, (function (all, shortcut) { var code = EmojiHelper.shortcuts[shortcut]; if (code !== undefined) { return this.getEmojiHtml(code); } return all; }).bind(this)); + html = html.replace(/ /g, " \u00A0").replace(/^ | $/g, "\u00A0"); + + return html; } @@ -1471,7 +1474,8 @@ MessageComposer.prototype.showInlineSuggestions = function (botResults) { } var self = this; if (self.autoCompleteScope.type == 'inline' && - self.autoCompleteScope.botResults == botResults) { + self.autoCompleteScope.botResults == botResults && + self.autocompleteShown) { return; } setZeroTimeout(function () { diff --git a/app/js/messages_manager.js b/app/js/messages_manager.js index a227b970..67454aaf 100644 --- a/app/js/messages_manager.js +++ b/app/js/messages_manager.js @@ -2176,18 +2176,6 @@ angular.module('myApp.services') return messagesForHistory[msgID] = message; } - function replyMarkupButtonPress(id, button) { - var message = getMessage(id); - var peerID = getMessagePeer(message); - MtpApiManager.invokeApi('messages.getBotCallbackAnswer', { - peer: AppPeersManager.getInputPeerByID(peerID), - msg_id: getMessageLocalID(id), - data: button.data - }).then(function (callbackAnswer) { - console.info(callbackAnswer.message || 'empty answer'); - }); - } - function wrapReplyMarkup (replyMarkup) { if (!replyMarkup || replyMarkup._ == 'replyKeyboardHide') { @@ -2208,6 +2196,9 @@ angular.module('myApp.services') angular.forEach(replyMarkup.rows, function (markupRow) { angular.forEach(markupRow.buttons, function (markupButton) { markupButton.rText = RichTextProcessor.wrapRichText(markupButton.text, {noLinks: true, noLinebreaks: true}); + if (markupButton._ == 'keyboardButtonUrl') { + markupButton.pUrl = RichTextProcessor.wrapUrl(markupButton.url, true); + } }) }); return replyMarkup; @@ -2800,21 +2791,20 @@ angular.module('myApp.services') break; } - console.trace(dT(), 'edit message', mid, message); - + // console.trace(dT(), 'edit message', message); saveMessages([message], true); safeReplaceObject(messagesStorage[mid], message); - messagesStorage[mid] = message; - if (messagesForHistory[mid] !== undefined) { - var wasForHistory = messagesForHistory[mid]; + var wasForHistory = messagesForHistory[mid]; + if (wasForHistory !== undefined) { delete messagesForHistory[mid]; - var newForHistory = wrapForHistory(mid); - // console.log('replacing', wasForHistory, 'with', newForHistory); - safeReplaceObject(wasForHistory, newForHistory); - messagesForHistory[mid] = newForHistory; + safeReplaceObject(wasForHistory, wrapForHistory(mid)); } - $rootScope.$broadcast('message_edit', {peerID: peerID, id: message.id, mid: mid}); + $rootScope.$broadcast('message_edit', { + peerID: peerID, + id: message.id, + mid: mid + }); break; case 'updateReadHistoryInbox': @@ -3085,6 +3075,7 @@ angular.module('myApp.services') getHistory: getHistory, getSearch: getSearch, getMessage: getMessage, + getMessageLocalID: getMessageLocalID, getReplyKeyboard: getReplyKeyboard, readHistory: readHistory, readMessages: readMessages, @@ -3096,7 +3087,6 @@ angular.module('myApp.services') sendOther: sendOther, forwardMessages: forwardMessages, startBot: startBot, - replyMarkupButtonPress: replyMarkupButtonPress, openChatInviteLink: openChatInviteLink, convertMigratedPeer: convertMigratedPeer, getMessagePeer: getMessagePeer, diff --git a/app/js/services.js b/app/js/services.js index b5503b81..7ef90c7e 100755 --- a/app/js/services.js +++ b/app/js/services.js @@ -2402,7 +2402,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } }) -.service('AppInlineBotsManager', function ($rootScope, Storage, MtpApiManager, AppMessagesManager, AppDocsManager, AppPhotosManager, RichTextProcessor, AppUsersManager, AppPeersManager) { +.service('AppInlineBotsManager', function ($rootScope, Storage, MtpApiManager, AppMessagesManager, AppDocsManager, AppPhotosManager, RichTextProcessor, AppUsersManager, AppPeersManager, PeersSelectService) { var inlineResults = {}; @@ -2411,6 +2411,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) regroupWrappedResults: regroupWrappedResults, switchToPM: switchToPM, checkSwitchReturn: checkSwitchReturn, + switchInlineButtonClick: switchInlineButtonClick, + callbackButtonClick: callbackButtonClick, getInlineResults: getInlineResults, getPopularBots: getPopularBots }; @@ -2501,37 +2503,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) inlineResults[qID] = result; }); - console.log('res', botResults); return botResults; }); } - function switchToPM(fromPeerID, botID, startParam) { - var setHash = {}; - var peerString = AppPeersManager.getPeerString(fromPeerID); - setHash['inline_switch_pm' + botID] = {peer: peerString, time: tsNow()}; - Storage.set(setHash); - $rootScope.$broadcast('history_focus', {peerString: AppPeersManager.getPeerString(botID)}); - AppMessagesManager.startBot(botID, 0, startParam); - } - - function checkSwitchReturn(botID) { - var bot = AppUsersManager.getUser(botID); - if (!bot || !bot.pFlags.bot || !bot.bot_inline_placeholder) { - return qSync.when(false); - } - var key = 'inline_switch_pm' + botID; - return Storage.get(key).then(function (peerData) { - if (peerData) { - Storage.remove(key); - if (tsNow() - peerData.time < 3600000) { - return peerData.peerString; - } - } - return false; - }); - } - function regroupWrappedResults (results, rowW, rowH) { if (!results || !results[0] || @@ -2606,6 +2581,73 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) }); } + function switchToPM(fromPeerID, botID, startParam) { + var peerString = AppPeersManager.getPeerString(fromPeerID); + var setHash = {}; + setHash['inline_switch_pm' + botID] = {peer: peerString, time: tsNow()}; + Storage.set(setHash); + $rootScope.$broadcast('history_focus', {peerString: AppPeersManager.getPeerString(botID)}); + AppMessagesManager.startBot(botID, 0, startParam); + } + + function checkSwitchReturn(botID) { + var bot = AppUsersManager.getUser(botID); + if (!bot || !bot.pFlags.bot || !bot.bot_inline_placeholder) { + return qSync.when(false); + } + var key = 'inline_switch_pm' + botID; + return Storage.get(key).then(function (peerData) { + if (peerData) { + Storage.remove(key); + if (tsNow() - peerData.time < 3600000) { + return peerData.peer; + } + } + return false; + }); + } + + function switchInlineQuery(botID, toPeerString, query) { + $rootScope.$broadcast('history_focus', { + peerString: toPeerString, + attachment: { + _: 'inline_query', + mention: '@' + AppUsersManager.getUser(botID).username, + query: query + } + }); + } + + function switchInlineButtonClick(id, button) { + var message = AppMessagesManager.getMessage(id); + var botID = message.fromID; + return checkSwitchReturn(botID).then(function (retPeerString) { + if (retPeerString) { + return switchInlineQuery(botID, retPeerString, button.query); + } + PeersSelectService.selectPeer({ + canSend: true + }).then(function (toPeerString) { + return switchInlineQuery(botID, toPeerString, button.query); + }); + }); + } + + function callbackButtonClick(id, button) { + var message = AppMessagesManager.getMessage(id); + var botID = message.fromID; + var peerID = AppMessagesManager.getMessagePeer(message); + + return MtpApiManager.invokeApi('messages.getBotCallbackAnswer', { + peer: AppPeersManager.getInputPeerByID(peerID), + msg_id: AppMessagesManager.getMessageLocalID(id), + data: button.data + }).then(function (callbackAnswer) { + console.info(callbackAnswer.message || 'empty answer'); + }); + } + + function sendInlineResult (peerID, qID, options) { var inlineResult = inlineResults[qID]; if (inlineResult === undefined) { @@ -3063,6 +3105,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) curState.pts = update.pts; popPts = true; } + else if (update.pts_count) { + // console.warn(dT(), 'Duplicate update', update); + return false; + } if (channelID && options.date && updatesState.date < options.date) { updatesState.date = options.date; } @@ -4228,7 +4274,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } } else if (name === 'share' && data.blobs && data.blobs.length > 0) { - PeersSelectService.selectPeers({confirm_type: 'EXT_SHARE_PEER'}).then(function (peerStrings) { + PeersSelectService.selectPeers({confirm_type: 'EXT_SHARE_PEER', canSend: true}).then(function (peerStrings) { angular.forEach(peerStrings, function (peerString) { var peerID = AppPeersManager.getPeerID(peerString); angular.forEach(data.blobs, function (blob) { diff --git a/app/partials/desktop/reply_markup.html b/app/partials/desktop/reply_markup.html index 4eca04ee..13388204 100644 --- a/app/partials/desktop/reply_markup.html +++ b/app/partials/desktop/reply_markup.html @@ -2,8 +2,8 @@
- - + +