[poll-view] Added paused state support for emoji and media.

This commit is contained in:
23rd
2026-04-04 16:22:40 +03:00
committed by John Preston
parent 9dce30e904
commit 87877fb506
@@ -195,12 +195,14 @@ struct PollThumbnailData {
[[nodiscard]] PollThumbnailData MakePollThumbnail(
not_null<PollData*> poll,
const PollAnswer &answer,
Window::SessionController::MessageContext messageContext);
Window::SessionController::MessageContext messageContext,
Fn<bool()> paused = nullptr);
[[nodiscard]] PollThumbnailData MakePollThumbnail(
not_null<PollData*> poll,
const PollMedia &media,
Window::SessionController::MessageContext messageContext) {
Window::SessionController::MessageContext messageContext,
Fn<bool()> paused = nullptr) {
auto result = PollThumbnailData();
if (!media) {
return result;
@@ -217,7 +219,8 @@ struct PollThumbnailData {
if (media.document->sticker()) {
result.thumbnail = Ui::MakeEmojiThumbnail(
&poll->owner(),
Data::SerializeCustomEmojiId(media.document));
Data::SerializeCustomEmojiId(media.document),
paused);
result.kind = PollThumbnailKind::Emoji;
} else if (media.document->isSong()
|| media.document->isVoiceMessage()) {
@@ -289,8 +292,10 @@ struct PollThumbnailData {
PollThumbnailData MakePollThumbnail(
not_null<PollData*> poll,
const PollAnswer &answer,
Window::SessionController::MessageContext messageContext) {
auto result = MakePollThumbnail(poll, answer.media, messageContext);
Window::SessionController::MessageContext messageContext,
Fn<bool()> paused) {
auto result
= MakePollThumbnail(poll, answer.media, messageContext, paused);
if (result.kind == PollThumbnailKind::Emoji && result.id) {
const auto documentId = DocumentId(result.id);
const auto option = answer.option;
@@ -363,7 +368,8 @@ struct Poll::Answer {
not_null<PollData*> poll,
const PollAnswer &original,
Window::SessionController::MessageContext messageContext,
Fn<void()> repaint);
Fn<void()> repaint,
Fn<bool()> paused);
Ui::Text::String text;
QByteArray option;
@@ -1734,11 +1740,13 @@ void Poll::Answer::fillMedia(
not_null<PollData*> poll,
const PollAnswer &original,
Window::SessionController::MessageContext messageContext,
Fn<void()> repaint) {
Fn<void()> repaint,
Fn<bool()> paused) {
const auto updated = MakePollThumbnail(
poll,
original,
messageContext);
messageContext,
paused);
const auto same = (updated.kind == thumbnailKind)
&& (updated.id == thumbnailId)
&& (updated.rounded == thumbnailRounded);
@@ -2037,7 +2045,11 @@ void Poll::updateTexts() {
options,
Core::TextContext({
.session = &_poll->session(),
.repaint = [=] { repaint(); },
.repaint = [=] {
if (!_parent->delegate()->elementAnimationsPaused()) {
repaint();
}
},
.customEmojiLoopLimit = 2,
}));
}
@@ -2097,7 +2109,11 @@ void Poll::Header::updateDescription() {
}
const auto context = Core::TextContext({
.session = &_owner->_poll->session(),
.repaint = [=] { _owner->_parent->customEmojiRepaint(); },
.repaint = [=] {
if (!_owner->_parent->delegate()->elementAnimationsPaused()) {
_owner->_parent->customEmojiRepaint();
}
},
.customEmojiLoopLimit = 2,
});
_description.setMarkedText(
@@ -2123,7 +2139,11 @@ void Poll::Header::updateSolutionText() {
Ui::ItemTextOptions(_owner->_parent->data()),
Core::TextContext({
.session = &_owner->_poll->session(),
.repaint = [=] { _owner->repaint(); },
.repaint = [=] {
if (!_owner->_parent->delegate()->elementAnimationsPaused()) {
_owner->repaint();
}
},
}));
InitElementTextPart(_owner->_parent, _solutionText);
}
@@ -2135,10 +2155,14 @@ void Poll::Header::updateSolutionMedia() {
.topicRootId = item->topicRootId(),
.monoforumPeerId = item->sublistPeerId(),
};
const auto paused = [=] {
return _owner->_parent->delegate()->elementAnimationsPaused();
};
const auto updated = MakePollThumbnail(
_owner->_poll,
_owner->_poll->solutionMedia,
messageContext);
messageContext,
paused);
if (!updated.thumbnail) {
_solutionMedia = nullptr;
_solutionAttach = nullptr;
@@ -2186,10 +2210,14 @@ void Poll::Header::updateAttachedMedia() {
.topicRootId = item->topicRootId(),
.monoforumPeerId = item->sublistPeerId(),
};
const auto paused = [=] {
return _owner->_parent->delegate()->elementAnimationsPaused();
};
const auto updated = MakePollThumbnail(
_owner->_poll,
_owner->_poll->attachedMedia,
messageContext);
messageContext,
paused);
const auto same = (_attachedMedia->kind == updated.kind)
&& (_attachedMedia->id == updated.id)
&& (_attachedMedia->rounded == updated.rounded);
@@ -2217,8 +2245,8 @@ void Poll::Header::updateAttachedMedia() {
_owner->_parent->data()->fullId());
if (const auto size = photo->size(Data::PhotoSize::Large)) {
_attachedMedia->photoSize = *size;
} else if (const auto size = photo->size(Data::PhotoSize::Thumbnail)) {
_attachedMedia->photoSize = *size;
} else if (const auto s = photo->size(Data::PhotoSize::Thumbnail)) {
_attachedMedia->photoSize = *s;
}
}
if ((updated.kind == PollThumbnailKind::Document
@@ -2235,8 +2263,10 @@ void Poll::Header::updateAttachedMedia() {
if (_attachedMedia->thumbnail) {
_attachedMedia->thumbnail->subscribeToUpdates(
crl::guard(_owner, [=] {
_attachedMediaCache = QImage();
_owner->repaint();
if (!_owner->_parent->delegate()->elementAnimationsPaused()) {
_attachedMediaCache = QImage();
_owner->repaint();
}
}));
}
}
@@ -2418,28 +2448,35 @@ uint16 Poll::Header::solutionSelectionLength() const {
: uint16(0);
}
TextSelection Poll::Header::toSolutionSelection(TextSelection selection) const {
TextSelection Poll::Header::toSolutionSelection(
TextSelection selection) const {
return UnshiftItemSelection(selection, _description);
}
TextSelection Poll::Header::fromSolutionSelection(TextSelection selection) const {
TextSelection Poll::Header::fromSolutionSelection(
TextSelection selection) const {
return ShiftItemSelection(selection, _description);
}
TextSelection Poll::Header::toQuestionSelection(TextSelection selection) const {
TextSelection Poll::Header::toQuestionSelection(
TextSelection selection) const {
return UnshiftItemSelection(
selection,
uint16(_description.length() + solutionSelectionLength()));
}
TextSelection Poll::Header::fromQuestionSelection(TextSelection selection) const {
TextSelection Poll::Header::fromQuestionSelection(
TextSelection selection) const {
return ShiftItemSelection(
selection,
uint16(_description.length() + solutionSelectionLength()));
}
void Poll::Options::checkQuizAnswered() {
if (!_owner->_voted || !_votedFromHere || !_owner->_poll->quiz() || anim::Disabled()) {
if (!_owner->_voted
|| !_votedFromHere
|| !_owner->_poll->quiz()
|| anim::Disabled()) {
return;
}
const auto i = ranges::find(_answers, true, &Answer::chosen);
@@ -2529,10 +2566,21 @@ void Poll::Header::updateRecentVoters() {
void Poll::Options::updateAnswers() {
const auto context = Core::TextContext({
.session = &_owner->_poll->session(),
.repaint = [=] { _owner->repaint(); },
.repaint = [=] {
if (!_owner->_parent->delegate()->elementAnimationsPaused()) {
_owner->repaint();
}
},
.customEmojiLoopLimit = 2,
});
const auto repaintThumbnail = crl::guard(_owner, [=] { _owner->repaint(); });
const auto repaintThumbnail = crl::guard(_owner, [=] {
if (!_owner->_parent->delegate()->elementAnimationsPaused()) {
_owner->repaint();
}
});
const auto paused = [=] {
return _owner->_parent->delegate()->elementAnimationsPaused();
};
const auto item = _owner->_parent->data();
const auto messageContext = Window::SessionController::MessageContext{
.id = item->fullId(),
@@ -2566,7 +2614,12 @@ void Poll::Options::updateAnswers() {
&PollAnswer::option);
Assert(i != end(_owner->_poll->answers));
answer.fillData(_owner->_poll, *i, context);
answer.fillMedia(_owner->_poll, *i, messageContext, repaintThumbnail);
answer.fillMedia(
_owner->_poll,
*i,
messageContext,
repaintThumbnail,
paused);
}
_anyAnswerHasMedia = ranges::any_of(_answers, [](const Answer &a) {
return a.thumbnail != nullptr;
@@ -2583,7 +2636,12 @@ void Poll::Options::updateAnswers() {
&PollAnswer::option);
Assert(i != end(_owner->_poll->answers));
result.fillData(_owner->_poll, *i, context);
result.fillMedia(_owner->_poll, *i, messageContext, repaintThumbnail);
result.fillMedia(
_owner->_poll,
*i,
messageContext,
repaintThumbnail,
paused);
return result;
}) | ranges::to_vector;
@@ -2992,7 +3050,9 @@ void Poll::Header::paintSolutionBlock(
}
if (!_closeSolutionLink) {
_closeSolutionLink = std::make_shared<LambdaClickHandler>(
crl::guard(_owner, [=] { _owner->_headerPart->solutionToggled(false); }));
crl::guard(
_owner,
[=] { _owner->_headerPart->solutionToggled(false); }));
}
const auto &qst = st::historyPagePreview;
@@ -3373,11 +3433,15 @@ void Poll::Options::paintRadio(
const auto o = p.opacity();
if (checkmark < 1.) {
p.setBrush(Qt::NoBrush);
p.setOpacity(o * (over ? st::historyPollRadioOpacityOver : st::historyPollRadioOpacity));
p.setOpacity(o
* (over
? st::historyPollRadioOpacityOver
: st::historyPollRadioOpacity));
}
const auto multiChoice = (_owner->_flags & PollData::Flag::MultiChoice);
const auto rect = QRectF(left, top, radio.diameter, radio.diameter).marginsRemoved(QMarginsF(radio.thickness / 2., radio.thickness / 2., radio.thickness / 2., radio.thickness / 2.));
const auto rect = QRectF(left, top, radio.diameter, radio.diameter)
- Margins(radio.thickness / 2.);
const auto radius = st::historyPollCheckboxRadius;
if (_sendingAnimation && _sendingAnimation->option == answer.option) {
const auto &active = stm->msgServiceFg;
@@ -3424,7 +3488,11 @@ void Poll::Options::paintRadio(
p.drawEllipse(inner);
}
const auto &icon = stm->historyPollChosen;
icon.paint(p, left + (radio.diameter - icon.width()) / 2, top + (radio.diameter - icon.height()) / 2, _owner->width());
icon.paint(
p,
left + (radio.diameter - icon.width()) / 2,
top + (radio.diameter - icon.height()) / 2,
_owner->width());
}
}
@@ -3448,7 +3516,12 @@ void Poll::Options::paintPercent(
p.setFont(st::historyPollPercentFont);
p.setPen(stm->historyTextFg);
const auto pleft = aleft - percentWidth - st::historyPollPercentSkip;
p.drawTextLeft(pleft, top + st::historyPollPercentTop, outerWidth, percent, percentWidth);
p.drawTextLeft(
pleft,
top + st::historyPollPercentTop,
outerWidth,
percent,
percentWidth);
}
void Poll::Options::paintFilling(
@@ -3471,7 +3544,8 @@ void Poll::Options::paintFilling(
const auto thickness = st::historyPollFillingHeight;
const auto max = contentWidth - st::historyPollFillingRight;
const auto size = anim::interpolate(st::historyPollFillingMin, max, filling);
const auto size
= anim::interpolate(st::historyPollFillingMin, max, filling);
const auto radius = st::historyPollFillingRadius;
const auto ftop = top
+ std::max(st::historyPollPercentFont->height, contentHeight)
@@ -3485,7 +3559,10 @@ void Poll::Options::paintFilling(
const auto style = [&] {
if (chosen && !correct) {
return Style::Incorrect;
} else if (chosen && correct && _owner->_poll->quiz() && !context.outbg) {
} else if (chosen
&& correct
&& _owner->_poll->quiz()
&& !context.outbg) {
return Style::Correct;
} else {
return Style::Default;
@@ -3600,7 +3677,8 @@ bool Poll::Options::checkAnimationStart() const {
// Skip initial changes.
return false;
}
const auto result = (_owner->showVotes() != (_owner->_poll->voted() || _owner->_poll->closed()))
const auto result = _owner->showVotes()
!= (_owner->_poll->voted() || _owner->_poll->closed())
|| answerVotesChanged();
if (result) {
saveStateInAnimation();