mirror of https://github.com/procxx/kepka.git
Show progress left to close by timer in polls.
This commit is contained in:
parent
423daecbde
commit
71637d2a0e
Binary file not shown.
After Width: | Height: | Size: 409 B |
Binary file not shown.
After Width: | Height: | Size: 819 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -622,6 +622,10 @@ historyQuizExplainIn: icon {{ "quiz_explain", msgInDateFg }};
|
||||||
historyQuizExplainInSelected: icon {{ "quiz_explain", msgInDateFgSelected }};
|
historyQuizExplainInSelected: icon {{ "quiz_explain", msgInDateFgSelected }};
|
||||||
historyQuizExplainOut: icon {{ "quiz_explain", msgOutDateFg }};
|
historyQuizExplainOut: icon {{ "quiz_explain", msgOutDateFg }};
|
||||||
historyQuizExplainOutSelected: icon {{ "quiz_explain", msgOutDateFgSelected }};
|
historyQuizExplainOutSelected: icon {{ "quiz_explain", msgOutDateFgSelected }};
|
||||||
|
historyQuizTimerIn: icon {{ "quiz_timer", msgInDateFg }};
|
||||||
|
historyQuizTimerInSelected: icon {{ "quiz_timer", msgInDateFgSelected }};
|
||||||
|
historyQuizTimerOut: icon {{ "quiz_timer", msgOutDateFg }};
|
||||||
|
historyQuizTimerOutSelected: icon {{ "quiz_timer", msgOutDateFgSelected }};
|
||||||
|
|
||||||
historySlowmodeCounterMargins: margins(0px, 0px, 10px, 0px);
|
historySlowmodeCounterMargins: margins(0px, 0px, 10px, 0px);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_poll.h"
|
#include "data/data_poll.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "base/unixtime.h"
|
||||||
|
#include "base/timer.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -40,6 +42,8 @@ constexpr auto kRotateAmplitude = 3.;
|
||||||
constexpr auto kScaleSegments = 2;
|
constexpr auto kScaleSegments = 2;
|
||||||
constexpr auto kScaleAmplitude = 0.03;
|
constexpr auto kScaleAmplitude = 0.03;
|
||||||
constexpr auto kRollDuration = crl::time(400);
|
constexpr auto kRollDuration = crl::time(400);
|
||||||
|
constexpr auto kLargestRadialDuration = 30 * crl::time(1000);
|
||||||
|
constexpr auto kCriticalCloseDuration = 5 * crl::time(1000);
|
||||||
|
|
||||||
struct PercentCounterItem {
|
struct PercentCounterItem {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -170,6 +174,16 @@ struct Poll::Answer {
|
||||||
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Poll::CloseInformation {
|
||||||
|
CloseInformation(TimeId date, TimeId period, Fn<void()> repaint);
|
||||||
|
|
||||||
|
crl::time start = 0;
|
||||||
|
crl::time finish = 0;
|
||||||
|
crl::time duration = 0;
|
||||||
|
base::Timer timer;
|
||||||
|
Ui::Animations::Basic radial;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
Poll::SendingAnimation::SendingAnimation(
|
Poll::SendingAnimation::SendingAnimation(
|
||||||
const QByteArray &option,
|
const QByteArray &option,
|
||||||
|
@ -197,6 +211,16 @@ void Poll::Answer::fillData(
|
||||||
Ui::WebpageTextTitleOptions());
|
Ui::WebpageTextTitleOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Poll::CloseInformation::CloseInformation(
|
||||||
|
TimeId date,
|
||||||
|
TimeId period,
|
||||||
|
Fn<void()> repaint)
|
||||||
|
: duration(period * crl::time(1000))
|
||||||
|
, timer(std::move(repaint)) {
|
||||||
|
const auto left = std::clamp(date - base::unixtime::now(), 0, period);
|
||||||
|
finish = crl::now() + left * crl::time(1000);
|
||||||
|
}
|
||||||
|
|
||||||
Poll::Poll(
|
Poll::Poll(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
not_null<PollData*> poll)
|
not_null<PollData*> poll)
|
||||||
|
@ -676,6 +700,7 @@ void Poll::draw(Painter &p, const QRect &r, TextSelection selection, crl::time m
|
||||||
p.setPen(regular);
|
p.setPen(regular);
|
||||||
_subtitle.drawLeftElided(p, padding.left(), tshift, paintw, width());
|
_subtitle.drawLeftElided(p, padding.left(), tshift, paintw, width());
|
||||||
paintRecentVoters(p, padding.left() + _subtitle.maxWidth(), tshift, selection);
|
paintRecentVoters(p, padding.left() + _subtitle.maxWidth(), tshift, selection);
|
||||||
|
paintCloseByTimer(p, padding.left() + paintw, tshift, selection);
|
||||||
paintShowSolution(p, padding.left() + paintw, tshift, selection);
|
paintShowSolution(p, padding.left() + paintw, tshift, selection);
|
||||||
tshift += st::msgDateFont->height + st::historyPollAnswersSkip;
|
tshift += st::msgDateFont->height + st::historyPollAnswersSkip;
|
||||||
|
|
||||||
|
@ -823,6 +848,80 @@ void Poll::paintRecentVoters(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Poll::paintCloseByTimer(
|
||||||
|
Painter &p,
|
||||||
|
int right,
|
||||||
|
int top,
|
||||||
|
TextSelection selection) const {
|
||||||
|
if (!canVote() || _poll->closeDate <= 0 || _poll->closePeriod <= 0) {
|
||||||
|
_close = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_close) {
|
||||||
|
_close = std::make_unique<CloseInformation>(
|
||||||
|
_poll->closeDate,
|
||||||
|
_poll->closePeriod,
|
||||||
|
[=] { history()->owner().requestViewRepaint(_parent); });
|
||||||
|
}
|
||||||
|
const auto now = crl::now();
|
||||||
|
const auto left = std::max(_close->finish - now, crl::time(0));
|
||||||
|
const auto radial = std::min(_close->duration, kLargestRadialDuration);
|
||||||
|
if (!left) {
|
||||||
|
_close->radial.stop();
|
||||||
|
} else if (left < radial && !anim::Disabled()) {
|
||||||
|
if (!_close->radial.animating()) {
|
||||||
|
_close->radial.init([=] {
|
||||||
|
history()->owner().requestViewRepaint(_parent);
|
||||||
|
});
|
||||||
|
_close->radial.start();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_close->radial.stop();
|
||||||
|
}
|
||||||
|
const auto time = formatDurationText(int(std::ceil(left / 1000.)));
|
||||||
|
const auto outbg = _parent->hasOutLayout();
|
||||||
|
const auto selected = (selection == FullSelection);
|
||||||
|
const auto &icon = selected
|
||||||
|
? (outbg
|
||||||
|
? st::historyQuizTimerOutSelected
|
||||||
|
: st::historyQuizTimerInSelected)
|
||||||
|
: (outbg ? st::historyQuizTimerOut : st::historyQuizTimerIn);
|
||||||
|
const auto x = right - icon.width();
|
||||||
|
const auto y = top
|
||||||
|
+ (st::normalFont->height - icon.height()) / 2
|
||||||
|
- st::lineWidth;
|
||||||
|
const auto ®ular = (left < kCriticalCloseDuration)
|
||||||
|
? st::boxTextFgError
|
||||||
|
: selected
|
||||||
|
? (outbg ? st::msgOutDateFgSelected : st::msgInDateFgSelected)
|
||||||
|
: (outbg ? st::msgOutDateFg : st::msgInDateFg);
|
||||||
|
p.setPen(regular);
|
||||||
|
const auto timeWidth = st::normalFont->width(time);
|
||||||
|
p.drawTextLeft(x - timeWidth, top, width(), time, timeWidth);
|
||||||
|
if (left < radial) {
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
const auto part = std::max(
|
||||||
|
left / float64(radial),
|
||||||
|
1. / FullArcLength);
|
||||||
|
const auto length = int(std::round(FullArcLength * part));
|
||||||
|
auto pen = regular->p;
|
||||||
|
pen.setWidth(st::historyPollRadio.thickness);
|
||||||
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
|
p.setPen(pen);
|
||||||
|
const auto size = icon.width() / 2;
|
||||||
|
const auto left = (x + (icon.width() - size) / 2);
|
||||||
|
const auto top = (y + (icon.height() - size) / 2) + st::lineWidth;
|
||||||
|
p.drawArc(left, top, size, size, (FullArcLength / 4), length);
|
||||||
|
} else {
|
||||||
|
icon.paint(p, x, y, width());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left > (anim::Disabled() ? 0 : (radial - 1))) {
|
||||||
|
const auto next = (left % 1000);
|
||||||
|
_close->timer.callOnce((next ? next : 1000) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Poll::paintShowSolution(
|
void Poll::paintShowSolution(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int right,
|
int right,
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
Poll(
|
Poll(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
not_null<PollData*> poll);
|
not_null<PollData*> poll);
|
||||||
|
~Poll();
|
||||||
|
|
||||||
void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override;
|
void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override;
|
||||||
TextState textState(QPoint point, StateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
@ -53,13 +54,12 @@ public:
|
||||||
const ClickHandlerPtr &handler,
|
const ClickHandlerPtr &handler,
|
||||||
bool pressed) override;
|
bool pressed) override;
|
||||||
|
|
||||||
~Poll();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AnswerAnimation;
|
struct AnswerAnimation;
|
||||||
struct AnswersAnimation;
|
struct AnswersAnimation;
|
||||||
struct SendingAnimation;
|
struct SendingAnimation;
|
||||||
struct Answer;
|
struct Answer;
|
||||||
|
struct CloseInformation;
|
||||||
|
|
||||||
QSize countOptimalSize() override;
|
QSize countOptimalSize() override;
|
||||||
QSize countCurrentSize(int newWidth) override;
|
QSize countCurrentSize(int newWidth) override;
|
||||||
|
@ -96,6 +96,11 @@ private:
|
||||||
int left,
|
int left,
|
||||||
int top,
|
int top,
|
||||||
TextSelection selection) const;
|
TextSelection selection) const;
|
||||||
|
void paintCloseByTimer(
|
||||||
|
Painter &p,
|
||||||
|
int right,
|
||||||
|
int top,
|
||||||
|
TextSelection selection) const;
|
||||||
void paintShowSolution(
|
void paintShowSolution(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int right,
|
int right,
|
||||||
|
@ -194,6 +199,8 @@ private:
|
||||||
Ui::Animations::Simple _wrongAnswerAnimation;
|
Ui::Animations::Simple _wrongAnswerAnimation;
|
||||||
mutable QPoint _lastLinkPoint;
|
mutable QPoint _lastLinkPoint;
|
||||||
|
|
||||||
|
mutable std::unique_ptr<CloseInformation> _close;
|
||||||
|
|
||||||
bool _hasSelected = false;
|
bool _hasSelected = false;
|
||||||
bool _votedFromHere = false;
|
bool _votedFromHere = false;
|
||||||
mutable bool _wrongAnswerAnimated = false;
|
mutable bool _wrongAnswerAnimated = false;
|
||||||
|
|
Loading…
Reference in New Issue