diff --git a/app/js/controllers.js b/app/js/controllers.js index fa39754b..451fc673 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -1794,6 +1794,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) historiesQueuePop(updPeerID); }); + $scope.$on('dialog_migrate', function (e, data) { + if (data.migrateFrom == $scope.curDialog.peerID) { + var peerString = AppPeersManager.getPeerString(data.migrateTo); + $rootScope.$broadcast('history_focus', {peerString: peerString}); + } + historiesQueuePop(data.migrateFrom); + }); + $scope.$on('notify_settings', function (e, data) { if (data.peerID == $scope.curDialog.peerID) { updateChannelActions(); @@ -3161,10 +3169,21 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {}); $scope.settings = {notifications: true}; + $scope.maxParticipants = 200; + AppProfileManager.getChatFull($scope.chatID).then(function (chatFull) { $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull); $scope.$broadcast('ui_height'); + $scope.canMigrate = $scope.chatFull && + $scope.chatFull.participants && + $scope.chatFull.participants.participants && + $scope.chatFull.participants.participants.length >= 200; + + if (Config.Modes.test || Config.Modes.debug) { + $scope.canMigrate = true; + } + NotificationsManager.savePeerSettings(-$scope.chatID, chatFull.notify_settings); NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) { @@ -3229,6 +3248,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) }); }; + $scope.migrateToSuperGroup = function () { + ErrorService.confirm({type: 'SUPERGROUP_MIGRATE'}).then(function () { + MtpApiManager.invokeApi('messages.migrateChat', { + chat_id: AppChatsManager.getChatInput($scope.chatID) + }).then(onChatUpdated); + }); + } + $scope.kickFromGroup = function (userID) { MtpApiManager.invokeApi('messages.deleteChatUser', { chat_id: AppChatsManager.getChatInput($scope.chatID), @@ -3338,6 +3365,15 @@ angular.module('myApp.controllers', ['myApp.i18n']) }); }); }); + + if ($scope.chatFull.chat && + $scope.chatFull.chat.pFlags.creator && + $scope.chatFull.exported_invite && + $scope.chatFull.exported_invite._ == 'chatInviteEmpty') { + AppProfileManager.getChatInviteLink($scope.chatID, true).then(function (link) { + $scope.chatFull.exported_invite = {_: 'chatInviteExported', link: link}; + }); + } }); diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index 6037e0b7..7af60b57 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -24,8 +24,15 @@ "group_modal_settings": "Settings", "group_modal_notifications": "Notifications", "group_modal_menu_share_link": "Invite to group via link", + "group_modal_migrate_to_supergroup": "Upgrade to supergroup", "group_modal_members": "Members", "group_modal_members_kick": "Remove", + "group_modal_migrate_header": "Members limit reached", + "group_modal_migrate_desc": "To go over the limit and get additional features, upgrade to a supergroup.", + "group_modal_migrate_item1": "Supergroups can get up to 1000 members", + "group_modal_migrate_item2": "New members see the entire chat history", + "group_modal_migrate_item3": "Admins delete messages for everyone", + "group_modal_migrate_item4": "Notifications are muted by default", "channel_modal_info": "Channel info", "channel_modal_description": "Description", @@ -223,6 +230,7 @@ "confirm_modal_revoke_channel_link": "Are you sure you want to revoke this link? Once you do, no one will be able to join the channel using it.", "confirm_modal_delete_channel_md": "Are you sure you want to delete this channel?\n\nAll members will be removed and all messages will be lost.", "confirm_modal_jump_ext_url_md": "Open this link?\n\n{url}", + "confirm_modal_migrate_supergroup_md": "Please note that group members will need to update their Telegram apps to the latest version to see your supergroup.\n\nAre you sure you want to upgrage this group?", "confirm_modal_are_u_sure": "Are you sure?", diff --git a/app/js/messages_manager.js b/app/js/messages_manager.js index 7f4aa681..7ae4f700 100644 --- a/app/js/messages_manager.js +++ b/app/js/messages_manager.js @@ -473,11 +473,8 @@ angular.module('myApp.services') function fillHistoryStorage (peerID, maxID, fullLimit, historyStorage) { // console.log('fill history storage', peerID, maxID, fullLimit, angular.copy(historyStorage)); - var migratedNextPeer = migratedFromTo[peerID]; - var migratedPrevPeer = migratedToFrom[peerID]; - var isMigrated = migratedNextPeer !== undefined || migratedPrevPeer !== undefined; - - return requestHistory (peerID, maxID, fullLimit).then(function (historyResult) { + var offset = (migratedFromTo[peerID] && !maxID) ? 1 : 0; + return requestHistory (peerID, maxID, fullLimit, offset).then(function (historyResult) { historyStorage.count = historyResult.count || historyResult.messages.length; var offset = 0; @@ -505,6 +502,10 @@ angular.module('myApp.services') var totalCount = historyStorage.history.length; fullLimit -= (totalCount - wasTotalCount); + var migratedNextPeer = migratedFromTo[peerID]; + var migratedPrevPeer = migratedToFrom[peerID]; + var isMigrated = migratedNextPeer !== undefined || migratedPrevPeer !== undefined; + if (isMigrated) { historyStorage.count = Math.max(historyStorage.count, totalCount) + 1; } @@ -546,6 +547,30 @@ angular.module('myApp.services') return $q.when(result); } + function migrateChecks (migrateFrom, migrateTo) { + if (!migratedFromTo[migrateFrom] && + !migratedToFrom[migrateTo] && + AppChatsManager.hasChat(-migrateTo)) { + + var fromChat = AppChatsManager.getChat(-migrateFrom); + if (fromChat && + fromChat.migrated_to && + fromChat.migrated_to.channel_id == -migrateTo) { + migratedFromTo[migrateFrom] = migrateTo; + migratedToFrom[migrateTo] = migrateFrom; + + $timeout(function () { + var foundDialog = getDialogByPeerID(migrateFrom); + if (foundDialog.length) { + dialogsStorage.dialogs.splice(foundDialog[1], 1); + $rootScope.$broadcast('dialog_drop', {peerID: migrateFrom}); + } + $rootScope.$broadcast('dialog_migrate', {migrateFrom: migrateFrom, migrateTo: migrateTo}); + }, 100); + } + } + } + function getHistory (peerID, maxID, limit, backLimit, prerendered) { if (migratedFromTo[peerID]) { peerID = migratedFromTo[peerID]; @@ -1174,6 +1199,7 @@ angular.module('myApp.services') } } if (apiMessage.action) { + var migrateFrom, migrateTo; switch (apiMessage.action._) { case 'messageActionChatEditPhoto': AppPhotosManager.savePhoto(apiMessage.action.photo, mediaContext); @@ -1211,6 +1237,22 @@ angular.module('myApp.services') apiMessage.action._ = 'messageActionChatLeave'; } break; + + case 'messageActionChannelMigrateFrom': + migrateFrom = -apiMessage.action.chat_id; + migrateTo = -channelID; + break; + + case 'messageActionChatMigrateTo': + migrateFrom = -channelID; + migrateTo = -apiMessage.action.channel_id; + break; + } + if (migrateFrom && + migrateTo && + !migratedFromTo[migrateFrom] && + !migratedToFrom[migrateTo]) { + migrateChecks(migrateFrom, migrateTo); } } diff --git a/app/js/services.js b/app/js/services.js index 8b3a0757..081e8010 100755 --- a/app/js/services.js +++ b/app/js/services.js @@ -1089,9 +1089,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) chatFull.exported_invite._ == 'chatInviteExported') { return chatFull.exported_invite.link; } - return MtpApiManager.invokeApi('messages.exportChatInvite', { - chat_id: AppChatsManager.getChatInput(id) - }).then(function (exportedInvite) { + var promise; + if (AppChatsManager.isChannel(id)) { + promise = MtpApiManager.invokeApi('channels.exportInvite', { + channel: AppChatsManager.getChannelInput(id) + }); + } else { + promise = MtpApiManager.invokeApi('messages.exportChatInvite', { + chat_id: AppChatsManager.getChatInput(id) + }); + } + return promise.then(function (exportedInvite) { if (chatsFull[id] !== undefined) { chatsFull[id].exported_invite = exportedInvite; } diff --git a/app/less/app.less b/app/less/app.less index 2c85314e..33e55111 100644 --- a/app/less/app.less +++ b/app/less/app.less @@ -3012,13 +3012,15 @@ _:-ms-lang(x), .composer_rich_textarea:empty:focus:before { padding: 20px 0; font-size: 14px; line-height: 160%; - word-break: break-all; } .confirm_phone_number { font-weight: bold; padding: 15px 10px 0; text-align: center; } +.confirm_modal_extlink_jump { + word-break: break-all; +} .photo_modal_window, .video_modal_window, @@ -3208,6 +3210,16 @@ a.contacts_modal_contact:hover .md_modal_list_peer_description, color: #91a6ba; } +h4.chat_modal_migrate_header { + font-size: inherit; + font-weight: bold; + color: inherit; +} +ul.chat_modal_migrate_list { + margin-top: 10px; + padding-left: 15px; +} + .chat_modal_participant_wrap { padding: 8px 0; border-top: 1px solid #F0F0F0; @@ -4045,11 +4057,18 @@ a.countries_modal_search_clear { &_splitter { border-top: 1px solid #dfdfdf; - height: 12px; + min-height: 12px; background: #f5f5f5; .box-shadow(inset 0px 1px 1px #ededed); } + &_splitter_content { + height: auto; + padding-left: 120px; + color: #777; + font-size: 12px; + padding: 5px 20px 3px 55px; + } } .md_modal_versioned_section_wrap { diff --git a/app/partials/desktop/chat_modal.html b/app/partials/desktop/chat_modal.html index 3eba1880..35a31141 100644 --- a/app/partials/desktop/chat_modal.html +++ b/app/partials/desktop/chat_modal.html @@ -40,7 +40,7 @@