diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 37ddc7d5b1..e342a09ad1 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1514,6 +1514,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_restricted_send_inline" = "The admins of this group restricted you from posting inline content here."; "lng_restricted_send_polls" = "The admins of this group restricted you from posting polls here."; +"lng_restricted_send_message_all" = "Writing messages isn't allowed in this group."; +"lng_restricted_send_media_all" = "Posting media content isn't allowed in this group."; +"lng_restricted_send_stickers_all" = "Posting stickers isn't allowed in this group."; +"lng_restricted_send_gifs_all" = "Posting GIFs isn't allowed in this group."; +"lng_restricted_send_inline_all" = "Posting inline content isn't allowed in this group."; +"lng_restricted_send_polls_all" = "Posting polls isn't allowed in this group."; + "lng_restricted_list_title" = "Restricted users"; "lng_banned_list_title" = "Banned users"; diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index ed4c71744e..1acc10f901 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -354,7 +354,7 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) { }(); if (user) { if (user->contactStatus() == UserData::ContactStatus::Contact - || Auth().supportMode()) { + || user->session().supportMode()) { Ui::showPeerHistory(user, ShowAtTheEndMsgId); } Ui::hideLayer(); @@ -539,7 +539,9 @@ void GroupInfoBox::createGroup( } | [&](not_null chat) { if (!image.isNull()) { - Auth().api().uploadPeerPhoto(chat, std::move(image)); + chat->session().api().uploadPeerPhoto( + chat, + std::move(image)); } Ui::showPeerHistory(chat, ShowAtUnreadMsgId); }; @@ -617,7 +619,11 @@ void GroupInfoBox::submit() { void GroupInfoBox::createChannel(const QString &title, const QString &description) { bool mega = false; auto flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast; - _creationRequestId = request(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description))).done([this](const MTPUpdates &result) { + _creationRequestId = request(MTPchannels_CreateChannel( + MTP_flags(flags), + MTP_string(title), + MTP_string(description) + )).done([=](const MTPUpdates &result) { Auth().api().applyUpdates(result); auto success = base::make_optional(&result) @@ -639,10 +645,12 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio | [](auto chats) { return App::channel(chats->front().c_channel().vid.v); } - | [this](not_null channel) { + | [&](not_null channel) { auto image = _photo->takeResultImage(); if (!image.isNull()) { - Auth().api().uploadPeerPhoto(channel, std::move(image)); + channel->session().api().uploadPeerPhoto( + channel, + std::move(image)); } _createdChannel = channel; _creationRequestId = request(MTPmessages_ExportChatInvite( @@ -825,7 +833,7 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) { void SetupChannelBox::mousePressEvent(QMouseEvent *e) { if (_linkOver) { if (_channel->inviteLink().isEmpty()) { - Auth().api().exportInviteLink(_channel); + _channel->session().api().exportInviteLink(_channel); } else { QGuiApplication::clipboard()->setText(_channel->inviteLink()); Ui::Toast::Show(lang(lng_create_channel_link_copied)); diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 663e7cb8b8..e9dd8b2700 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -31,37 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "auth_session.h" #include "observer_peer.h" -namespace { - -void ConvertToSupergroupDone(const MTPUpdates &updates) { - Auth().api().applyUpdates(updates); - - auto handleChats = [](const MTPVector &chats) { - for (const auto &chat : chats.v) { - if (chat.type() == mtpc_channel) { - const auto channel = App::channel(chat.c_channel().vid.v); - Ui::showPeerHistory(channel, ShowAtUnreadMsgId); - Auth().api().requestParticipantsCountDelayed(channel); - } - } - }; - - switch (updates.type()) { - case mtpc_updates: - handleChats(updates.c_updates().vchats); - break; - case mtpc_updatesCombined: - handleChats(updates.c_updatesCombined().vchats); - break; - default: - LOG(("API Error: unexpected update cons %1 " - "(ConvertToSupergroupBox::convertDone)").arg(updates.type())); - break; - } -} - -} // namespace - TextParseOptions _confirmBoxTextOptions = { TextParseLinks | TextParseMultiline | TextParseRichText, // flags 0, // maxw @@ -69,7 +38,11 @@ TextParseOptions _confirmBoxTextOptions = { Qt::LayoutDirectionAuto, // dir }; -ConfirmBox::ConfirmBox(QWidget*, const QString &text, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(lang(lng_box_ok)) , _cancelText(lang(lng_cancel)) , _confirmStyle(st::defaultBoxButton) @@ -79,7 +52,12 @@ ConfirmBox::ConfirmBox(QWidget*, const QString &text, FnMut confirmedCal init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(confirmText) , _cancelText(lang(lng_cancel)) , _confirmStyle(st::defaultBoxButton) @@ -89,7 +67,12 @@ ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText init(text); } -ConfirmBox::ConfirmBox(QWidget*, const TextWithEntities &text, const QString &confirmText, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const TextWithEntities &text, + const QString &confirmText, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(confirmText) , _cancelText(lang(lng_cancel)) , _confirmStyle(st::defaultBoxButton) @@ -99,7 +82,13 @@ ConfirmBox::ConfirmBox(QWidget*, const TextWithEntities &text, const QString &co init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + const style::RoundButton &confirmStyle, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(confirmText) , _cancelText(lang(lng_cancel)) , _confirmStyle(confirmStyle) @@ -109,7 +98,13 @@ ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const QString &cancelText, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + const QString &cancelText, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(confirmText) , _cancelText(cancelText) , _confirmStyle(st::defaultBoxButton) @@ -119,7 +114,14 @@ ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText init(text); } -ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText, const style::RoundButton &confirmStyle, const QString &cancelText, FnMut confirmedCallback, FnMut cancelledCallback) +ConfirmBox::ConfirmBox( + QWidget*, + const QString &text, + const QString &confirmText, + const style::RoundButton &confirmStyle, + const QString &cancelText, + FnMut confirmedCallback, + FnMut cancelledCallback) : _confirmText(confirmText) , _cancelText(cancelText) , _confirmStyle(st::defaultBoxButton) @@ -129,7 +131,11 @@ ConfirmBox::ConfirmBox(QWidget*, const QString &text, const QString &confirmText init(text); } -ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString &doneText, Fn closedCallback) +ConfirmBox::ConfirmBox( + const InformBoxTag &, + const QString &text, + const QString &doneText, + Fn closedCallback) : _confirmText(doneText) , _confirmStyle(st::defaultBoxButton) , _informative(true) @@ -139,7 +145,11 @@ ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString init(text); } -ConfirmBox::ConfirmBox(const InformBoxTag &, const TextWithEntities &text, const QString &doneText, Fn closedCallback) +ConfirmBox::ConfirmBox( + const InformBoxTag &, + const TextWithEntities &text, + const QString &doneText, + Fn closedCallback) : _confirmText(doneText) , _confirmStyle(st::defaultBoxButton) , _informative(true) @@ -149,8 +159,9 @@ ConfirmBox::ConfirmBox(const InformBoxTag &, const TextWithEntities &text, const init(text); } -FnMut ConfirmBox::generateInformCallback(Fn closedCallback) { - return crl::guard(this, [this, closedCallback] { +FnMut ConfirmBox::generateInformCallback( + Fn closedCallback) { + return crl::guard(this, [=] { closeBox(); if (closedCallback) { closedCallback(); @@ -159,7 +170,10 @@ FnMut ConfirmBox::generateInformCallback(Fn closedCallback) { } void ConfirmBox::init(const QString &text) { - _text.setText(st::boxLabelStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions); + _text.setText( + st::boxLabelStyle, + text, + _informative ? _confirmBoxTextOptions : _textPlainOptions); } void ConfirmBox::init(const TextWithEntities &text) { @@ -167,9 +181,14 @@ void ConfirmBox::init(const TextWithEntities &text) { } void ConfirmBox::prepare() { - addButton([this] { return _confirmText; }, [this] { confirmed(); }, _confirmStyle); + addButton( + [=] { return _confirmText; }, + [=] { confirmed(); }, + _confirmStyle); if (!_informative) { - addButton([this] { return _cancelText; }, [this] { _cancelled = true; closeBox(); }); + addButton( + [=] { return _cancelText; }, + [=] { _cancelled = true; closeBox(); }); } boxClosing() | rpl::start_with_next([=] { @@ -321,7 +340,7 @@ void MaxInviteBox::mousePressEvent(QMouseEvent *e) { mouseMoveEvent(e); if (_linkOver) { if (_channel->inviteLink().isEmpty()) { - Auth().api().exportInviteLink(_channel); + _channel->session().api().exportInviteLink(_channel); } else { QGuiApplication::clipboard()->setText(_channel->inviteLink()); Ui::Toast::Show(lang(lng_create_channel_link_copied)); @@ -423,7 +442,7 @@ void PinMessageBox::pinMessage() { } void PinMessageBox::pinDone(const MTPUpdates &updates) { - Auth().api().applyUpdates(updates); + _peer->session().api().applyUpdates(updates); Ui::hideLayer(); } @@ -562,20 +581,21 @@ void DeleteMessagesBox::keyPressEvent(QKeyEvent *e) { void DeleteMessagesBox::deleteAndClear() { if (_moderateFrom) { if (_banUser && _banUser->checked()) { - Auth().api().kickParticipant( + _moderateInChannel->session().api().kickParticipant( _moderateInChannel, _moderateFrom, MTP_chatBannedRights(MTP_flags(0), MTP_int(0))); } if (_reportSpam->checked()) { - MTP::send( + _moderateInChannel->session().api().request( MTPchannels_ReportSpam( _moderateInChannel->inputChannel, _moderateFrom->inputUser, - MTP_vector(1, MTP_int(_ids[0].msg)))); + MTP_vector(1, MTP_int(_ids[0].msg))) + ).send(); } if (_deleteAll && _deleteAll->checked()) { - Auth().api().deleteAllFromUser( + _moderateInChannel->session().api().deleteAllFromUser( _moderateInChannel, _moderateFrom); } @@ -596,7 +616,7 @@ void DeleteMessagesBox::deleteAndClear() { if (wasOnServer) { idsByPeer[history->peer].push_back(MTP_int(itemId.msg)); } else if (wasLast && !history->lastMessageKnown()) { - Auth().api().requestDialogEntry(history); + history->session().api().requestDialogEntry(history); } } } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 2695a08c01..fe9b317470 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -439,14 +439,16 @@ void AddBotToGroupBoxController::addBotToGroup(not_null chat) { LayerOption::KeepOther); } -std::unique_ptr AddBotToGroupBoxController::createRow(not_null history) { +auto AddBotToGroupBoxController::createRow(not_null history) +-> std::unique_ptr { if (!needToCreateRow(history->peer)) { return nullptr; } return std::make_unique(history); } -bool AddBotToGroupBoxController::needToCreateRow(not_null peer) const { +bool AddBotToGroupBoxController::needToCreateRow( + not_null peer) const { if (sharingBotGame()) { if (!peer->canWrite() || peer->amRestricted(ChatRestriction::f_send_games)) { diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index d114fa9ca4..9e3f4f85e8 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -668,7 +668,7 @@ void Controller::exportInviteLink(const QString &confirmation) { if (const auto strong = *boxPointer) { strong->closeBox(); } - Auth().api().exportInviteLink(_peer->migrateToOrMe()); + _peer->session().api().exportInviteLink(_peer->migrateToOrMe()); }); auto box = Box( confirmation, @@ -1186,7 +1186,7 @@ void Controller::saveTitle() { } const auto onDone = [=](const MTPUpdates &result) { - Auth().api().applyUpdates(result); + _peer->session().api().applyUpdates(result); continueSave(); }; const auto onFail = [=](const RPCError &error) { @@ -1281,7 +1281,7 @@ void Controller::saveHistoryVisibility() { // So after saving we need to update it manually. channel->updateFullForced(); - Auth().api().applyUpdates(result); + channel->session().api().applyUpdates(result); continueSave(); }).fail([=](const RPCError &error) { if (error.type() == qstr("CHAT_NOT_MODIFIED")) { @@ -1302,10 +1302,10 @@ void Controller::saveSignatures() { request(MTPchannels_ToggleSignatures( channel->inputChannel, MTP_bool(*_savingData.signatures) - )).done([this](const MTPUpdates &result) { - Auth().api().applyUpdates(result); + )).done([=](const MTPUpdates &result) { + channel->session().api().applyUpdates(result); continueSave(); - }).fail([this](const RPCError &error) { + }).fail([=](const RPCError &error) { if (error.type() == qstr("CHAT_NOT_MODIFIED")) { continueSave(); } else { @@ -1319,7 +1319,7 @@ void Controller::savePhoto() { ? _controls.photo->takeResultImage() : QImage(); if (!image.isNull()) { - Auth().api().uploadPeerPhoto(_peer, std::move(image)); + _peer->session().api().uploadPeerPhoto(_peer, std::move(image)); } _box->closeBox(); } diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index fb9e5cebaa..782f085a40 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -673,21 +673,20 @@ void TabbedSelector::setCurrentPeer(PeerData *peer) { void TabbedSelector::checkRestrictedPeer() { if (_currentPeer) { - const auto restricted = (_currentTabType == SelectorTab::Stickers) - ? _currentPeer->amRestricted(ChatRestriction::f_send_stickers) + const auto errorKey = (_currentTabType == SelectorTab::Stickers) + ? Data::RestrictionErrorKey( + _currentPeer, + ChatRestriction::f_send_stickers) : (_currentTabType == SelectorTab::Gifs) - ? _currentPeer->amRestricted(ChatRestriction::f_send_gifs) - : false; - if (restricted) { + ? Data::RestrictionErrorKey( + _currentPeer, + ChatRestriction::f_send_gifs) + : std::nullopt; + if (errorKey) { if (!_restrictedLabel) { - auto text = (_currentTabType == SelectorTab::Stickers) - ? lang(lng_restricted_send_stickers) - : (_currentTabType == SelectorTab::Gifs) - ? lang(lng_restricted_send_gifs) - : QString(); _restrictedLabel.create( this, - text, + lang(*errorKey), Ui::FlatLabel::InitType::Simple, st::stickersRestrictedLabel); _restrictedLabel->show(); diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 6ca5d33ded..b9c04d8e76 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -326,10 +326,10 @@ bool MediaPhoto::allowsEditCaption() const { } QString MediaPhoto::errorTextForForward(not_null peer) const { - if (peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_media); + return errorKey ? lang(*errorKey) : QString(); } bool MediaPhoto::updateInlineResultMedia(const MTPMessageMedia &media) { @@ -651,21 +651,29 @@ bool MediaFile::forwardedBecomesUnread() const { QString MediaFile::errorTextForForward(not_null peer) const { if (const auto sticker = _document->sticker()) { - if (peer->amRestricted(ChatRestriction::f_send_stickers)) { - return lang(lng_restricted_send_stickers); + if (const auto key = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_stickers)) { + return lang(*key); } } else if (_document->isAnimation()) { if (_document->isVideoMessage()) { - if (peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); + if (const auto key = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_media)) { + return lang(*key); } } else { - if (peer->amRestricted(ChatRestriction::f_send_gifs)) { - return lang(lng_restricted_send_gifs); + if (const auto key = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_gifs)) { + return lang(*key); } } - } else if (peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); + } else if (const auto key = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_media)) { + return lang(*key); } return QString(); } @@ -1115,10 +1123,10 @@ TextWithEntities MediaGame::clipboardText() const { } QString MediaGame::errorTextForForward(not_null peer) const { - if (peer->amRestricted(ChatRestriction::f_send_games)) { - return lang(lng_restricted_send_inline); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_games); + return errorKey ? lang(*errorKey) : QString(); } bool MediaGame::consumeMessageText(const TextWithEntities &text) { @@ -1254,10 +1262,10 @@ TextWithEntities MediaPoll::clipboardText() const { } QString MediaPoll::errorTextForForward(not_null peer) const { - if (peer->amRestricted(ChatRestriction::f_send_polls)) { - return lang(lng_restricted_send_polls); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_polls); + return errorKey ? lang(*errorKey) : QString(); } bool MediaPoll::updateInlineResultMedia(const MTPMessageMedia &media) { diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 82b3cca3d7..d063942d01 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -598,7 +598,9 @@ bool PeerData::canWrite() const { : false; } -bool PeerData::amRestricted(ChatRestriction right) const { +Data::RestrictionCheckResult PeerData::amRestricted( + ChatRestriction right) const { + using Result = Data::RestrictionCheckResult; const auto allowByAdminRights = [](auto right, auto chat) -> bool { if (right == ChatRestriction::f_invite_users) { return chat->adminRights() & ChatAdminRight::f_invite_users; @@ -611,14 +613,61 @@ bool PeerData::amRestricted(ChatRestriction right) const { } }; if (const auto channel = asChannel()) { - return !channel->amCreator() - && !allowByAdminRights(right, channel) - && ((channel->restrictions() & right) - || (channel->defaultRestrictions() & right)); + return (channel->amCreator() || allowByAdminRights(right, channel)) + ? Result::Allowed() + : (channel->defaultRestrictions() & right) + ? Result::WithEveryone() + : (channel->restrictions() & right) + ? Result::Explicit() + : Result::Allowed(); } else if (const auto chat = asChat()) { - return !chat->amCreator() - && !allowByAdminRights(right, chat) - && (chat->defaultRestrictions() & right); + return (chat->amCreator() || allowByAdminRights(right, chat)) + ? Result::Allowed() + : (chat->defaultRestrictions() & right) + ? Result::WithEveryone() + : Result::Allowed(); } - return false; + return Result::Allowed(); } + +namespace Data { + +std::optional RestrictionErrorKey( + not_null peer, + ChatRestriction restriction) { + using Flag = ChatRestriction; + if (const auto restricted = peer->amRestricted(restriction)) { + const auto all = restricted.isWithEveryone(); + switch (restriction) { + case Flag::f_send_polls: + return all + ? lng_restricted_send_polls_all + : lng_restricted_send_polls; + case Flag::f_send_messages: + return all + ? lng_restricted_send_message_all + : lng_restricted_send_message; + case Flag::f_send_media: + return all + ? lng_restricted_send_media_all + : lng_restricted_send_media; + case Flag::f_send_stickers: + return all + ? lng_restricted_send_stickers_all + : lng_restricted_send_stickers; + case Flag::f_send_gifs: + return all + ? lng_restricted_send_gifs_all + : lng_restricted_send_gifs; + case Flag::f_send_inline: + case Flag::f_send_games: + return all + ? lng_restricted_send_inline_all + : lng_restricted_send_inline; + } + Unexpected("Restriction in Data::RestrictionErrorKey."); + } + return std::nullopt; +} + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 33cab96086..dae4b7e547 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_flags.h" #include "data/data_notify_settings.h" +enum LangKey : int; + namespace Ui { class EmptyUserpic; } // namespace Ui @@ -37,6 +39,51 @@ using ChatRestriction = MTPDchatBannedRights::Flag; using ChatAdminRights = MTPDchatAdminRights::Flags; using ChatRestrictions = MTPDchatBannedRights::Flags; +namespace Data { + +class RestrictionCheckResult { +public: + [[nodiscard]] static RestrictionCheckResult Allowed() { + return { 0 }; + } + [[nodiscard]] static RestrictionCheckResult WithEveryone() { + return { 1 }; + } + [[nodiscard]] static RestrictionCheckResult Explicit() { + return { 2 }; + } + + explicit operator bool() const { + return (_value != 0); + } + + bool operator==(const RestrictionCheckResult &other) const { + return (_value == other._value); + } + bool operator!=(const RestrictionCheckResult &other) const { + return !(*this == other); + } + + [[nodiscard]] bool isAllowed() const { + return (*this == Allowed()); + } + [[nodiscard]] bool isWithEveryone() const { + return (*this == WithEveryone()); + } + [[nodiscard]] bool isExplicit() const { + return (*this == Explicit()); + } + +private: + RestrictionCheckResult(int value) : _value(value) { + } + + int _value = 0; + +}; + +} // namespace Data + class PeerClickHandler : public ClickHandler { public: PeerClickHandler(not_null peer); @@ -100,7 +147,8 @@ public: } [[nodiscard]] bool canWrite() const; - [[nodiscard]] bool amRestricted(ChatRestriction right) const; + [[nodiscard]] Data::RestrictionCheckResult amRestricted( + ChatRestriction right) const; [[nodiscard]] UserData *asUser(); [[nodiscard]] const UserData *asUser() const; @@ -275,3 +323,11 @@ private: QString _about; }; + +namespace Data { + +std::optional RestrictionErrorKey( + not_null peer, + ChatRestriction restriction); + +} // namespace Data diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 503f7506a2..b539e8e498 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -1047,16 +1047,23 @@ void History::applyServiceChanges( } break; case mtpc_messageActionChatMigrateTo: { - if (auto chat = peer->asChat()) { + if (const auto chat = peer->asChat()) { chat->addFlags(MTPDchat::Flag::f_deactivated); + const auto &d = action.c_messageActionChatMigrateTo(); + if (const auto channel = App::channelLoaded(d.vchannel_id.v)) { + Data::ApplyMigration(chat, channel); + } } - //auto &d = action.c_messageActionChatMigrateTo(); - //auto channel = App::channelLoaded(d.vchannel_id.v); } break; case mtpc_messageActionChannelMigrateFrom: { - //auto &d = action.c_messageActionChannelMigrateFrom(); - //auto chat = App::chatLoaded(d.vchat_id.v); + if (const auto channel = peer->asChannel()) { + channel->addFlags(MTPDchannel::Flag::f_megagroup); + const auto &d = action.c_messageActionChannelMigrateFrom(); + if (const auto chat = App::chatLoaded(d.vchat_id.v)) { + Data::ApplyMigration(chat, channel); + } + } } break; case mtpc_messageActionPinMessage: { diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 37f29b1350..84a2b53217 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -262,11 +262,12 @@ QString GetErrorTextForForward( } } } - if (peer->amRestricted(ChatRestriction::f_send_inline) - && HasInlineItems(items)) { - return lang(lng_restricted_send_inline); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_inline); + return (errorKey && HasInlineItems(items)) + ? lang(*errorKey) + : QString(); } struct HistoryMessage::CreateConfig { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 8b9b3ed73b..7931cb5c5d 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -1916,8 +1916,10 @@ bool HistoryWidget::canWriteMessage() const { return true; } -bool HistoryWidget::isRestrictedWrite() const { - return _peer && _peer->amRestricted(ChatRestriction::f_send_messages); +std::optional HistoryWidget::writeRestrictionKey() const { + return _peer + ? Data::RestrictionErrorKey(_peer, ChatRestriction::f_send_messages) + : std::nullopt; } void HistoryWidget::updateControlsVisibility() { @@ -3015,8 +3017,10 @@ void HistoryWidget::step_recording(float64 ms, bool timer) { void HistoryWidget::chooseAttach() { if (!_peer || !_peer->canWrite()) { return; - } else if (_peer->amRestricted(ChatRestriction::f_send_media)) { - Ui::show(Box(lang(lng_restricted_send_media))); + } else if (const auto key = Data::RestrictionErrorKey( + _peer, + ChatRestriction::f_send_media)) { + Ui::show(Box(lang(*key))); return; } @@ -3120,8 +3124,11 @@ void HistoryWidget::leaveToChildEvent(QEvent *e, QWidget *child) { // e -- from } void HistoryWidget::recordStartCallback() { - if (_peer && _peer->amRestricted(ChatRestriction::f_send_media)) { - Ui::show(Box(lang(lng_restricted_send_media))); + const auto errorKey = _peer + ? Data::RestrictionErrorKey(_peer, ChatRestriction::f_send_media) + : std::nullopt; + if (errorKey) { + Ui::show(Box(lang(*errorKey))); return; } else if (!Media::Capture::instance()->available()) { return; @@ -3915,8 +3922,13 @@ void HistoryWidget::updateFieldPlaceholder() { bool HistoryWidget::showSendingFilesError( const Storage::PreparedList &list) const { const auto text = [&] { - if (_peer && _peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); + const auto errorKey = _peer + ? Data::RestrictionErrorKey( + _peer, + ChatRestriction::f_send_media) + : std::nullopt; + if (errorKey) { + return lang(*errorKey); } else if (!canWriteMessage()) { return lang(lng_forward_send_files_cant); } @@ -4745,7 +4757,7 @@ void HistoryWidget::updateHistoryGeometry(bool initial, bool loadedDown, const S } else { if (editingMessage() || _canSendMessages) { newScrollHeight -= (_field->height() + 2 * st::historySendPadding); - } else if (isRestrictedWrite()) { + } else if (writeRestrictionKey().has_value()) { newScrollHeight -= _unblock->height(); } if (_editMsgId || replyToId() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) { @@ -5380,10 +5392,11 @@ void HistoryWidget::destroyPinnedBar() { bool HistoryWidget::sendExistingDocument( not_null document, TextWithEntities caption) { - if (_peer && _peer->amRestricted(ChatRestriction::f_send_stickers)) { - Ui::show( - Box(lang(lng_restricted_send_stickers)), - LayerOption::KeepOther); + const auto errorKey = _peer + ? Data::RestrictionErrorKey(_peer, ChatRestriction::f_send_stickers) + : std::nullopt; + if (errorKey) { + Ui::show(Box(lang(*errorKey)), LayerOption::KeepOther); return false; } else if (!_peer || !_peer->canWrite()) { return false; @@ -5414,10 +5427,11 @@ bool HistoryWidget::sendExistingDocument( bool HistoryWidget::sendExistingPhoto( not_null photo, TextWithEntities caption) { - if (_peer && _peer->amRestricted(ChatRestriction::f_send_media)) { - Ui::show( - Box(lang(lng_restricted_send_media)), - LayerOption::KeepOther); + const auto errorKey = _peer + ? Data::RestrictionErrorKey(_peer, ChatRestriction::f_send_media) + : std::nullopt; + if (errorKey) { + Ui::show(Box(lang(*errorKey)), LayerOption::KeepOther); return false; } else if (!_peer || !_peer->canWrite()) { return false; @@ -5858,10 +5872,10 @@ void HistoryWidget::previewCancel() { } void HistoryWidget::checkPreview() { - auto previewRestricted = [this] { + const auto previewRestricted = [&] { return _peer && _peer->amRestricted(ChatRestriction::f_embed_links); - }; - if (_previewCancelled || previewRestricted()) { + }(); + if (_previewCancelled || previewRestricted) { previewCancel(); return; } @@ -6399,13 +6413,13 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { } } -void HistoryWidget::drawRestrictedWrite(Painter &p) { +void HistoryWidget::drawRestrictedWrite(Painter &p, const QString &error) { auto rect = myrtlrect(0, height() - _unblock->height(), width(), _unblock->height()); p.fillRect(rect, st::historyReplyBg); p.setFont(st::normalFont); p.setPen(st::windowSubTextFg); - p.drawText(rect.marginsRemoved(QMargins(st::historySendPadding, 0, st::historySendPadding, 0)), lang(lng_restricted_send_message), style::al_center); + p.drawText(rect.marginsRemoved(QMargins(st::historySendPadding, 0, st::historySendPadding, 0)), error, style::al_center); } void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const { @@ -6560,8 +6574,8 @@ void HistoryWidget::paintEvent(QPaintEvent *e) { if (!_send->isHidden() && _recording) { drawRecording(p, _send->recordActiveRatio()); } - } else if (isRestrictedWrite()) { - drawRestrictedWrite(p); + } else if (const auto errorKey = writeRestrictionKey()) { + drawRestrictedWrite(p, lang(*errorKey)); } if (_aboutProxyPromotion) { p.fillRect(_aboutProxyPromotion->geometry(), st::historyReplyBg); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index d4b46a571e..7f890b755b 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -23,6 +23,7 @@ struct SendingAlbum; enum class SendMediaType; enum class CompressConfirm; class MessageLinksParser; +enum LangKey : int; namespace InlineBots { namespace Layout { @@ -472,7 +473,7 @@ private: void checkTabbedSelectorToggleTooltip(); bool canWriteMessage() const; - bool isRestrictedWrite() const; + std::optional writeRestrictionKey() const; void orderWidgets(); void clearInlineBot(); @@ -543,10 +544,14 @@ private: not_null bot); void drawField(Painter &p, const QRect &rect); - void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const; + void paintEditHeader( + Painter &p, + const QRect &rect, + int left, + int top) const; void drawRecording(Painter &p, float64 recordActive); void drawPinnedBar(Painter &p); - void drawRestrictedWrite(Painter &p); + void drawRestrictedWrite(Painter &p, const QString &error); bool paintShowAnimationFrame(TimeMs ms); void updateMouseTracking(); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp index a82c04f309..0686ad0d62 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp @@ -64,10 +64,10 @@ void SendDataCommon::addToHistory( QString SendDataCommon::getErrorOnSend( const Result *owner, not_null history) const { - if (history->peer->amRestricted(ChatRestriction::f_send_messages)) { - return lang(lng_restricted_send_message); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_messages); + return errorKey ? lang(*errorKey) : QString(); } SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const { @@ -144,10 +144,10 @@ void SendPhoto::addToHistory( QString SendPhoto::getErrorOnSend( const Result *owner, not_null history) const { - if (history->peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_media); + return errorKey ? lang(*errorKey) : QString(); } void SendFile::addToHistory( @@ -177,17 +177,24 @@ void SendFile::addToHistory( QString SendFile::getErrorOnSend( const Result *owner, not_null history) const { - if (history->peer->amRestricted(ChatRestriction::f_send_media)) { - return lang(lng_restricted_send_media); - } else if (history->peer->amRestricted(ChatRestriction::f_send_stickers) - && (_document->sticker() != nullptr)) { - return lang(lng_restricted_send_stickers); - } else if (history->peer->amRestricted(ChatRestriction::f_send_gifs) - && _document->isAnimation() - && !_document->isVideoMessage()) { - return lang(lng_restricted_send_gifs); - } - return QString(); + const auto errorMedia = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_media); + const auto errorStickers = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_stickers); + const auto errorGifs = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_gifs); + return errorMedia + ? lang(*errorMedia) + : (errorStickers && (_document->sticker() != nullptr)) + ? lang(*errorStickers) + : (errorGifs + && _document->isAnimation() + && !_document->isVideoMessage()) + ? lang(*errorGifs) + : QString(); } void SendGame::addToHistory( @@ -216,10 +223,10 @@ void SendGame::addToHistory( QString SendGame::getErrorOnSend( const Result *owner, not_null history) const { - if (history->peer->amRestricted(ChatRestriction::f_send_games)) { - return lang(lng_restricted_send_inline); - } - return QString(); + const auto errorKey = Data::RestrictionErrorKey( + history->peer, + ChatRestriction::f_send_games); + return errorKey ? lang(*errorKey) : QString(); } } // namespace internal diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index 225f49913a..acf8f438d3 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -81,9 +81,12 @@ void Inner::visibleTopBottomUpdated( void Inner::checkRestrictedPeer() { if (_inlineQueryPeer) { - if (_inlineQueryPeer->amRestricted(ChatRestriction::f_send_inline)) { + const auto errorKey = Data::RestrictionErrorKey( + _inlineQueryPeer, + ChatRestriction::f_send_inline); + if (errorKey) { if (!_restrictedLabel) { - _restrictedLabel.create(this, lang(lng_restricted_send_inline), Ui::FlatLabel::InitType::Simple, st::stickersRestrictedLabel); + _restrictedLabel.create(this, lang(*errorKey), Ui::FlatLabel::InitType::Simple, st::stickersRestrictedLabel); _restrictedLabel->show(); _restrictedLabel->move(st::inlineResultsLeft - st::buttonRadius, st::stickerPanPadding); if (_switchPmButton) { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 5718966f0c..03689a6192 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -565,8 +565,10 @@ bool MainWidget::sendPaths(PeerId peerId) { if (!peer->canWrite()) { Ui::show(Box(lang(lng_forward_send_files_cant))); return false; - } else if (peer->amRestricted(ChatRestriction::f_send_media)) { - Ui::show(Box(lang(lng_restricted_send_media))); + } else if (const auto key = Data::RestrictionErrorKey( + peer, + ChatRestriction::f_send_media)) { + Ui::show(Box(lang(*key))); return false; } Ui::showPeerHistory(peer, ShowAtTheEndMsgId);