Added sub-button to top of sponsored messages that can be reported.

This commit is contained in:
23rd 2024-03-29 05:19:37 +03:00 committed by John Preston
parent 24c1151101
commit 8718d94e7d
6 changed files with 117 additions and 0 deletions

View file

@ -1960,6 +1960,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarded_imported" = "This message was imported from another app. It may not be real.";
"lng_signed_author" = "Author: {user}";
"lng_sponsored_message_title" = "Sponsored";
"lng_sponsored_message_revenue_button" = "what's this?";
"lng_recommended_message_title" = "Recommended";
"lng_edited" = "edited";
"lng_commented" = "commented";

View file

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media_common.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "menu/menu_sponsored.h"
#include "ui/chat/chat_style.h"
#include "ui/painter.h"
#include "ui/rect.h"
@ -136,6 +137,15 @@ constexpr auto kMaxOriginalEntryLines = 8192;
});
}
[[nodiscard]] ClickHandlerPtr AboutSponsoredClickHandler() {
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
const auto my = context.other.value<ClickHandlerContext>();
if (const auto controller = my.sessionWindow.get()) {
Menu::ShowSponsoredAbout(controller->uiShow());
}
});
}
[[nodiscard]] TextWithEntities PageToPhrase(not_null<WebPageData*> page) {
const auto type = page->type;
const auto text = Ui::Text::Upper(page->iv
@ -223,6 +233,7 @@ WebPage::WebPage(
auto result = std::make_optional<SponsoredData>();
result->buttonText = details.buttonText;
result->hasExternalLink = (details.externalLink == _data->url);
result->canReport = details.canReport;
#ifdef _DEBUG
if (details.peer) {
#else
@ -337,6 +348,10 @@ QSize WebPage::countOptimalSize() {
_openl = SponsoredLink(_sponsoredData->hasExternalLink
? _data->url
: QString());
if (_sponsoredData->canReport) {
_sponsoredData->hintLink = AboutSponsoredClickHandler();
}
}
}
@ -480,6 +495,16 @@ QSize WebPage::countOptimalSize() {
if (_asArticle) {
minHeight = resizeGetHeight(maxWidth);
}
if (_sponsoredData && _sponsoredData->canReport) {
_sponsoredData->widthBeforeHint =
st::webPageTitleStyle.font->width(siteName);
const auto &font = st::webPageSponsoredHintFont;
_sponsoredData->hintSize = QSize(
font->width(tr::lng_sponsored_message_revenue_button(tr::now))
+ font->height,
font->height);
maxWidth += _sponsoredData->hintSize.width();
}
return { maxWidth, minHeight };
}
@ -790,6 +815,50 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
endskip,
false,
context.selection);
if (asSponsored
&& _sponsoredData->canReport
&& (paintw >
_sponsoredData->widthBeforeHint
+ _sponsoredData->hintSize.width())) {
if (_sponsoredData->hintRipple) {
_sponsoredData->hintRipple->paint(
p,
_sponsoredData->lastHintPos.x(),
_sponsoredData->lastHintPos.y(),
width(),
&cache->bg);
if (_sponsoredData->hintRipple->empty()) {
_sponsoredData->hintRipple = nullptr;
}
}
auto color = cache->icon;
color.setAlphaF(color.alphaF() * 0.15);
const auto height = st::webPageSponsoredHintFont->height;
const auto radius = height / 2;
_sponsoredData->lastHintPos = QPoint(
radius + inner.left() + _sponsoredData->widthBeforeHint,
tshift
+ (_siteName.style()->font->height - height) / 2
+ st::webPageSponsoredHintFont->descent / 2);
const auto rect = QRect(
_sponsoredData->lastHintPos,
_sponsoredData->hintSize);
auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen);
p.setBrush(color);
p.drawRoundedRect(rect, radius, radius);
p.setPen(cache->icon);
p.setBrush(Qt::NoBrush);
p.setFont(st::webPageSponsoredHintFont);
p.drawText(
rect,
tr::lng_sponsored_message_revenue_button(tr::now),
style::al_center);
}
tshift += lineHeight;
p.setTextPalette(stm->textPalette);
@ -1076,6 +1145,15 @@ TextState WebPage::textState(QPoint point, StateRequest request) const {
if ((!result.link || _sponsoredData) && outer.contains(point)) {
result.link = _openl;
}
if (_sponsoredData && _sponsoredData->canReport) {
const auto contains = QRect(
_sponsoredData->lastHintPos,
_sponsoredData->hintSize).contains(point
- QPoint(0, st::msgDateFont->height));
if (contains) {
result.link = _sponsoredData->hintLink;
}
}
_lastPoint = point - outer.topLeft();
result.symbol += symbolAdd;
@ -1145,6 +1223,28 @@ void WebPage::clickHandlerActiveChanged(
void WebPage::clickHandlerPressedChanged(
const ClickHandlerPtr &p,
bool pressed) {
if (_sponsoredData && _sponsoredData->hintLink == p) {
if (pressed) {
if (!_sponsoredData->hintRipple) {
const auto owner = &parent()->history()->owner();
auto ripple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::RoundRectMask(
_sponsoredData->hintSize,
_st.radius),
[=] { owner->requestViewRepaint(parent()); });
_sponsoredData->hintRipple = std::move(ripple);
}
const auto full = Rect(currentSize());
const auto outer = full - inBubblePadding();
_sponsoredData->hintRipple->add(_lastPoint
+ outer.topLeft()
- _sponsoredData->lastHintPos);
} else if (_sponsoredData->hintRipple) {
_sponsoredData->hintRipple->lastStop();
}
return;
}
if (p == _openl) {
if (pressed) {
if (!_ripple) {

View file

@ -135,6 +135,13 @@ private:
Ui::PeerUserpicView userpicView;
QString buttonText;
bool hasExternalLink = false;
bool canReport = false;
QSize hintSize;
QPoint lastHintPos;
int widthBeforeHint = 0;
std::unique_ptr<Ui::RippleAnimation> hintRipple;
ClickHandlerPtr hintLink;
};
mutable std::optional<SponsoredData> _sponsoredData;

View file

@ -324,4 +324,10 @@ void ShowSponsored(
menu->popup(QCursor::pos());
}
void ShowSponsoredAbout(std::shared_ptr<ChatHelpers::Show> show) {
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
AboutBox(box, &show->session());
}));
}
} // namespace Menu

View file

@ -24,4 +24,6 @@ void ShowSponsored(
std::shared_ptr<ChatHelpers::Show> show,
not_null<HistoryItem*> item);
void ShowSponsoredAbout(std::shared_ptr<ChatHelpers::Show> show);
} // namespace Menu

View file

@ -602,6 +602,7 @@ historyPsaForwardPalette: TextPalette(defaultTextPalette) {
webPageTitleFont: semiboldFont;
webPageTitleStyle: semiboldTextStyle;
webPageSponsoredHintFont: font(10px);
webPageDescriptionFont: normalFont;
webPageDescriptionStyle: defaultTextStyle;
webPagePhotoDelta: 8px;