Added button for poll voting to media view.

This commit is contained in:
23rd
2026-03-18 16:39:05 +03:00
parent 0328de897c
commit a98b2f4a39
3 changed files with 112 additions and 0 deletions
@@ -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 },
@@ -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 <QGraphicsOpacityEffect>
#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<PrintDead<QGraphicsOpacityEffect>>(
_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<QGraphicsOpacityEffect*>(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();
@@ -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<DocumentData*> document);
void changingMsgId(FullMsgId newId, MsgId oldId);
@@ -741,6 +746,7 @@ private:
base::Timer _dropdownShowTimer;
base::unique_qptr<SponsoredButton> _sponsoredButton;
object_ptr<Ui::RoundButton> _voteButton = { nullptr };
bool _receiveMouse = true;
bool _processingKeyPress = false;