Display last voters userpics.

This commit is contained in:
John Preston 2020-01-09 20:24:54 +03:00
parent 95b2886bad
commit afff7634f9
8 changed files with 95 additions and 9 deletions

View file

@ -706,7 +706,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
};
const auto collectResult = [=] {
auto result = PollData(id);
auto result = PollData(&_session->data(), id);
result.question = question->getLastText().trimmed();
result.answers = options->toPollAnswers();
return result;

View file

@ -366,7 +366,7 @@ private:
static constexpr auto kUnknownPhotoId = PhotoId(0xFFFFFFFFFFFFFFFFULL);
not_null<Data::Session*> _owner;
const not_null<Data::Session*> _owner;
ImagePtr _userpic;
PhotoId _userpicPhotoId = kUnknownPhotoId;

View file

@ -8,6 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_poll.h"
#include "apiwrap.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "main/main_session.h"
namespace {
@ -34,7 +36,9 @@ PollAnswer *AnswerByOption(
} // namespace
PollData::PollData(PollId id) : id(id) {
PollData::PollData(not_null<Data::Session*> owner, PollId id)
: id(id)
, _owner(owner) {
}
bool PollData::applyChanges(const MTPDpoll &poll) {
@ -96,6 +100,26 @@ bool PollData::applyResults(const MTPPollResults &results) {
}
}
}
if (const auto recent = results.vrecent_voters()) {
const auto recentChanged = !ranges::equal(
recentVoters,
recent->v,
ranges::equal_to(),
&UserData::id,
&MTPint::v);
if (recentChanged) {
changed = true;
recentVoters = ranges::view::all(
recent->v
) | ranges::view::transform([&](MTPint userId) {
return _owner->userLoaded(userId.v);
}) | ranges::view::filter([](UserData *user) {
return user != nullptr;
}) | ranges::view::transform([](UserData *user) {
return not_null<UserData*>(user);
}) | ranges::to_vector;
}
}
if (!changed) {
return false;
}
@ -112,7 +136,7 @@ void PollData::checkResultsReload(not_null<HistoryItem*> item, crl::time now) {
return;
}
lastResultsUpdate = now;
Auth().api().reloadPollResults(item);
_owner->session().api().reloadPollResults(item);
}
PollAnswer *PollData::answerByOption(const QByteArray &option) {

View file

@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Data {
class Session;
} // namespace Data
struct PollAnswer {
QString text;
QByteArray option;
@ -25,7 +29,7 @@ inline bool operator!=(const PollAnswer &a, const PollAnswer &b) {
}
struct PollData {
explicit PollData(PollId id);
PollData(not_null<Data::Session*> owner, PollId id);
enum class Flag {
Closed = 0x01,
@ -54,6 +58,7 @@ struct PollData {
PollId id = 0;
QString question;
std::vector<PollAnswer> answers;
std::vector<not_null<UserData*>> recentVoters;
int totalVoters = 0;
QByteArray sendingVote;
crl::time lastResultsUpdate = 0;
@ -67,6 +72,7 @@ private:
const MTPPollAnswerVoters &result,
bool isMinResults);
not_null<Data::Session*> _owner;
Flags _flags = Flags();
};

View file

@ -2895,7 +2895,7 @@ void Session::gameApplyFields(
not_null<PollData*> Session::poll(PollId id) {
auto i = _polls.find(id);
if (i == _polls.cend()) {
i = _polls.emplace(id, std::make_unique<PollData>(id)).first;
i = _polls.emplace(id, std::make_unique<PollData>(this, id)).first;
}
return i->second.get();
}

View file

@ -534,9 +534,9 @@ historyPollQuestionStyle: TextStyle(defaultTextStyle) {
}
historyPollAnswerStyle: defaultTextStyle;
historyPollQuestionTop: 7px;
historyPollSubtitleSkip: 2px;
historyPollSubtitleSkip: 4px;
historyPollAnswerPadding: margins(31px, 10px, 0px, 10px);
historyPollAnswersSkip: 3px;
historyPollAnswersSkip: 2px;
historyPollPercentFont: semiboldFont;
historyPollPercentSkip: 6px;
historyPollPercentTop: 0px;
@ -570,6 +570,9 @@ historyPollRippleOut: RippleAnimation(defaultRippleAnimation) {
color: msgWaveformOutInactive;
}
historyPollRippleOpacity: 0.3;
historyPollRecentVotersSkip: 4px;
historyPollRecentVoterSize: 18px;
historyPollRecentVoterSkip: 13px;
boxAttachEmoji: IconButton(historyAttachEmoji) {
width: 30px;

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "data/data_media_types.h"
#include "data/data_poll.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "layout.h"
#include "main/main_session.h"
@ -29,6 +30,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
namespace {
constexpr auto kShowRecentVotersCount = 3;
struct PercentCounterItem {
int index = 0;
int percent = 0;
@ -331,7 +334,7 @@ void Poll::updateTexts() {
? tr::lng_polls_public(tr::now)
: tr::lng_polls_anonymous(tr::now))));
}
updateRecentVoters();
updateAnswers();
updateVotes();
@ -340,6 +343,16 @@ void Poll::updateTexts() {
}
}
void Poll::updateRecentVoters() {
auto &&sliced = ranges::view::all(
_poll->recentVoters
) | ranges::view::take(kShowRecentVotersCount);
const auto changed = !ranges::equal(_recentVoters, sliced);
if (changed) {
_recentVoters = sliced | ranges::to_vector;
}
}
void Poll::updateAnswers() {
const auto changed = !ranges::equal(
_answers,
@ -501,6 +514,7 @@ void Poll::draw(Painter &p, const QRect &r, TextSelection selection, crl::time m
p.setPen(regular);
_subtitle.drawLeftElided(p, padding.left(), tshift, paintw, width());
paintRecentVoters(p, padding.left() + _subtitle.maxWidth(), tshift, selection);
tshift += st::msgDateFont->height + st::historyPollAnswersSkip;
const auto progress = _answersAnimation
@ -560,6 +574,36 @@ void Poll::radialAnimationCallback() const {
}
}
void Poll::paintRecentVoters(
Painter &p,
int left,
int top,
TextSelection selection) const {
const auto count = int(_recentVoters.size());
if (!count) {
return;
}
auto x = left
+ st::historyPollRecentVotersSkip
+ (count - 1) * st::historyPollRecentVoterSkip;
auto y = top;
const auto size = st::historyPollRecentVoterSize;
const auto outbg = _parent->hasOutLayout();
const auto selected = (selection == FullSelection);
auto pen = (selected
? (outbg ? st::msgOutBgSelected : st::msgInBgSelected)
: (outbg ? st::msgOutBg : st::msgInBg))->p;
pen.setWidth(st::lineWidth);
for (const auto &recent : _recentVoters) {
recent->paintUserpic(p, x, y, size);
p.setPen(pen);
p.setBrush(Qt::NoBrush);
PainterHighQualityEnabler hq(p);
p.drawEllipse(x, y, size, size);
x -= st::historyPollRecentVoterSkip;
}
}
int Poll::paintAnswer(
Painter &p,
const Answer &answer,

View file

@ -62,6 +62,7 @@ private:
[[nodiscard]] ClickHandlerPtr createAnswerClickHandler(
const Answer &answer) const;
void updateTexts();
void updateRecentVoters();
void updateAnswers();
void updateVotes();
void updateTotalVotes();
@ -73,6 +74,11 @@ private:
int maxVotes);
void checkSendingAnimation() const;
void paintRecentVoters(
Painter &p,
int left,
int top,
TextSelection selection) const;
int paintAnswer(
Painter &p,
const Answer &answer,
@ -124,6 +130,9 @@ private:
Ui::Text::String _question;
Ui::Text::String _subtitle;
std::vector<not_null<UserData*>> _recentVoters;
QImage _recentVotersImage;
std::vector<Answer> _answers;
Ui::Text::String _totalVotesLabel;