Added chat invites support to sponsored messages.

This commit is contained in:
23rd 2021-12-23 19:48:36 +03:00 committed by John Preston
parent 4252066cf6
commit baca36e715
4 changed files with 79 additions and 24 deletions

View File

@ -157,22 +157,53 @@ void SponsoredMessages::append(
not_null<History*> history, not_null<History*> history,
List &list, List &list,
const MTPSponsoredMessage &message) { const MTPSponsoredMessage &message) {
message.match([&](const MTPDsponsoredMessage &data) { const auto &data = message.match([](
const auto randomId = data.vrandom_id().v; const auto &data) -> const MTPDsponsoredMessage& {
auto sharedMessage = SponsoredMessage{ return data;
.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 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*> history) { void SponsoredMessages::clearItems(not_null<History*> history) {
@ -232,13 +263,18 @@ void SponsoredMessages::view(const FullMsgId &fullId) {
}).send(); }).send();
} }
MsgId SponsoredMessages::channelPost(const FullMsgId &fullId) const { SponsoredMessages::ChannelPost SponsoredMessages::channelPost(
const FullMsgId &fullId) const {
const auto entryPtr = find(fullId); const auto entryPtr = find(fullId);
if (!entryPtr) { if (!entryPtr) {
return ShowAtUnreadMsgId; return { .msgId = ShowAtUnreadMsgId, .hash = std::nullopt };
} }
const auto msgId = entryPtr->sponsored.msgId; 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 } // namespace Data

View File

@ -26,10 +26,15 @@ struct SponsoredMessage final {
TextWithEntities textWithEntities; TextWithEntities textWithEntities;
History *history = nullptr; History *history = nullptr;
MsgId msgId; MsgId msgId;
QString chatInviteHash;
}; };
class SponsoredMessages final { class SponsoredMessages final {
public: public:
struct ChannelPost {
MsgId msgId;
std::optional<QString> hash;
};
using RandomId = QByteArray; using RandomId = QByteArray;
explicit SponsoredMessages(not_null<Session*> owner); explicit SponsoredMessages(not_null<Session*> owner);
SponsoredMessages(const SponsoredMessages &other) = delete; SponsoredMessages(const SponsoredMessages &other) = delete;
@ -40,7 +45,7 @@ public:
void request(not_null<History*> history); void request(not_null<History*> history);
[[nodiscard]] bool append(not_null<History*> history); [[nodiscard]] bool append(not_null<History*> history);
void clearItems(not_null<History*> history); void clearItems(not_null<History*> history);
[[nodiscard]] MsgId channelPost(const FullMsgId &fullId) const; [[nodiscard]] ChannelPost channelPost(const FullMsgId &fullId) const;
void view(const FullMsgId &fullId); void view(const FullMsgId &fullId);

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "history/view/history_view_element.h" #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_service_message.h"
#include "history/view/history_view_message.h" #include "history/view/history_view_message.h"
#include "history/history_item_components.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_session.h"
#include "data/data_groups.h" #include "data/data_groups.h"
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_sponsored_messages.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "app.h" #include "app.h"
#include "styles/style_chat.h" #include "styles/style_chat.h"
@ -598,11 +600,11 @@ ClickHandlerPtr Element::fromLink() const {
return; return;
} }
const auto my = context.other.value<ClickHandlerContext>(); const auto my = context.other.value<ClickHandlerContext>();
const auto session = &from->session();
const auto window = [&]() -> Window::SessionController* { const auto window = [&]() -> Window::SessionController* {
if (const auto controller = my.sessionWindow.get()) { if (const auto controller = my.sessionWindow.get()) {
return controller; return controller;
} }
const auto session = &from->session();
const auto &windows = session->windows(); const auto &windows = session->windows();
if (windows.empty()) { if (windows.empty()) {
session->domain().activate(&session->account()); session->domain().activate(&session->account());
@ -613,7 +615,15 @@ ClickHandlerPtr Element::fromLink() const {
return windows.front(); return windows.front();
}(); }();
if (window) { 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); _fromLink->setProperty(kPeerLinkPeerIdProperty, from->id.value);

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "history/view/history_view_view_button.h" #include "history/view/history_view_view_button.h"
#include "api/api_chat_invite.h"
#include "core/application.h" #include "core/application.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/data_cloud_themes.h" #include "data/data_cloud_themes.h"
@ -119,9 +120,12 @@ ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
const auto my = context.other.value<ClickHandlerContext>(); const auto my = context.other.value<ClickHandlerContext>();
if (const auto controller = my.sessionWindow.get()) { if (const auto controller = my.sessionWindow.get()) {
const auto &data = controller->session().data(); const auto &data = controller->session().data();
controller->showPeer( const auto link = data.sponsoredMessages().channelPost(my.itemId);
peer, if (link.hash) {
data.sponsoredMessages().channelPost(my.itemId)); Api::CheckChatInvite(controller, *link.hash);
} else {
controller->showPeer(peer, link.msgId);
}
} }
})) }))
, updateCallback(std::move(updateCallback)) , updateCallback(std::move(updateCallback))