diff --git a/app/js/controllers.js b/app/js/controllers.js index 765004d0..77c3f5fc 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -638,6 +638,9 @@ angular.module('myApp.controllers', ['myApp.i18n']) var topMessages = []; var topToDialogs = {}; angular.forEach(dialogsUpdated, function (dialog, peerID) { + if ($scope.noUsers && peerID > 0) { + return; + } topToDialogs[dialog.top_message] = dialog; topMessages.push(dialog.top_message); }); @@ -776,7 +779,11 @@ angular.module('myApp.controllers', ['myApp.i18n']) return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID); }); } else { - promise = AppMessagesManager.getDialogs($scope.search.query, maxID); + var query = $scope.search.query; + if ($scope.noUsers) { + query = '%pg ' + (query || ''); + } + promise = AppMessagesManager.getDialogs(query, maxID); } return promise.then(function (result) { @@ -861,7 +868,10 @@ angular.module('myApp.controllers', ['myApp.i18n']) return; } - if (!hasMore && !searchMessages && ($scope.search.query || !$scope.dialogs.length)) { + if (!hasMore && + !searchMessages && + !$scope.noUsers && + ($scope.search.query || !$scope.dialogs.length)) { showMoreConversations(); return; } @@ -936,7 +946,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) }, 500); } - if ($scope.search.query) { + if ($scope.search.query && !$scope.noMessages) { searchMessages = true; loadDialogs(); } @@ -2570,6 +2580,19 @@ angular.module('myApp.controllers', ['myApp.i18n']) }); }; + $scope.inviteToGroup = function () { + PeersSelectService.selectPeer({ + confirm_type: 'INVITE_TO_GROUP', + noUsers: true + }).then(function (peerString) { + var peerID = AppPeersManager.getPeerID(peerString); + var chatID = peerID < 0 ? -peerID : 0; + AppMessagesManager.startBot($scope.user.id, chatID).then(function () { + $rootScope.$broadcast('history_focus', {peerString: peerString}); + }); + }); + }; + $scope.toggleBlock = function (block) { MtpApiManager.invokeApi(block ? 'contacts.block' : 'contacts.unblock', { id: AppUsersManager.getUserInput($scope.userID) diff --git a/app/js/lib/utils.js b/app/js/lib/utils.js index fdcdc47e..daa63d25 100644 --- a/app/js/lib/utils.js +++ b/app/js/lib/utils.js @@ -365,11 +365,15 @@ function versionCompare (ver1, ver2) { } function cleanSearchText (text) { + var hasTag = text.charAt(0) == '%'; text = text.replace(badCharsRe, ' ').replace(trimRe, ''); text = text.replace(/[^A-Za-z0-9]/g, function (ch) { return Config.LatinizeMap[ch] || ch; }); text = text.toLowerCase(); + if (hasTag) { + text = '%' + text; + } return text; } diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index 47ac64a1..fc481dcf 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -115,6 +115,7 @@ "user_modal_block_user": "Block user", "user_modal_unblock_user": "Unblock user", "user_modal_delete_chat": "Delete chat", + "user_modal_add_to_group": "Add to group", "user_modal_info": "Info", "user_modal_phone": "Phone", "user_modal_about": "About", diff --git a/app/js/services.js b/app/js/services.js index 0500d00b..360a2748 100755 --- a/app/js/services.js +++ b/app/js/services.js @@ -795,10 +795,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) getPeerSearchText: function (peerID) { var text; if (peerID > 0) { - text = AppUsersManager.getUserSearchText(peerID); + text = '%pu ' + AppUsersManager.getUserSearchText(peerID); } else if (peerID < 0) { var chat = AppChatsManager.getChat(-peerID); - text = chat.title || ''; + text = '%pg ' + (chat.title || ''); } return text; }, @@ -973,7 +973,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) NotificationsManager.start(); function getDialogs (query, maxID, limit) { - var curDialogStorage = dialogsStorage; if (angular.isString(query) && query.length) { @@ -2006,6 +2005,39 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) }); }; + function startBot (botID, chatID, startParam) { + if (startParam) { + var randomID = bigint(nextRandomInt(0xFFFFFFFF)).shiftLeft(32).add(bigint(nextRandomInt(0xFFFFFFFF))).toString(); + + return MtpApiManager.invokeApi('messages.startBot', { + bot: AppUsersManager.getUserInput(botID), + chat_id: chatID, + random_id: randomID, + start_param: startParam + }); + } + + var peerID = chatID ? -chatID : botID; + var inputPeer = AppPeersManager.getInputPeerByID(peerID); + + if (chatID) { + return MtpApiManager.invokeApi('messages.addChatUser', { + chat_id: chatID, + user_id: AppUsersManager.getUserInput(botID) + }).then(function (updates) { + ApiUpdatesManager.processUpdateMessage(updates); + }, function (error) { + if (error && error.type == 'USER_ALREADY_PARTICIPANT') { + var bot = AppUsersManager.getUser(botID); + sendText(-chatID, '/start@' + bot.username); + error.handled = true; + } + }); + } + + return sendText(botID, '/start'); + } + function cancelPendingMessage (randomID) { var pendingData = pendingByRandomID[randomID]; @@ -2909,6 +2941,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) sendFile: sendFile, sendOther: sendOther, forwardMessages: forwardMessages, + startBot: startBot, openChatInviteLink: openChatInviteLink, getMessagePeer: getMessagePeer, wrapForDialog: wrapForDialog, @@ -4549,7 +4582,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) url = 'tg://addstickers?set=' + path[1]; break; default: - url = 'tg://resolve?domain=' + path[0]; + var domainQuery = path[0].split('?'); + url = 'tg://resolve?domain=' + domainQuery[0] + (domainQuery[1] ? '&' + domainQuery[1] : ''); } } } else { // IP address @@ -5409,6 +5443,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) function selectPeer (options) { var scope = $rootScope.$new(); scope.multiSelect = false; + scope.noMessages = true; if (options) { angular.extend(scope, options); } @@ -5430,6 +5465,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) var scope = $rootScope.$new(); scope.multiSelect = true; + scope.noMessages = true; if (options) { angular.extend(scope, options); } @@ -5651,7 +5687,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) }) -.service('LocationParamsService', function ($rootScope, $routeParams, AppPeersManager, AppUsersManager, AppMessagesManager, AppStickersManager) { +.service('LocationParamsService', function ($rootScope, $routeParams, AppPeersManager, AppUsersManager, AppMessagesManager, PeersSelectService, AppStickersManager) { var tgAddrRegExp = /^(web\+)?tg:(\/\/)?(.+)/; @@ -5671,10 +5707,26 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) function handleTgProtoAddr (url, inner) { var matches; - if (matches = url.match(/^resolve\?domain=(.+)$/)) { + if (matches = url.match(/^resolve\?domain=(.+?)(?:&(start|startgroup)=(.+))?$/)) { AppUsersManager.resolveUsername(matches[1]).then(function (userID) { + + if (matches[2] == 'startgroup') { + PeersSelectService.selectPeer({ + confirm_type: 'INVITE_TO_GROUP', + noUsers: true + }).then(function (peerString) { + var peerID = AppPeersManager.getPeerID(peerString); + var chatID = peerID < 0 ? -peerID : 0; + AppMessagesManager.startBot(userID, chatID, matches[3]).then(function () { + $rootScope.$broadcast('history_focus', {peerString: peerString}); + }); + }); + return true; + } + $rootScope.$broadcast('history_focus', { - peerString: AppUsersManager.getUserString(userID) + peerString: AppUsersManager.getUserString(userID), + startParam: matches[3] }); }); return true; diff --git a/app/partials/desktop/user_modal.html b/app/partials/desktop/user_modal.html index dd04eba5..c7a7c5ab 100644 --- a/app/partials/desktop/user_modal.html +++ b/app/partials/desktop/user_modal.html @@ -69,6 +69,10 @@