mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Added recent voters to media view.
This commit is contained in:
@@ -276,6 +276,30 @@ bool PollData::applyResultToAnswers(
|
||||
answer->correct = voters.is_correct();
|
||||
changed = true;
|
||||
}
|
||||
if (const auto recent = voters.vrecent_voters()) {
|
||||
const auto recentChanged = !ranges::equal(
|
||||
answer->recentVoters,
|
||||
recent->v,
|
||||
ranges::equal_to(),
|
||||
&PeerData::id,
|
||||
peerFromMTP);
|
||||
if (recentChanged) {
|
||||
changed = true;
|
||||
answer->recentVoters = ranges::views::all(
|
||||
recent->v
|
||||
) | ranges::views::transform([&](MTPPeer peerId) {
|
||||
const auto peer = _owner->peer(
|
||||
peerFromMTP(peerId));
|
||||
return peer->isMinimalLoaded()
|
||||
? peer.get()
|
||||
: nullptr;
|
||||
}) | ranges::views::filter([](PeerData *peer) {
|
||||
return peer != nullptr;
|
||||
}) | ranges::views::transform([](PeerData *peer) {
|
||||
return not_null(peer);
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,10 +15,13 @@ namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
class PeerData;
|
||||
|
||||
struct PollAnswer {
|
||||
TextWithEntities text;
|
||||
QByteArray option;
|
||||
std::optional<MTPInputMedia> media;
|
||||
std::vector<not_null<PeerData*>> recentVoters;
|
||||
int votes = 0;
|
||||
bool chosen = false;
|
||||
bool correct = false;
|
||||
|
||||
@@ -4916,6 +4916,7 @@ void Session::sendWebPageGamePollTodoListNotifications() {
|
||||
}
|
||||
}
|
||||
for (const auto &poll : base::take(_pollsUpdated)) {
|
||||
_pollUpdates.fire_copy(poll);
|
||||
if (const auto i = _pollViews.find(poll); i != _pollViews.end()) {
|
||||
resize.insert(end(resize), begin(i->second), end(i->second));
|
||||
}
|
||||
@@ -4935,6 +4936,10 @@ rpl::producer<not_null<WebPageData*>> Session::webPageUpdates() const {
|
||||
return _webpageUpdates.events();
|
||||
}
|
||||
|
||||
rpl::producer<not_null<PollData*>> Session::pollUpdates() const {
|
||||
return _pollUpdates.events();
|
||||
}
|
||||
|
||||
void Session::channelDifferenceTooLong(not_null<ChannelData*> channel) {
|
||||
_channelDifferenceTooLong.fire_copy(channel);
|
||||
}
|
||||
|
||||
@@ -849,6 +849,7 @@ public:
|
||||
[[nodiscard]] bool hasPendingWebPageGamePollTodoListNotification() const;
|
||||
void sendWebPageGamePollTodoListNotifications();
|
||||
[[nodiscard]] rpl::producer<not_null<WebPageData*>> webPageUpdates() const;
|
||||
[[nodiscard]] rpl::producer<not_null<PollData*>> pollUpdates() const;
|
||||
|
||||
void channelDifferenceTooLong(not_null<ChannelData*> channel);
|
||||
[[nodiscard]] rpl::producer<not_null<ChannelData*>> channelDifferenceTooLong() const;
|
||||
@@ -1243,6 +1244,7 @@ private:
|
||||
base::flat_set<not_null<TodoListData*>> _todoListsUpdated;
|
||||
|
||||
rpl::event_stream<not_null<WebPageData*>> _webpageUpdates;
|
||||
rpl::event_stream<not_null<PollData*>> _pollUpdates;
|
||||
rpl::event_stream<not_null<ChannelData*>> _channelDifferenceTooLong;
|
||||
rpl::event_stream<not_null<DocumentData*>> _documentLoadProgress;
|
||||
base::flat_set<not_null<ChannelData*>> _suggestToGigagroup;
|
||||
|
||||
@@ -127,6 +127,15 @@ mediaviewVoteButton: RoundButton(defaultActiveButton) {
|
||||
}
|
||||
mediaviewVoteButtonMargin: 8px;
|
||||
|
||||
mediaviewPollVotersUserpics: GroupCallUserpics {
|
||||
size: 24px;
|
||||
shift: 8px;
|
||||
stroke: 2px;
|
||||
align: align(left);
|
||||
}
|
||||
mediaviewPollVotersPadding: margins(12px, 0px, 14px, 0px);
|
||||
mediaviewPollVotersSpacing: 6px;
|
||||
|
||||
mediaviewFileRed: icon {
|
||||
{ size(25px, 25px), mediaviewFileBg },
|
||||
{ "mediaview/file_corner", mediaviewFileRedCornerFg },
|
||||
|
||||
@@ -63,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/view/media/history_view_media.h"
|
||||
#include "history/view/history_view_group_call_bar.h"
|
||||
#include "history/view/reactions/history_view_reactions_selector.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/data_group_call.h"
|
||||
@@ -98,6 +99,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_media_view.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "platform/platform_text_recognition.h"
|
||||
|
||||
@@ -1633,9 +1635,29 @@ void OverlayWidget::resizeCenteredControls() {
|
||||
refreshClipControllerGeometry();
|
||||
refreshSponsoredButtonGeometry();
|
||||
refreshVoteButton();
|
||||
refreshPollVotersWidget();
|
||||
refreshVoteButtonGeometry();
|
||||
refreshPollVotersWidgetGeometry();
|
||||
refreshCaptionGeometry();
|
||||
refreshSponsoredButtonWidth();
|
||||
|
||||
_pollUpdateLifetime.destroy();
|
||||
if (currentPollAnswer()) {
|
||||
const auto media = _message ? _message->media() : nullptr;
|
||||
const auto poll = media ? media->poll() : nullptr;
|
||||
if (poll && _session) {
|
||||
_session->data().pollUpdates(
|
||||
) | rpl::filter([=](not_null<PollData*> updated) {
|
||||
return updated == poll;
|
||||
}) | rpl::on_next([=] {
|
||||
refreshVoteButton();
|
||||
refreshPollVotersWidget();
|
||||
refreshVoteButtonGeometry();
|
||||
refreshPollVotersWidgetGeometry();
|
||||
refreshCaptionGeometry();
|
||||
}, _pollUpdateLifetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayWidget::refreshCaptionGeometry() {
|
||||
@@ -1664,6 +1686,8 @@ void OverlayWidget::refreshCaptionGeometry() {
|
||||
? (_sponsoredButton->y() - st::mediaviewCaptionMargin.height())
|
||||
: _voteButton
|
||||
? (_voteButton->y() - st::mediaviewCaptionMargin.height())
|
||||
: _pollVotersWidget
|
||||
? (_pollVotersWidget->y() - st::mediaviewCaptionMargin.height())
|
||||
: (_streamed && _streamed->controls)
|
||||
? (_streamed->controls->y() - st::mediaviewCaptionMargin.height())
|
||||
: _groupThumbs
|
||||
@@ -1789,18 +1813,23 @@ void OverlayWidget::refreshVoteButton() {
|
||||
tr::lng_polls_submit_votes(),
|
||||
st::mediaviewVoteButton);
|
||||
_voteButton->setTextTransform(TextTransform::NoTransform);
|
||||
const auto effect = Ui::CreateChild<PrintDead<QGraphicsOpacityEffect>>(
|
||||
const auto effect = Ui::CreateChild<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();
|
||||
if (!_session) {
|
||||
return;
|
||||
}
|
||||
const auto current = currentPollAnswer();
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
_session->api().polls().sendVotes(
|
||||
_message->fullId(),
|
||||
{ current->option });
|
||||
_voteButton.destroy();
|
||||
refreshCaptionGeometry();
|
||||
});
|
||||
}
|
||||
_voteButton->show();
|
||||
@@ -1824,6 +1853,97 @@ void OverlayWidget::refreshVoteButtonGeometry() {
|
||||
- st::mediaviewVoteButtonMargin);
|
||||
}
|
||||
|
||||
void OverlayWidget::refreshPollVotersWidget() {
|
||||
const auto answer = currentPollAnswer();
|
||||
const auto show = answer
|
||||
&& (answer->votes > 0)
|
||||
&& !_voteButton;
|
||||
if (!show) {
|
||||
_pollVotersWidget.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
_pollVotersWidget.destroy();
|
||||
_pollVotersWidget.create(_body);
|
||||
|
||||
const auto effect = Ui::CreateChild<QGraphicsOpacityEffect>(
|
||||
_pollVotersWidget.data());
|
||||
effect->setOpacity(_controlsOpacity.current());
|
||||
_pollVotersWidget->setGraphicsEffect(effect);
|
||||
|
||||
auto prepared = HistoryView::PrepareUserpicsInRow(
|
||||
answer->recentVoters,
|
||||
st::mediaviewPollVotersUserpics,
|
||||
3);
|
||||
|
||||
const auto votesText = tr::lng_polls_votes_count(
|
||||
tr::now,
|
||||
lt_count,
|
||||
answer->votes);
|
||||
const auto &font = st::semiboldFont;
|
||||
const auto textWidth = font->width(votesText);
|
||||
|
||||
const auto userpicsWidth = prepared.width;
|
||||
const auto spacing = (userpicsWidth > 0)
|
||||
? st::mediaviewPollVotersSpacing
|
||||
: 0;
|
||||
const auto &padding = st::mediaviewPollVotersPadding;
|
||||
const auto widgetWidth = padding.left()
|
||||
+ userpicsWidth
|
||||
+ spacing
|
||||
+ textWidth
|
||||
+ padding.right();
|
||||
const auto widgetHeight = st::mediaviewVoteButton.height;
|
||||
|
||||
_pollVotersWidget->resize(widgetWidth, widgetHeight);
|
||||
|
||||
const auto userpicSize = st::mediaviewPollVotersUserpics.size;
|
||||
const auto raw = _pollVotersWidget.data();
|
||||
raw->paintRequest() | rpl::on_next([=,
|
||||
image = std::move(prepared.image)] {
|
||||
auto p = QPainter(raw);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
|
||||
const auto radius = st::mediaviewCaptionRadius;
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::mediaviewCaptionBg);
|
||||
p.drawRoundedRect(raw->rect(), radius, radius);
|
||||
|
||||
auto left = padding.left();
|
||||
|
||||
if (!image.isNull()) {
|
||||
const auto top = (widgetHeight - userpicSize) / 2;
|
||||
p.drawImage(left, top, image);
|
||||
left += userpicsWidth + spacing;
|
||||
}
|
||||
|
||||
p.setFont(font);
|
||||
p.setPen(st::mediaviewCaptionFg);
|
||||
const auto textTop = (widgetHeight + font->ascent - font->descent) / 2;
|
||||
p.drawText(left, textTop, votesText);
|
||||
}, raw->lifetime());
|
||||
|
||||
_pollVotersWidget->show();
|
||||
}
|
||||
|
||||
void OverlayWidget::refreshPollVotersWidgetGeometry() {
|
||||
if (!_pollVotersWidget) {
|
||||
return;
|
||||
}
|
||||
const auto controllerBottom = (_groupThumbs && !_fullScreenVideo)
|
||||
? _groupThumbsTop
|
||||
: height();
|
||||
_pollVotersWidget->moveToLeft(
|
||||
(width() - _pollVotersWidget->width()) / 2,
|
||||
controllerBottom
|
||||
- ((_streamed && _streamed->controls)
|
||||
? (_streamed->controls->height()
|
||||
+ st::mediaviewCaptionPadding.bottom())
|
||||
: 0)
|
||||
- _pollVotersWidget->height()
|
||||
- st::mediaviewVoteButtonMargin);
|
||||
}
|
||||
|
||||
void OverlayWidget::fillContextMenuActions(
|
||||
const Ui::Menu::MenuCallback &addAction) {
|
||||
if (_message && _message->isSponsored()) {
|
||||
@@ -2158,6 +2278,15 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) {
|
||||
Qt::WA_TransparentForMouseEvents,
|
||||
value < 1);
|
||||
}
|
||||
if (_pollVotersWidget) {
|
||||
const auto value = _controlsOpacity.current();
|
||||
if (const auto e = _pollVotersWidget->graphicsEffect()) {
|
||||
static_cast<QGraphicsOpacityEffect*>(e)->setOpacity(value);
|
||||
}
|
||||
_pollVotersWidget->setAttribute(
|
||||
Qt::WA_TransparentForMouseEvents,
|
||||
value < 1);
|
||||
}
|
||||
_helper->setControlsOpacity(_controlsOpacity.current());
|
||||
const auto content = finalContentRect();
|
||||
const auto siblingType = (_over == Over::LeftStories)
|
||||
@@ -7255,6 +7384,8 @@ void OverlayWidget::clearBeforeHide() {
|
||||
_groupThumbsRect = QRect();
|
||||
_sponsoredButton = nullptr;
|
||||
_voteButton.destroy();
|
||||
_pollVotersWidget.destroy();
|
||||
_pollUpdateLifetime.destroy();
|
||||
_showRecognitionResults = false;
|
||||
}
|
||||
|
||||
@@ -7270,6 +7401,7 @@ void OverlayWidget::clearAfterHide() {
|
||||
_staticContent = QImage();
|
||||
_themePreview = nullptr;
|
||||
_voteButton.destroyDelayed();
|
||||
_pollVotersWidget.destroyDelayed();
|
||||
_themeApply.destroyDelayed();
|
||||
_themeCancel.destroyDelayed();
|
||||
_themeShare.destroyDelayed();
|
||||
|
||||
@@ -440,6 +440,8 @@ private:
|
||||
|
||||
void refreshVoteButton();
|
||||
void refreshVoteButtonGeometry();
|
||||
void refreshPollVotersWidget();
|
||||
void refreshPollVotersWidgetGeometry();
|
||||
[[nodiscard]] const PollAnswer *currentPollAnswer() const;
|
||||
|
||||
void documentUpdated(not_null<DocumentData*> document);
|
||||
@@ -747,6 +749,8 @@ private:
|
||||
|
||||
base::unique_qptr<SponsoredButton> _sponsoredButton;
|
||||
object_ptr<Ui::RoundButton> _voteButton = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _pollVotersWidget = { nullptr };
|
||||
rpl::lifetime _pollUpdateLifetime;
|
||||
|
||||
bool _receiveMouse = true;
|
||||
bool _processingKeyPress = false;
|
||||
|
||||
Reference in New Issue
Block a user