From baca36e71516d534f426a7be35f762f800a00e83 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 23 Dec 2021 19:48:36 +0300 Subject: [PATCH] Added chat invites support to sponsored messages. --- .../data/data_sponsored_messages.cpp | 72 ++++++++++++++----- .../data/data_sponsored_messages.h | 7 +- .../history/view/history_view_element.cpp | 14 +++- .../history/view/history_view_view_button.cpp | 10 ++- 4 files changed, 79 insertions(+), 24 deletions(-) diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.cpp b/Telegram/SourceFiles/data/data_sponsored_messages.cpp index 0503b47160..6ef4681919 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.cpp +++ b/Telegram/SourceFiles/data/data_sponsored_messages.cpp @@ -157,22 +157,53 @@ void SponsoredMessages::append( not_null history, List &list, const MTPSponsoredMessage &message) { - message.match([&](const MTPDsponsoredMessage &data) { - const auto randomId = data.vrandom_id().v; - auto sharedMessage = SponsoredMessage{ - .randomId = randomId, - .fromId = peerFromMTP(*data.vfrom_id()), // #TODO ads - .textWithEntities = { - .text = qs(data.vmessage()), - .entities = Api::EntitiesFromMTP( - _session, - data.ventities().value_or_empty()), - }, - .history = history, - .msgId = data.vchannel_post().value_or_empty(), - }; - list.entries.push_back({ nullptr, std::move(sharedMessage) }); + const auto &data = message.match([]( + const auto &data) -> const MTPDsponsoredMessage& { + return data; }); + const auto randomId = data.vrandom_id().v; + const auto hash = qs(data.vchat_invite_hash().value_or_empty()); + const auto fromId = [&] { + if (data.vfrom_id()) { + return peerFromMTP(*data.vfrom_id()); + } + Assert(data.vchat_invite()); + return data.vchat_invite()->match([](const MTPDchatInvite &data) { + return Data::FakePeerIdForJustName(qs(data.vtitle())); + }, [&](const MTPDchatInviteAlready &data) { + const auto chat = _session->data().processChat(data.vchat()); + if (!chat) { + return PeerId(0); + } + if (const auto channel = chat->asChannel()) { + channel->clearInvitePeek(); + } + return chat->id; + }, [&](const MTPDchatInvitePeek &data) { + const auto chat = _session->data().processChat(data.vchat()); + if (!chat) { + return PeerId(0); + } + if (const auto channel = chat->asChannel()) { + channel->setInvitePeek(hash, data.vexpires().v); + } + return chat->id; + }); + }(); + auto sharedMessage = SponsoredMessage{ + .randomId = randomId, + .fromId = fromId, + .textWithEntities = { + .text = qs(data.vmessage()), + .entities = Api::EntitiesFromMTP( + _session, + data.ventities().value_or_empty()), + }, + .history = history, + .msgId = data.vchannel_post().value_or_empty(), + .chatInviteHash = hash, + }; + list.entries.push_back({ nullptr, std::move(sharedMessage) }); } void SponsoredMessages::clearItems(not_null history) { @@ -232,13 +263,18 @@ void SponsoredMessages::view(const FullMsgId &fullId) { }).send(); } -MsgId SponsoredMessages::channelPost(const FullMsgId &fullId) const { +SponsoredMessages::ChannelPost SponsoredMessages::channelPost( + const FullMsgId &fullId) const { const auto entryPtr = find(fullId); if (!entryPtr) { - return ShowAtUnreadMsgId; + return { .msgId = ShowAtUnreadMsgId, .hash = std::nullopt }; } const auto msgId = entryPtr->sponsored.msgId; - return msgId ? msgId : ShowAtUnreadMsgId; + const auto hash = entryPtr->sponsored.chatInviteHash; + return { + .msgId = msgId ? msgId : ShowAtUnreadMsgId, + .hash = hash.isEmpty() ? std::nullopt : std::make_optional(hash), + }; } } // namespace Data diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.h b/Telegram/SourceFiles/data/data_sponsored_messages.h index ab779190a0..90c2a4ef0f 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.h +++ b/Telegram/SourceFiles/data/data_sponsored_messages.h @@ -26,10 +26,15 @@ struct SponsoredMessage final { TextWithEntities textWithEntities; History *history = nullptr; MsgId msgId; + QString chatInviteHash; }; class SponsoredMessages final { public: + struct ChannelPost { + MsgId msgId; + std::optional hash; + }; using RandomId = QByteArray; explicit SponsoredMessages(not_null owner); SponsoredMessages(const SponsoredMessages &other) = delete; @@ -40,7 +45,7 @@ public: void request(not_null history); [[nodiscard]] bool append(not_null history); void clearItems(not_null history); - [[nodiscard]] MsgId channelPost(const FullMsgId &fullId) const; + [[nodiscard]] ChannelPost channelPost(const FullMsgId &fullId) const; void view(const FullMsgId &fullId); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index df770e01e9..875ff1806e 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_element.h" +#include "api/api_chat_invite.h" #include "history/view/history_view_service_message.h" #include "history/view/history_view_message.h" #include "history/history_item_components.h" @@ -33,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_groups.h" #include "data/data_media_types.h" +#include "data/data_sponsored_messages.h" #include "lang/lang_keys.h" #include "app.h" #include "styles/style_chat.h" @@ -598,11 +600,11 @@ ClickHandlerPtr Element::fromLink() const { return; } const auto my = context.other.value(); + const auto session = &from->session(); const auto window = [&]() -> Window::SessionController* { if (const auto controller = my.sessionWindow.get()) { return controller; } - const auto session = &from->session(); const auto &windows = session->windows(); if (windows.empty()) { session->domain().activate(&session->account()); @@ -613,7 +615,15 @@ ClickHandlerPtr Element::fromLink() const { return windows.front(); }(); if (window) { - window->showPeerInfo(from); + const auto inviteHash = item->isSponsored() + ? session->data().sponsoredMessages().channelPost( + my.itemId).hash + : std::nullopt; + if (inviteHash) { + Api::CheckChatInvite(window, *inviteHash); + } else { + window->showPeerInfo(from); + } } }); _fromLink->setProperty(kPeerLinkPeerIdProperty, from->id.value); diff --git a/Telegram/SourceFiles/history/view/history_view_view_button.cpp b/Telegram/SourceFiles/history/view/history_view_view_button.cpp index 96cb8b4949..3fd4f8a42f 100644 --- a/Telegram/SourceFiles/history/view/history_view_view_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_view_button.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_view_button.h" +#include "api/api_chat_invite.h" #include "core/application.h" #include "core/click_handler_types.h" #include "data/data_cloud_themes.h" @@ -119,9 +120,12 @@ ViewButton::Inner::Inner(not_null peer, Fn updateCallback) const auto my = context.other.value(); if (const auto controller = my.sessionWindow.get()) { const auto &data = controller->session().data(); - controller->showPeer( - peer, - data.sponsoredMessages().channelPost(my.itemId)); + const auto link = data.sponsoredMessages().channelPost(my.itemId); + if (link.hash) { + Api::CheckChatInvite(controller, *link.hash); + } else { + controller->showPeer(peer, link.msgId); + } } })) , updateCallback(std::move(updateCallback))