From 0477d43fbb0be91ef20b584c09792fabe26b30a9 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 14 Aug 2024 20:42:14 +0300 Subject: [PATCH] Added button to media viewer for media from sponsored messages. --- .../SourceFiles/media/view/media_view.style | 9 ++ .../media/view/media_view_overlay_widget.cpp | 83 ++++++++++++++++++- .../media/view/media_view_overlay_widget.h | 10 +++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index fe1a7b5b6..b01baa4f2 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -1051,3 +1051,12 @@ storiesRepostSimpleStyle: QuoteStyle(defaultQuoteStyle) { storiesRepostIcon: icon {{ "mediaview/mini_repost", windowFg }}; storiesRepostIconPadding: margins(0px, 4px, 2px, 0px); storiesRepostUserpicPadding: margins(0px, 1px, 4px, 0px); + +mediaviewSponsoredButton: RoundButton(defaultActiveButton) { + textFg: mediaviewPlaybackIconFg; + textFgOver: mediaviewPlaybackIconFg; + textBg: mediaviewSaveMsgBg; + textBgOver: mediaviewSaveMsgBg; + + ripple: universalRippleAnimation; +} diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index b2a9d97e1..4cedf02d1 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -99,6 +99,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include #include +#include #include @@ -750,6 +751,8 @@ void OverlayWidget::setupWindow() { && (widgetPoint.y() > st::mediaviewHeaderTop) && QRect(_x, _y, _w, _h).contains(widgetPoint)) { } else if (_stories && _stories->ignoreWindowMove(widgetPoint)) { + } else if (_sponsoredButton + && _sponsoredButton->geometry().contains(widgetPoint)) { } else if (_windowed) { result |= Flag::Move; } @@ -1421,7 +1424,9 @@ void OverlayWidget::resizeCenteredControls() { _groupThumbsTop = _groupThumbs ? (height() - _groupThumbs->height()) : 0; refreshClipControllerGeometry(); + refreshSponsoredButtonGeometry(); refreshCaptionGeometry(); + refreshSponsoredButtonWidth(); } void OverlayWidget::refreshCaptionGeometry() { @@ -1443,6 +1448,8 @@ void OverlayWidget::refreshCaptionGeometry() { } const auto captionBottom = _stories ? (_y + _h) + : _sponsoredButton + ? (_sponsoredButton->y() - st::mediaviewCaptionMargin.height()) : (_streamed && _streamed->controls) ? (_streamed->controls->y() - st::mediaviewCaptionMargin.height()) : _groupThumbs @@ -1487,6 +1494,41 @@ void OverlayWidget::refreshCaptionGeometry() { captionHeight); } +void OverlayWidget::refreshSponsoredButtonGeometry() { + if (!_sponsoredButton) { + return; + } + const auto controllerBottom = (_groupThumbs && !_fullScreenVideo) + ? _groupThumbsTop + : height(); + const auto skip = st::mediaviewCaptionPadding.bottom(); + const auto captionRect = captionGeometry(); + _sponsoredButton->resize( + captionRect.width(), + _sponsoredButton->height()); + _sponsoredButton->move( + (width() - captionRect.width()) / 2, + (controllerBottom // Duplicated in recountSkipTop(). + - ((_streamed && _streamed->controls) + ? (_streamed->controls->height() + + st::mediaviewCaptionMargin.height()) + : 0) + - _sponsoredButton->height() + - st::mediaviewCaptionPadding.bottom())); + Ui::SendPendingMoveResizeEvents(_sponsoredButton.get()); +} + +void OverlayWidget::refreshSponsoredButtonWidth() { + if (!_sponsoredButton) { + return; + } + const auto captionWidth = captionGeometry().width(); + _sponsoredButton->resize(captionWidth, _sponsoredButton->height()); + _sponsoredButton->move( + (width() - captionWidth) / 2, + _sponsoredButton->y()); +} + void OverlayWidget::fillContextMenuActions( const Ui::Menu::MenuCallback &addAction) { if (_message && _message->isSponsored()) { @@ -1769,6 +1811,13 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) { } else { _controlsOpacity.update(dt, anim::linear); } + if (_sponsoredButtonOpacity && _sponsoredButton) { + const auto value = _controlsOpacity.current(); + _sponsoredButtonOpacity->setOpacity(value); + _sponsoredButton->setAttribute( + Qt::WA_TransparentForMouseEvents, + value < 1); + } _helper->setControlsOpacity(_controlsOpacity.current()); const auto content = finalContentRect(); const auto siblingType = (_over == Over::LeftStories) @@ -3508,6 +3557,7 @@ void OverlayWidget::displayDocument( ).toImage()); } } else { + initSponsoredButton(); if (_documentMedia->canBePlayed(_message) && initStreaming(startStreaming)) { } else if (_document->isVideoFile()) { @@ -3613,6 +3663,33 @@ void OverlayWidget::displayDocument( } } +void OverlayWidget::initSponsoredButton() { + const auto has = _message && _message->isSponsored() && _session; + if (has && _sponsoredButton) { + return; + } else if (!has && _sponsoredButton) { + _sponsoredButton = nullptr; + return; + } else if (!has && !_sponsoredButton) { + return; + } + const auto &component = _session->sponsoredMessages(); + const auto details = component.lookupDetails(_message->fullId()); + _sponsoredButton = base::make_unique_q( + _body, + rpl::single(details.buttonText), + st::mediaviewSponsoredButton); + + _sponsoredButton->setClickedCallback([=, link = details.link] { + UrlClickHandler::Open(link); + hide(); + }); + _sponsoredButtonOpacity = base::make_unique_q( + _sponsoredButton.get()); + _sponsoredButtonOpacity->setOpacity(1.0); + _sponsoredButton->setGraphicsEffect(_sponsoredButtonOpacity.get()); +} + void OverlayWidget::updateThemePreviewGeometry() { if (_themePreviewShown) { auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height()); @@ -5677,8 +5754,8 @@ void OverlayWidget::updateOverRect(Over state) { break; case Over::LeftStories: update(_stories - ? _stories->sibling(Type::Left).layout.geometry : - QRect()); + ? _stories->sibling(Type::Left).layout.geometry + : QRect()); break; case Over::RightStories: update(_stories @@ -6219,6 +6296,8 @@ void OverlayWidget::clearBeforeHide() { _helper->setControlsOpacity(1.); _groupThumbs = nullptr; _groupThumbsRect = QRect(); + _sponsoredButtonOpacity = nullptr; + _sponsoredButton = nullptr; } void OverlayWidget::clearAfterHide() { diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 47622c77f..37c0da390 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/view/media_view_open_common.h" #include "media/stories/media_stories_delegate.h" +class QGraphicsOpacityEffect; + class History; namespace anim { @@ -149,6 +151,7 @@ private: Right, LeftStories, RightStories, + SponsoredButton, Header, Name, Date, @@ -411,6 +414,10 @@ private: void destroyThemePreview(); void updateThemePreviewGeometry(); + void initSponsoredButton(); + void refreshSponsoredButtonGeometry(); + void refreshSponsoredButtonWidth(); + void documentUpdated(not_null document); void changingMsgId(FullMsgId newId, MsgId oldId); @@ -693,6 +700,9 @@ private: object_ptr _dropdown; base::Timer _dropdownShowTimer; + base::unique_qptr _sponsoredButton; + base::unique_qptr _sponsoredButtonOpacity; + bool _receiveMouse = true; bool _processingKeyPress = false;