diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 0cc9d7fc0..a533e34dd 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2031,6 +2031,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gigagroup_warning_title" = "Are you sure?"; "lng_gigagroup_warning" = "Regular members of the group (non-admins) will **irrevocably** lose their right to post messages in the group.\n\nThis action **can't** be undone."; "lng_gigagroup_done" = "Your group can now have more than 200,000 members."; +"lng_gigagroup_suggest_title" = "Limit reached"; +"lng_gigagroup_suggest_text" = "Your group has reached a limit of **200,000** members.\n\nYou can increase this limit by converting the group to a **broadcast group** where only admins can post. Interested?"; +"lng_gigagroup_suggest_more" = "Learn more"; "lng_rights_channel_info" = "Change channel info"; "lng_rights_channel_post" = "Post messages"; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp index 6918fe0d4..a1570e1c6 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp @@ -314,6 +314,68 @@ ChatAdminRights AdminRightsForOwnershipTransfer(bool isGroup) { return result; } +Fn AboutGigagroupCallback(not_null channel) { + const auto converting = std::make_shared(); + const auto convertSure = [=] { + if (*converting) { + return; + } + *converting = true; + channel->session().api().request(MTPchannels_ConvertToGigagroup( + channel->inputChannel + )).done([=](const MTPUpdates &result) { + channel->session().api().applyUpdates(result); + Ui::hideSettingsAndLayer(); + Ui::Toast::Show(tr::lng_gigagroup_done(tr::now)); + }).fail([=](const RPCError &error) { + *converting = false; + }).send(); + }; + const auto convertWarn = [=] { + if (*converting) { + return; + } + Ui::show(Box([=](not_null box) { + box->setTitle(tr::lng_gigagroup_warning_title()); + box->addRow( + object_ptr( + box, + tr::lng_gigagroup_warning( + ) | Ui::Text::ToRichLangValue(), + st::infoAboutGigagroup)); + box->addButton(tr::lng_gigagroup_convert_sure(), convertSure); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + }), Ui::LayerOption::KeepOther); + }; + return [=] { + if (*converting) { + return; + } + Ui::show(Box([=](not_null box) { + box->setTitle(tr::lng_gigagroup_convert_title()); + const auto addFeature = [&](rpl::producer text) { + using namespace rpl::mappers; + const auto prefix = QString::fromUtf8("\xE2\x80\xA2 "); + box->addRow( + object_ptr( + box, + std::move(text) | rpl::map(prefix + _1), + st::infoAboutGigagroup), + style::margins( + st::boxRowPadding.left(), + st::boxLittleSkip, + st::boxRowPadding.right(), + st::boxLittleSkip)); + }; + addFeature(tr::lng_gigagroup_convert_feature1()); + addFeature(tr::lng_gigagroup_convert_feature2()); + addFeature(tr::lng_gigagroup_convert_feature3()); + box->addButton(tr::lng_gigagroup_convert_sure(), convertWarn); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + }), Ui::LayerOption::KeepOther); + }; +} + EditPeerPermissionsBox::EditPeerPermissionsBox( QWidget*, not_null navigation, @@ -541,71 +603,11 @@ void EditPeerPermissionsBox::addSuggestGigagroup( tr::lng_rights_gigagroup_title(), st::rightsHeaderLabel), st::rightsHeaderMargin); - const auto channel = _peer->asChannel(); - const auto converting = std::make_shared(); - const auto convertSure = [=] { - if (*converting) { - return; - } - *converting = true; - channel->session().api().request(MTPchannels_ConvertToGigagroup( - channel->inputChannel - )).done([=](const MTPUpdates &result) { - channel->session().api().applyUpdates(result); - Ui::hideSettingsAndLayer(); - Ui::Toast::Show(tr::lng_gigagroup_done(tr::now)); - }).fail([=](const RPCError &error) { - *converting = false; - }).send(); - }; - const auto convertWarn = [=] { - if (*converting) { - return; - } - getDelegate()->show(Box([=](not_null box) { - box->setTitle(tr::lng_gigagroup_warning_title()); - box->addRow( - object_ptr( - box, - tr::lng_gigagroup_warning( - ) | Ui::Text::ToRichLangValue(), - st::infoAboutGigagroup)); - box->addButton(tr::lng_gigagroup_convert_sure(), convertSure); - box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); - })); - }; - const auto convert = [=] { - if (*converting) { - return; - } - getDelegate()->show(Box([=](not_null box) { - box->setTitle(tr::lng_gigagroup_convert_title()); - const auto addFeature = [&](rpl::producer text) { - using namespace rpl::mappers; - const auto prefix = QString::fromUtf8("\xE2\x80\xA2 "); - box->addRow( - object_ptr( - box, - std::move(text) | rpl::map(prefix + _1), - st::infoAboutGigagroup), - style::margins( - st::boxRowPadding.left(), - st::boxLittleSkip, - st::boxRowPadding.right(), - st::boxLittleSkip)); - }; - addFeature(tr::lng_gigagroup_convert_feature1()); - addFeature(tr::lng_gigagroup_convert_feature2()); - addFeature(tr::lng_gigagroup_convert_feature3()); - box->addButton(tr::lng_gigagroup_convert_sure(), convertWarn); - box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); - })); - }; container->add(EditPeerInfoBox::CreateButton( container, tr::lng_rights_gigagroup_convert(), rpl::single(QString()), - convert, + AboutGigagroupCallback(_peer->asChannel()), st::peerPermissionsButton)); container->add( diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h index a817ac3da..ee4dfc0df 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h @@ -49,6 +49,9 @@ private: }; +[[nodiscard]] Fn AboutGigagroupCallback( + not_null channel); + template struct EditFlagsControl { object_ptr widget; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 880945e0b..c09430116 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -739,6 +739,16 @@ void ApplyChannelUpdate( const MTPDchannelFull &update) { const auto session = &channel->session(); + if (channel->isMegagroup()) { + const auto suggestions = update.vpending_suggestions().value_or_empty(); + channel->owner().setSuggestToGigagroup( + channel, + ranges::contains( + suggestions, + "convert_to_gigagroup"_q, + &MTPstring::v)); + } + channel->setAvailableMinId(update.vavailable_min_id().value_or_empty()); auto canViewAdmins = channel->canViewAdmins(); auto canViewMembers = channel->canViewMembers(); diff --git a/Telegram/SourceFiles/data/data_groups.cpp b/Telegram/SourceFiles/data/data_groups.cpp index 965566994..650a4f889 100644 --- a/Telegram/SourceFiles/data/data_groups.cpp +++ b/Telegram/SourceFiles/data/data_groups.cpp @@ -65,8 +65,8 @@ void Groups::unregisterMessage(not_null item) { } void Groups::refreshMessage( - not_null item, - bool justRefreshViews) { + not_null item, + bool justRefreshViews) { if (!isGrouped(item)) { unregisterMessage(item); return; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index c72ad3603..8d844e64e 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -2049,6 +2049,20 @@ MsgId Session::nextLocalMessageId() { return _localMessageIdCounter++; } +void Session::setSuggestToGigagroup( + not_null group, + bool suggest) { + if (suggest) { + _suggestToGigagroup.emplace(group); + } else { + _suggestToGigagroup.remove(group); + } +} + +bool Session::suggestToGigagroup(not_null group) const { + return _suggestToGigagroup.contains(group); +} + HistoryItem *Session::message(ChannelId channelId, MsgId itemId) const { if (!itemId) { return nullptr; diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 1a307076d..3e0418093 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -327,6 +327,10 @@ public: const Dialogs::Key &key1, const Dialogs::Key &key2); + void setSuggestToGigagroup(not_null group, bool suggest); + [[nodiscard]] bool suggestToGigagroup( + not_null group) const; + void registerMessage(not_null item); void unregisterMessage(not_null item); @@ -930,6 +934,7 @@ private: rpl::event_stream> _webpageUpdates; rpl::event_stream> _channelDifferenceTooLong; + base::flat_set> _suggestToGigagroup; base::flat_multi_map> _pollsClosings; base::Timer _pollsClosingTimer; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index e504f0d82..87a68e485 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/send_files_box.h" #include "boxes/share_box.h" #include "boxes/edit_caption_box.h" +#include "boxes/peers/edit_peer_permissions_box.h" // ShowAboutGigagroup. #include "core/file_utilities.h" #include "ui/toast/toast.h" #include "ui/toasts/common_toasts.h" @@ -3446,6 +3447,36 @@ void HistoryWidget::doneShow() { checkHistoryActivation(); controller()->widget()->setInnerFocus(); _preserveScrollTop = false; + checkSuggestToGigagroup(); +} + +void HistoryWidget::checkSuggestToGigagroup() { + const auto group = _peer ? _peer->asMegagroup() : nullptr; + if (!group || !group->owner().suggestToGigagroup(group)) { + return; + } + InvokeQueued(_list, [=] { + if (!Ui::isLayerShown()) { + group->owner().setSuggestToGigagroup(group, false); + group->session().api().request(MTPhelp_DismissSuggestion( + group->input, + MTP_string("convert_to_gigagroup") + )).send(); + Ui::show(Box([=](not_null box) { + box->setTitle(tr::lng_gigagroup_suggest_title()); + box->addRow( + object_ptr( + box, + tr::lng_gigagroup_suggest_text( + ) | Ui::Text::ToRichLangValue(), + st::infoAboutGigagroup)); + box->addButton( + tr::lng_gigagroup_suggest_more(), + AboutGigagroupCallback(group)); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + })); + } + }); } void HistoryWidget::finishAnimating() { @@ -6183,6 +6214,7 @@ void HistoryWidget::fullPeerUpdated(PeerData *peer) { _list->updateBotInfo(); handlePeerUpdate(); + checkSuggestToGigagroup(); } if (updateCmdStartShown()) { refresh = true; diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 49c093912..65df86b0e 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -330,6 +330,8 @@ private: using TextUpdateEvents = base::flags; friend inline constexpr bool is_flag_type(TextUpdateEvent) { return true; }; + void checkSuggestToGigagroup(); + void initTabbedSelector(); void initVoiceRecordBar(); void refreshTabbedPanel();