diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 18afb14c84..1184b9b322 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -121,6 +121,12 @@ mediaviewMore: icon {{ "title_menu_dots", mediaviewControlFg }}; mediaviewRecognize: icon {{ "mediaview/recognize", mediaviewControlFg }}; mediaviewDraw: icon {{ "mediaview/draw", mediaviewControlFg }}; +mediaviewVoteButton: RoundButton(defaultActiveButton) { + height: 36px; + radius: 18px; +} +mediaviewVoteButtonMargin: 8px; + mediaviewFileRed: icon { { size(25px, 25px), mediaviewFileBg }, { "mediaview/file_corner", mediaviewFileRedCornerFg }, diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index c74bc8829c..6913fa8afa 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "api/api_attached_stickers.h" #include "api/api_peer_photo.h" +#include "api/api_polls.h" #include "base/qt/qt_common_adapters.h" #include "base/timer_rpl.h" #include "lang/lang_keys.h" @@ -100,6 +101,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_menu_icons.h" #include "platform/platform_text_recognition.h" +#include + #ifdef Q_OS_MAC #include "platform/mac/touchbar/mac_touchbar_media_view.h" #endif // Q_OS_MAC @@ -1629,6 +1632,8 @@ void OverlayWidget::resizeCenteredControls() { refreshClipControllerGeometry(); refreshSponsoredButtonGeometry(); + refreshVoteButton(); + refreshVoteButtonGeometry(); refreshCaptionGeometry(); refreshSponsoredButtonWidth(); } @@ -1657,6 +1662,8 @@ void OverlayWidget::refreshCaptionGeometry() { ? (_y + _h) : _sponsoredButton ? (_sponsoredButton->y() - st::mediaviewCaptionMargin.height()) + : _voteButton + ? (_voteButton->y() - st::mediaviewCaptionMargin.height()) : (_streamed && _streamed->controls) ? (_streamed->controls->y() - st::mediaviewCaptionMargin.height()) : _groupThumbs @@ -1735,6 +1742,88 @@ void OverlayWidget::refreshSponsoredButtonWidth() { _sponsoredButton->y()); } +const PollAnswer *OverlayWidget::currentPollAnswer() const { + if (!_message || !_session) { + return nullptr; + } + const auto media = _message->media(); + if (!media) { + return nullptr; + } + const auto poll = media->poll(); + if (!poll || (!_photo && !_document)) { + return nullptr; + } + const auto current = _photo + ? WebPageCollage::Item(_photo) + : WebPageCollage::Item(_document); + for (const auto &answer : poll->answers) { + const auto candidate = PollAnswerMediaItem(poll, answer); + if (candidate && (*candidate == current)) { + return &answer; + } + } + return nullptr; +} + +void OverlayWidget::refreshVoteButton() { + const auto answer = currentPollAnswer(); + const auto media = _message ? _message->media() : nullptr; + const auto poll = media ? media->poll() : nullptr; + const auto show = answer + && poll + && !answer->chosen + && !poll->closed() + && !poll->voted() + && poll->sendingVotes.empty(); + if (!show) { + if (_voteButton) { + _voteButton.destroy(); + } + return; + } + if (!_voteButton) { + using TextTransform = Ui::RoundButton::TextTransform; + _voteButton.create( + _body, + tr::lng_polls_submit_votes(), + st::mediaviewVoteButton); + _voteButton->setTextTransform(TextTransform::NoTransform); + const auto effect = Ui::CreateChild>( + _voteButton.data()); + effect->setOpacity(_controlsOpacity.current()); + _voteButton->setGraphicsEffect(effect); + const auto itemId = _message->fullId(); + const auto option = answer->option; + _voteButton->setClickedCallback([=] { + if (_session) { + _session->api().polls().sendVotes(itemId, { option }); + _voteButton.destroy(); + refreshCaptionGeometry(); + } + }); + } + _voteButton->show(); +} + +void OverlayWidget::refreshVoteButtonGeometry() { + if (!_voteButton) { + return; + } + const auto controllerBottom = (_groupThumbs && !_fullScreenVideo) + ? _groupThumbsTop + : height(); + _voteButton->moveToLeft( + (width() - _voteButton->width()) / 2, + controllerBottom + - ((_streamed && _streamed->controls) + ? (_streamed->controls->height() + + st::mediaviewCaptionPadding.bottom()) + : 0) + - _voteButton->height() + - st::mediaviewVoteButtonMargin); +} + void OverlayWidget::fillContextMenuActions( const Ui::Menu::MenuCallback &addAction) { if (_message && _message->isSponsored()) { @@ -2060,6 +2149,15 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) { Qt::WA_TransparentForMouseEvents, value < 1); } + if (_voteButton) { + const auto value = _controlsOpacity.current(); + if (const auto e = _voteButton->graphicsEffect()) { + static_cast(e)->setOpacity(value); + } + _voteButton->setAttribute( + Qt::WA_TransparentForMouseEvents, + value < 1); + } _helper->setControlsOpacity(_controlsOpacity.current()); const auto content = finalContentRect(); const auto siblingType = (_over == Over::LeftStories) @@ -7156,6 +7254,7 @@ void OverlayWidget::clearBeforeHide() { _groupThumbs = nullptr; _groupThumbsRect = QRect(); _sponsoredButton = nullptr; + _voteButton.destroy(); _showRecognitionResults = false; } @@ -7170,6 +7269,7 @@ void OverlayWidget::clearAfterHide() { _radial.stop(); _staticContent = QImage(); _themePreview = nullptr; + _voteButton.destroyDelayed(); _themeApply.destroyDelayed(); _themeCancel.destroyDelayed(); _themeShare.destroyDelayed(); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 2c16b09463..468514549a 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_text_recognition.h" class History; +struct PollAnswer; namespace anim { enum class activation : uchar; @@ -437,6 +438,10 @@ private: void refreshSponsoredButtonGeometry(); void refreshSponsoredButtonWidth(); + void refreshVoteButton(); + void refreshVoteButtonGeometry(); + [[nodiscard]] const PollAnswer *currentPollAnswer() const; + void documentUpdated(not_null document); void changingMsgId(FullMsgId newId, MsgId oldId); @@ -741,6 +746,7 @@ private: base::Timer _dropdownShowTimer; base::unique_qptr _sponsoredButton; + object_ptr _voteButton = { nullptr }; bool _receiveMouse = true; bool _processingKeyPress = false;