Added api support for clicks on sponsored messages with media.

This commit is contained in:
23rd 2024-09-17 17:41:52 +03:00 committed by John Preston
parent a2fad84dae
commit 3f6d184435
8 changed files with 64 additions and 28 deletions

View file

@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "core/sandbox.h"
#include "core/click_handler_types.h"
#include "data/components/sponsored_messages.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_session.h"
#include "iv/iv_instance.h"
@ -296,16 +295,6 @@ Fn<void()> UiIntegration::createSpoilerRepaint(const std::any &context) {
return my ? my->customEmojiRepaint : nullptr;
}
bool UiIntegration::allowClickHandlerActivation(
const std::shared_ptr<ClickHandler> &handler,
const ClickContext &context) {
const auto my = context.other.value<ClickHandlerContext>();
if (const auto window = my.sessionWindow.get()) {
window->session().sponsoredMessages().clicked(my.itemId);
}
return true;
}
rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
return Core::App().passcodeLockChanges() | rpl::to_empty;
}

View file

@ -61,9 +61,6 @@ public:
QStringView data,
const std::any &context) override;
Fn<void()> createSpoilerRepaint(const std::any &context) override;
bool allowClickHandlerActivation(
const std::shared_ptr<ClickHandler> &handler,
const ClickContext &context) override;
QString phraseContextCopyText() override;
QString phraseContextCopyEmail() override;

View file

@ -433,7 +433,10 @@ SponsoredMessages::Details SponsoredMessages::lookupDetails(
};
}
void SponsoredMessages::clicked(const FullMsgId &fullId) {
void SponsoredMessages::clicked(
const FullMsgId &fullId,
bool isMedia,
bool isFullscreen) {
const auto entryPtr = find(fullId);
if (!entryPtr) {
return;
@ -443,7 +446,9 @@ void SponsoredMessages::clicked(const FullMsgId &fullId) {
Assert(channel != nullptr);
using Flag = MTPchannels_ClickSponsoredMessage::Flag;
_session->api().request(MTPchannels_ClickSponsoredMessage(
MTP_flags(Flag(0)),
MTP_flags(Flag(0)
| (isMedia ? Flag::f_media : Flag(0))
| (isFullscreen ? Flag::f_fullscreen : Flag(0))),
channel->inputChannel,
MTP_bytes(randomId)
)).send();

View file

@ -90,7 +90,7 @@ public:
void request(not_null<History*> history, Fn<void()> done);
void clearItems(not_null<History*> history);
[[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const;
void clicked(const FullMsgId &fullId);
void clicked(const FullMsgId &fullId, bool isMedia, bool isFullscreen);
[[nodiscard]] bool append(not_null<History*> history);
void inject(

View file

@ -689,7 +689,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
}
if (!unwrapped && !skipDrawingSurrounding) {
if (!isRound || !inWebPage) {
if ((!isRound || !inWebPage) && !_realParent->isSponsored()) {
drawCornerStatus(p, context, QPoint());
}
} else if (!skipDrawingSurrounding) {

View file

@ -297,9 +297,10 @@ void WebPage::setupAdditionalData() {
if (_flags & MediaWebPageFlag::Sponsored) {
_additionalData = std::make_unique<AdditionalData>(SponsoredData());
const auto raw = sponsoredData();
const auto &session = _parent->data()->history()->session();
const auto details = session.sponsoredMessages().lookupDetails(
_parent->data()->fullId());
const auto session = &_data->session();
const auto id = _parent->data()->fullId();
const auto details = session->sponsoredMessages().lookupDetails(id);
const auto link = details.link;
raw->buttonText = details.buttonText;
raw->isLinkInternal = details.isLinkInternal ? 1 : 0;
raw->backgroundEmojiId = details.backgroundEmojiId;
@ -308,12 +309,16 @@ void WebPage::setupAdditionalData() {
raw->hasMedia = (details.mediaPhotoId || details.mediaDocumentId)
? 1
: 0;
raw->link = std::make_shared<LambdaClickHandler>([=] {
session->sponsoredMessages().clicked(id, false, false);
UrlClickHandler::Open(link);
});
if (!_attach) {
const auto maybePhoto = details.mediaPhotoId
? _data->session().data().photo(details.mediaPhotoId).get()
? session->data().photo(details.mediaPhotoId).get()
: nullptr;
const auto maybeDocument = details.mediaDocumentId
? _data->session().data().document(
? session->data().document(
details.mediaDocumentId).get()
: nullptr;
_attach = CreateAttach(
@ -323,6 +328,25 @@ void WebPage::setupAdditionalData() {
_collage,
_data->url);
}
if (_attach) {
if (_attach->getPhoto()) {
raw->mediaLink = std::make_shared<LambdaClickHandler>([=] {
session->sponsoredMessages().clicked(id, true, false);
UrlClickHandler::Open(link);
});
} else if (const auto document = _attach->getDocument()) {
const auto delegate = _parent->delegate();
raw->mediaLink = document->isVideoFile()
? std::make_shared<LambdaClickHandler>([=] {
session->sponsoredMessages().clicked(id, true, false);
delegate->elementOpenDocument(document, id, true);
})
: std::make_shared<LambdaClickHandler>([=] {
session->sponsoredMessages().clicked(id, true, false);
UrlClickHandler::Open(link);
});
}
}
} else if (_data->stickerSet) {
_additionalData = std::make_unique<AdditionalData>(StickerSetData());
const auto raw = stickerSetData();
@ -1339,6 +1363,7 @@ TextState WebPage::textState(QPoint point, StateRequest request) const {
}
tshift += descriptionHeight;
}
auto isWithinSponsoredMedia = false;
if (inThumb) {
result.link = _openl;
} else if (_attach) {
@ -1373,6 +1398,7 @@ TextState WebPage::textState(QPoint point, StateRequest request) const {
point - QPoint(attachLeft, attachTop),
request);
if (hasSponsoredMedia) {
isWithinSponsoredMedia = true;
} else if (result.cursor == CursorState::Enlarge) {
result.cursor = CursorState::None;
} else {
@ -1383,8 +1409,12 @@ TextState WebPage::textState(QPoint point, StateRequest request) const {
tshift += _attach->height();
}
}
if ((!result.link || (sponsored && !hasSponsoredMedia))
&& outer.contains(point)) {
if (isWithinSponsoredMedia) {
result.link = sponsored->mediaLink;
} else if (sponsored && outer.contains(point)) {
result.link = sponsored->link;
}
if (!result.link && outer.contains(point)) {
result.link = _openl;
}
if (const auto hint = hintData()) {

View file

@ -122,6 +122,8 @@ private:
std::vector<std::unique_ptr<Sticker>> views;
};
struct SponsoredData {
ClickHandlerPtr link;
ClickHandlerPtr mediaLink;
QString buttonText;
uint64 backgroundEmojiId = 0;

View file

@ -3715,14 +3715,16 @@ void OverlayWidget::initSponsoredButton() {
} else if (!has && !_sponsoredButton) {
return;
}
const auto &component = _session->sponsoredMessages();
const auto details = component.lookupDetails(_message->fullId());
const auto sponsoredMessages = &_session->sponsoredMessages();
const auto fullId = _message->fullId();
const auto details = sponsoredMessages->lookupDetails(fullId);
_sponsoredButton = base::make_unique_q<SponsoredButton>(_body);
_sponsoredButton->setText(details.buttonText);
_sponsoredButton->setOpacity(1.0);
_sponsoredButton->setClickedCallback([=, link = details.link] {
UrlClickHandler::Open(link);
sponsoredMessages->clicked(fullId, false, true);
hide();
});
}
@ -6020,7 +6022,18 @@ void OverlayWidget::handleMouseRelease(
if (_stories) {
_stories->contentPressed(false);
} else if (_streamed && !_window->mousePressCancelled()) {
playbackPauseResume();
if (_sponsoredButton && _session && _message) {
const auto sponsoredMessages = &_session->sponsoredMessages();
const auto fullId = _message->fullId();
const auto details = sponsoredMessages->lookupDetails(fullId);
if (const auto link = details.link; !link.isEmpty()) {
UrlClickHandler::Open(link);
sponsoredMessages->clicked(fullId, true, true);
hide();
}
} else {
playbackPauseResume();
}
}
} else if (_pressed) {
if (_dragging) {