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/application.h"
#include "core/sandbox.h" #include "core/sandbox.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/components/sponsored_messages.h"
#include "data/stickers/data_custom_emoji.h" #include "data/stickers/data_custom_emoji.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "iv/iv_instance.h" #include "iv/iv_instance.h"
@ -296,16 +295,6 @@ Fn<void()> UiIntegration::createSpoilerRepaint(const std::any &context) {
return my ? my->customEmojiRepaint : nullptr; 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() { rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
return Core::App().passcodeLockChanges() | rpl::to_empty; return Core::App().passcodeLockChanges() | rpl::to_empty;
} }

View file

@ -61,9 +61,6 @@ public:
QStringView data, QStringView data,
const std::any &context) override; const std::any &context) override;
Fn<void()> createSpoilerRepaint(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 phraseContextCopyText() override;
QString phraseContextCopyEmail() 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); const auto entryPtr = find(fullId);
if (!entryPtr) { if (!entryPtr) {
return; return;
@ -443,7 +446,9 @@ void SponsoredMessages::clicked(const FullMsgId &fullId) {
Assert(channel != nullptr); Assert(channel != nullptr);
using Flag = MTPchannels_ClickSponsoredMessage::Flag; using Flag = MTPchannels_ClickSponsoredMessage::Flag;
_session->api().request(MTPchannels_ClickSponsoredMessage( _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, channel->inputChannel,
MTP_bytes(randomId) MTP_bytes(randomId)
)).send(); )).send();

View file

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

View file

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

View file

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

View file

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

View file

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