diff --git a/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp b/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp index 86c41e28a..badb8b73e 100644 --- a/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.cpp @@ -57,41 +57,6 @@ private: }; -void ShareBotGame( - not_null bot, - not_null chat, - const QString &shortName) { - const auto history = chat->owner().history(chat); - auto &histories = history->owner().histories(); - const auto randomId = base::RandomValue(); - const auto replyTo = 0; - const auto topicRootId = 0; - histories.sendPreparedMessage( - history, - replyTo, - topicRootId, - randomId, - Data::Histories::PrepareMessage( - MTP_flags(0), - chat->input, - Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), - MTP_inputMediaGame( - MTP_inputGameShortName( - bot->inputUser, - MTP_string(shortName))), - MTP_string(), - MTP_long(randomId), - MTPReplyMarkup(), - MTPVector(), - MTP_int(0), // schedule_date - MTPInputPeer() // send_as - ), [=](const MTPUpdates &result, const MTP::Response &response) { - }, [=](const MTP::Error &error, const MTP::Response &response) { - chat->session().api().sendMessageFail(error, chat); - }); -} - Controller::Controller( not_null session, rpl::producer> add, @@ -165,9 +130,7 @@ AddBotToGroupBoxController::AddBotToGroupBoxController( Scope scope, const QString &token, ChatAdminRights requestedRights) -: ChatsListBoxController((scope == Scope::ShareGame) - ? std::make_unique(&bot->session()) - : nullptr) +: ChatsListBoxController(std::unique_ptr()) , _controller(controller) , _bot(bot) , _scope(scope) @@ -185,42 +148,7 @@ Main::Session &AddBotToGroupBoxController::session() const { } void AddBotToGroupBoxController::rowClicked(not_null row) { - if (sharingBotGame()) { - shareBotGame(row->peer()); - } else { - addBotToGroup(row->peer()); - } -} - -void AddBotToGroupBoxController::shareBotGame(not_null chat) { - auto send = crl::guard(this, [ - bot = _bot, - controller = _controller, - chat, - token = _token] { - ShareBotGame(bot, chat, token); - using Way = Window::SectionShow::Way; - controller->hideLayer(); - controller->showPeerHistory(chat, Way::ClearStack, ShowAtUnreadMsgId); - }); - auto confirmText = [chat] { - if (chat->isUser()) { - return tr::lng_bot_sure_share_game( - tr::now, - lt_user, - chat->name()); - } - return tr::lng_bot_sure_share_game_group( - tr::now, - lt_group, - chat->name()); - }(); - _controller->show( - Ui::MakeConfirmBox({ - .text = confirmText, - .confirmed = std::move(send), - }), - Ui::LayerOption::KeepOther); + addBotToGroup(row->peer()); } void AddBotToGroupBoxController::requestExistingRights( @@ -341,13 +269,6 @@ auto AddBotToGroupBoxController::createRow(not_null history) bool AddBotToGroupBoxController::needToCreateRow( not_null peer) const { - if (sharingBotGame()) { - if (!peer->canWrite() // #TODO forum forward - || peer->amRestricted(ChatRestriction::SendGames)) { - return false; - } - return true; - } if (const auto chat = peer->asChat()) { if (onlyAdminToGroup()) { return chat->canAddAdmins(); @@ -374,14 +295,10 @@ bool AddBotToGroupBoxController::needToCreateRow( return false; } -bool AddBotToGroupBoxController::sharingBotGame() const { - return (_scope == Scope::ShareGame); -} - QString AddBotToGroupBoxController::emptyBoxText() const { return !session().data().chatsListLoaded() ? tr::lng_contacts_loading(tr::now) - : (sharingBotGame() || _adminToChannel) + : _adminToChannel ? tr::lng_bot_no_chats(tr::now) : tr::lng_bot_no_groups(tr::now); } @@ -389,7 +306,7 @@ QString AddBotToGroupBoxController::emptyBoxText() const { QString AddBotToGroupBoxController::noResultsText() const { return !session().data().chatsListLoaded() ? tr::lng_contacts_loading(tr::now) - : (sharingBotGame() || _adminToChannel) + : _adminToChannel ? tr::lng_bot_chats_not_found(tr::now) : tr::lng_bot_groups_not_found(tr::now); } @@ -463,7 +380,7 @@ bool AddBotToGroupBoxController::onlyAdminToChannel() const { } void AddBotToGroupBoxController::prepareViewHook() { - delegate()->peerListSetTitle((sharingBotGame() || _adminToChannel) + delegate()->peerListSetTitle(_adminToChannel ? tr::lng_bot_choose_chat() : tr::lng_bot_choose_group()); if ((_adminToGroup && !onlyAdminToGroup()) diff --git a/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h b/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h index f048ee0bd..1a129a4d8 100644 --- a/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h +++ b/Telegram/SourceFiles/boxes/peers/add_bot_to_chat_box.h @@ -18,7 +18,6 @@ public: None, GroupAdmin, ChannelAdmin, - ShareGame, All, }; static void Start( @@ -50,11 +49,9 @@ private: [[nodiscard]] bool onlyAdminToChannel() const; bool needToCreateRow(not_null peer) const; - bool sharingBotGame() const; QString noResultsText() const; void updateLabels(); - void shareBotGame(not_null chat); void addBotToGroup(not_null chat); void requestExistingRights(not_null channel); diff --git a/Telegram/SourceFiles/data/data_histories.cpp b/Telegram/SourceFiles/data/data_histories.cpp index caace2997..0571723a3 100644 --- a/Telegram/SourceFiles/data/data_histories.cpp +++ b/Telegram/SourceFiles/data/data_histories.cpp @@ -850,7 +850,7 @@ void Histories::sendCreateTopicRequest( MsgId rootId) { Expects(history->peer->isChannel()); - const auto forum = history->peer->forum(); + const auto forum = history->asForum(); Assert(forum != nullptr); const auto topic = forum->topicFor(rootId); Assert(topic != nullptr); @@ -879,7 +879,7 @@ void Histories::sendCreateTopicRequest( bool Histories::isCreatingTopic( not_null history, MsgId rootId) const { - const auto forum = history->peer->forum(); + const auto forum = history->asForum(); return forum && forum->creating(rootId); } @@ -947,7 +947,7 @@ void Histories::checkTopicCreated(FullMsgId rootId, MsgId realRoot) { _createdTopicIds.emplace(rootId, realRoot); const auto history = _owner->history(rootId.peer); - if (const auto forum = history->peer->forum()) { + if (const auto forum = history->asForum()) { forum->created(rootId.msg, realRoot); } diff --git a/Telegram/SourceFiles/data/data_replies_list.cpp b/Telegram/SourceFiles/data/data_replies_list.cpp index 44160f132..ed9cbe324 100644 --- a/Telegram/SourceFiles/data/data_replies_list.cpp +++ b/Telegram/SourceFiles/data/data_replies_list.cpp @@ -42,7 +42,7 @@ constexpr auto kMaxMessagesToDeleteMyTopic = 10; } [[nodiscard]] bool IsCreating(not_null history, MsgId rootId) { - if (const auto forum = history->peer->forum()) { + if (const auto forum = history->asForum()) { return forum->creating(rootId); } return false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 45bcea5a3..20d705b63 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -97,7 +97,15 @@ Main::Session &Entry::session() const { } History *Entry::asHistory() { - return (_flags & Flag::IsHistory) ? static_cast(this) : nullptr; + return (_flags & Flag::IsHistory) + ? static_cast(this) + : nullptr; +} + +Data::Forum *Entry::asForum() { + return (_flags & Flag::IsHistory) + ? static_cast(this)->peer->forum() + : nullptr; } Data::Folder *Entry::asFolder() { @@ -122,6 +130,10 @@ const History *Entry::asHistory() const { return const_cast(this)->asHistory(); } +const Data::Forum *Entry::asForum() const { + return const_cast(this)->asForum(); +} + const Data::Folder *Entry::asFolder() const { return const_cast(this)->asFolder(); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 780f1dfff..0a3e70c5d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -22,6 +22,7 @@ class Session; namespace Data { class Session; +class Forum; class Folder; class ForumTopic; class CloudImageView; @@ -157,11 +158,13 @@ public: [[nodiscard]] Main::Session &session() const; History *asHistory(); + Data::Forum *asForum(); Data::Folder *asFolder(); Data::Thread *asThread(); Data::ForumTopic *asTopic(); const History *asHistory() const; + const Data::Forum *asForum() const; const Data::Folder *asFolder() const; const Data::Thread *asThread() const; const Data::ForumTopic *asTopic() const; diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index c61ac650b..a0fce172e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -365,7 +365,7 @@ void FakeRow::invalidateTopic() { if (_topic) { return; } else if (const auto rootId = _item->topicRootId()) { - if (const auto forum = _item->history()->peer->forum()) { + if (const auto forum = _item->history()->asForum()) { if (!forum->topicDeleted(rootId)) { forum->requestTopic(rootId, crl::guard(this, [=] { _topic = _item->topic(); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 907ffe34a..a00887234 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2085,7 +2085,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { const auto itemId = item->fullId(); const auto canReply = [&] { const auto peer = item->history()->peer; - if (const auto forum = item->history()->peer->forum()) { + if (const auto forum = peer->forum()) { const auto topicRootId = item->topicRootId(); const auto topic = item->topic(); return topic diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index ecc134344..87a663dc2 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -632,7 +632,7 @@ void HistoryItem::destroy() { not_null HistoryItem::notificationThread() const { if (const auto rootId = topicRootId()) { - if (const auto forum = _history->peer->forum()) { + if (const auto forum = _history->asForum()) { return forum->enforceTopicFor(rootId); } } @@ -641,7 +641,7 @@ not_null HistoryItem::notificationThread() const { Data::ForumTopic *HistoryItem::topic() const { if (const auto rootId = topicRootId()) { - if (const auto forum = _history->peer->forum()) { + if (const auto forum = _history->asForum()) { return forum->topicFor(rootId); } } diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 431194619..5ab67cd20 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -661,7 +661,7 @@ void HistoryMessage::createComponentsHelper( const auto to = LookupReplyTo(history(), replyTo); const auto replyToTop = LookupReplyToTop(to); config.replyToTop = replyToTop ? replyToTop : replyTo; - const auto forum = history()->peer->forum(); + const auto forum = history()->asForum(); config.replyIsTopicPost = LookupReplyIsTopicPost(to) || (to && to->Has()) || (forum && forum->creating(config.replyToTop)); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 74fb27ff8..d9d03600e 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -722,7 +722,7 @@ auto Element::contextDependentServiceText() -> TextWithLinks { return Ui::Text::Link(std::move(full), topicUrl); }; const auto wrapParentTopic = [&] { - const auto forum = history()->peer->forum(); + const auto forum = history()->asForum(); if (!forum || forum->topicDeleted(topicRootId)) { return wrapTopic( tr::lng_deleted_message(tr::now), diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 841f097c7..762943c5d 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -151,7 +151,7 @@ void RepliesMemento::setReadInformation( int unreadCount, MsgId outboxReadTillId) { if (!_replies) { - if (const auto forum = _history->peer->forum()) { + if (const auto forum = _history->asForum()) { if (const auto topic = forum->topicFor(_rootId)) { _replies = topic->replies(); } @@ -576,12 +576,12 @@ HistoryItem *RepliesWidget::lookupRoot() const { } Data::ForumTopic *RepliesWidget::lookupTopic() { - if (const auto forum = _history->peer->forum()) { + if (const auto forum = _history->asForum()) { if (const auto result = forum->topicFor(_rootId)) { return result; } else { forum->requestTopic(_rootId, crl::guard(this, [=] { - if (const auto forum = _history->peer->forum()) { + if (const auto forum = _history->asForum()) { setTopic(forum->topicFor(_rootId)); } })); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 6b105ba4b..c590bc8b1 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -626,8 +626,7 @@ bool MainWidget::sendPaths(not_null thread) { bool MainWidget::onFilesOrForwardDrop( not_null thread, not_null data) { - const auto history = thread->asHistory(); - if (const auto forum = history ? history->peer->forum() : nullptr) { + if (const auto forum = thread->asForum()) { Window::ShowDropMediaBox( _controller, Core::ShareMimeMediaData(data), diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 492303e11..db7880a96 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_chat_participants.h" #include "lang/lang_keys.h" #include "ui/boxes/confirm_box.h" +#include "base/random.h" #include "base/options.h" #include "base/unixtime.h" #include "boxes/delete_messages_box.h" @@ -86,6 +87,48 @@ namespace { constexpr auto kTopicsSearchMinCount = 1; +void ShareBotGame( + not_null bot, + not_null thread, + const QString &shortName) { + auto &histories = thread->owner().histories(); + const auto history = thread->owningHistory(); + const auto randomId = base::RandomValue(); + const auto replyTo = thread->topicRootId(); + const auto topicRootId = replyTo; + auto flags = MTPmessages_SendMedia::Flags(0); + if (replyTo) { + flags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; + if (topicRootId) { + flags |= MTPmessages_SendMedia::Flag::f_top_msg_id; + } + } + histories.sendPreparedMessage( + history, + replyTo, + topicRootId, + randomId, + Data::Histories::PrepareMessage( + MTP_flags(flags), + history->peer->input, + Data::Histories::ReplyToPlaceholder(), + Data::Histories::TopicRootPlaceholder(), + MTP_inputMediaGame( + MTP_inputGameShortName( + bot->inputUser, + MTP_string(shortName))), + MTP_string(), + MTP_long(randomId), + MTPReplyMarkup(), + MTPVector(), + MTP_int(0), // schedule_date + MTPInputPeer() // send_as + ), [=](const MTPUpdates &, const MTP::Response &) { + }, [=](const MTP::Error &error, const MTP::Response &) { + history->session().api().sendMessageFail(error, history->peer); + }); +} + } // namespace const char kOptionViewProfileInChatsListContextMenu[] = @@ -121,17 +164,15 @@ void MarkAsReadThread(not_null thread) { }; if (!IsUnreadThread(thread)) { return; + } else if (const auto forum = thread->asForum()) { + forum->enumerateTopics([]( + not_null topic) { + MarkAsReadThread(topic); + }); } else if (const auto history = thread->asHistory()) { - if (const auto forum = history->peer->forum()) { - forum->enumerateTopics([]( - not_null topic) { - MarkAsReadThread(topic); - }); - } else { - readHistory(history); - if (const auto migrated = history->migrateSibling()) { - readHistory(migrated); - } + readHistory(history); + if (const auto migrated = history->migrateSibling()) { + readHistory(migrated); } } else if (const auto topic = thread->asTopic()) { topic->readTillEnd(); @@ -1542,6 +1583,63 @@ QPointer ShowForwardMessagesBox( std::move(successCallback)); } +QPointer ShowShareGameBox( + not_null navigation, + not_null bot, + QString shortName) { + const auto weak = std::make_shared>(); + auto chosen = [=](not_null thread) mutable { + const auto confirm = std::make_shared>(); + auto send = crl::guard(thread, [=] { + ShareBotGame(bot, thread, shortName); + using Way = Window::SectionShow::Way; + if (const auto strong = *weak) { + strong->closeBox(); + } + if (const auto strong = *confirm) { + strong->closeBox(); + } + navigation->showThread( + thread, + ShowAtUnreadMsgId, + SectionShow::Way::ClearStack); + }); + const auto confirmText = thread->owningHistory()->peer->isUser() + ? tr::lng_bot_sure_share_game( + tr::now, + lt_user, + thread->chatListName()) + : tr::lng_bot_sure_share_game_group( + tr::now, + lt_group, + thread->chatListName()); + *confirm = navigation->parentController()->show( + Ui::MakeConfirmBox({ + .text = confirmText, + .confirmed = std::move(send), + }), + Ui::LayerOption::KeepOther); + }; + auto filter = [](not_null thread) { + const auto peer = thread->owningHistory()->peer; + return (thread->canWrite() || thread->asForum()) + && !peer->amRestricted(ChatRestriction::SendGames) + && !peer->isSelf(); + }; + auto initBox = [](not_null box) { + box->addButton(tr::lng_cancel(), [box] { + box->closeBox(); + }); + }; + *weak = navigation->parentController()->show(Box( + std::make_unique( + &navigation->session(), + std::move(chosen), + std::move(filter)), + std::move(initBox)), Ui::LayerOption::KeepOther); + return weak->data(); +} + QPointer ShowDropMediaBox( not_null navigation, std::shared_ptr data, diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index 08246c1c3..58a12f9c1 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -122,6 +122,10 @@ QPointer ShowForwardMessagesBox( not_null navigation, MessageIdsList &&items, FnMut &&successCallback = nullptr); +QPointer ShowShareGameBox( + not_null navigation, + not_null bot, + QString shortName); QPointer ShowDropMediaBox( not_null navigation, std::shared_ptr data, diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 03c69579e..ad6aabef5 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -81,6 +81,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/file_upload.h" #include "facades.h" #include "window/themes/window_theme.h" +#include "window/window_peer_menu.h" #include "settings/settings_main.h" #include "settings/settings_privacy_security.h" #include "styles/style_window.h" @@ -387,13 +388,12 @@ void SessionNavigation::showPeerByLinkResolved( info.messageId, callback); } + } else if (bot && info.resolveType == ResolveType::ShareGame) { + Window::ShowShareGameBox(parentController(), bot, info.startToken); } else if (bot && (info.resolveType == ResolveType::AddToGroup - || info.resolveType == ResolveType::AddToChannel - || info.resolveType == ResolveType::ShareGame)) { - const auto scope = (info.resolveType == ResolveType::ShareGame) - ? Scope::ShareGame - : (info.resolveType == ResolveType::AddToGroup) + || info.resolveType == ResolveType::AddToChannel)) { + const auto scope = (info.resolveType == ResolveType::AddToGroup) ? (info.startAdminRights ? Scope::GroupAdmin : Scope::All) : (info.resolveType == ResolveType::AddToChannel) ? Scope::ChannelAdmin