From 8718d94e7d9cbacd41ae532e426719422eaf7a49 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Mar 2024 05:19:37 +0300 Subject: [PATCH] Added sub-button to top of sponsored messages that can be reported. --- Telegram/Resources/langs/lang.strings | 1 + .../view/media/history_view_web_page.cpp | 100 ++++++++++++++++++ .../view/media/history_view_web_page.h | 7 ++ Telegram/SourceFiles/menu/menu_sponsored.cpp | 6 ++ Telegram/SourceFiles/menu/menu_sponsored.h | 2 + Telegram/SourceFiles/ui/chat/chat.style | 1 + 6 files changed, 117 insertions(+) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index a5ba2a744..cfab9c867 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -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"; diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 2cf19510a..fbd61a00e 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -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([=](ClickContext context) { + const auto my = context.other.value(); + if (const auto controller = my.sessionWindow.get()) { + Menu::ShowSponsoredAbout(controller->uiShow()); + } + }); +} + [[nodiscard]] TextWithEntities PageToPhrase(not_null 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(); 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( + 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) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.h b/Telegram/SourceFiles/history/view/media/history_view_web_page.h index b048cfc39..61c834eea 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.h +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.h @@ -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 hintRipple; + ClickHandlerPtr hintLink; }; mutable std::optional _sponsoredData; diff --git a/Telegram/SourceFiles/menu/menu_sponsored.cpp b/Telegram/SourceFiles/menu/menu_sponsored.cpp index 41e72a432..51aaad13e 100644 --- a/Telegram/SourceFiles/menu/menu_sponsored.cpp +++ b/Telegram/SourceFiles/menu/menu_sponsored.cpp @@ -324,4 +324,10 @@ void ShowSponsored( menu->popup(QCursor::pos()); } +void ShowSponsoredAbout(std::shared_ptr show) { + show->showBox(Box([=](not_null box) { + AboutBox(box, &show->session()); + })); +} + } // namespace Menu diff --git a/Telegram/SourceFiles/menu/menu_sponsored.h b/Telegram/SourceFiles/menu/menu_sponsored.h index 7402931fa..ddd011ad6 100644 --- a/Telegram/SourceFiles/menu/menu_sponsored.h +++ b/Telegram/SourceFiles/menu/menu_sponsored.h @@ -24,4 +24,6 @@ void ShowSponsored( std::shared_ptr show, not_null item); +void ShowSponsoredAbout(std::shared_ptr show); + } // namespace Menu diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 3634be953..ef46e0405 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -602,6 +602,7 @@ historyPsaForwardPalette: TextPalette(defaultTextPalette) { webPageTitleFont: semiboldFont; webPageTitleStyle: semiboldTextStyle; +webPageSponsoredHintFont: font(10px); webPageDescriptionFont: normalFont; webPageDescriptionStyle: defaultTextStyle; webPagePhotoDelta: 8px;