From 3cb76fb80b259211a41d87720fcf105bb090e606 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 7 Apr 2020 16:10:34 +0400 Subject: [PATCH] Support poll closing by date. --- Telegram/SourceFiles/data/data_poll.cpp | 18 +++++++++++++- Telegram/SourceFiles/data/data_poll.h | 5 ++-- Telegram/SourceFiles/data/data_session.cpp | 28 ++++++++++++++++++++++ Telegram/SourceFiles/data/data_session.h | 5 ++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index de7509bbf..95a75d9ce 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -43,6 +43,15 @@ PollData::PollData(not_null owner, PollId id) , _owner(owner) { } +bool PollData::closeByTimer() { + if (closed()) { + return false; + } + _flags |= Flag::Closed; + ++version; + return true; +} + bool PollData::applyChanges(const MTPDpoll &poll) { Expects(poll.vid().v == id); @@ -51,6 +60,8 @@ bool PollData::applyChanges(const MTPDpoll &poll) { | (poll.is_public_voters() ? Flag::PublicVotes : Flag(0)) | (poll.is_multiple_choice() ? Flag::MultiChoice : Flag(0)) | (poll.is_quiz() ? Flag::Quiz : Flag(0)); + const auto newCloseDate = poll.vclose_date().value_or_empty(); + const auto newClosePeriod = poll.vclose_period().value_or_empty(); auto newAnswers = ranges::view::all( poll.vanswers().v ) | ranges::view::transform([](const MTPPollAnswer &data) { @@ -65,6 +76,8 @@ bool PollData::applyChanges(const MTPDpoll &poll) { ) | ranges::to_vector; const auto changed1 = (question != newQuestion) + || (closeDate != newCloseDate) + || (closePeriod != newClosePeriod) || (_flags != newFlags); const auto changed2 = (answers != newAnswers); if (!changed1 && !changed2) { @@ -72,6 +85,8 @@ bool PollData::applyChanges(const MTPDpoll &poll) { } if (changed1) { question = newQuestion; + closeDate = newCloseDate; + closePeriod = newClosePeriod; _flags = newFlags; } if (changed2) { @@ -238,7 +253,8 @@ MTPPoll PollDataToMTP(not_null poll, bool close) { | (poll->multiChoice() ? Flag::f_multiple_choice : Flag(0)) | (poll->publicVotes() ? Flag::f_public_voters : Flag(0)) | (poll->quiz() ? Flag::f_quiz : Flag(0)) - | (poll->closePeriod > 0 ? Flag::f_close_period : Flag(0)); + | (poll->closePeriod > 0 ? Flag::f_close_period : Flag(0)) + | (poll->closeDate > 0 ? Flag::f_close_date : Flag(0)); return MTP_poll( MTP_long(poll->id), MTP_flags(flags), diff --git a/Telegram/SourceFiles/data/data_poll.h b/Telegram/SourceFiles/data/data_poll.h index ded89a318..db582bf7e 100644 --- a/Telegram/SourceFiles/data/data_poll.h +++ b/Telegram/SourceFiles/data/data_poll.h @@ -40,6 +40,7 @@ struct PollData { friend inline constexpr bool is_flag_type(Flag) { return true; }; using Flags = base::flags; + bool closeByTimer(); bool applyChanges(const MTPDpoll &poll); bool applyResults(const MTPPollResults &results); void checkResultsReload(not_null item, crl::time now); @@ -63,8 +64,8 @@ struct PollData { std::vector sendingVotes; crl::time lastResultsUpdate = 0; TextWithEntities solution; - TimeId closePeriod = -1; - TimeId closeDate = -1; + TimeId closePeriod = 0; + TimeId closeDate = 0; int totalVoters = 0; int version = 0; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index b3cf55211..43e529815 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -191,6 +191,7 @@ Session::Session(not_null session) , _sendActionsAnimation([=](crl::time now) { return sendActionsAnimationCallback(now); }) +, _pollsClosingTimer([=] { checkPollsClosings(); }) , _unmuteByFinishedTimer([=] { unmuteByFinished(); }) , _groups(this) , _chatsFilters(std::make_unique(this)) @@ -2877,6 +2878,10 @@ not_null Session::processPoll(const MTPPoll &data) { if (changed) { notifyPollUpdateDelayed(result); } + if (result->closeDate > 0 && !result->closed()) { + _pollsClosings.emplace(result->closeDate, result); + checkPollsClosings(); + } return result; }); } @@ -2890,6 +2895,29 @@ not_null Session::processPoll(const MTPDmessageMediaPoll &data) { return result; } +void Session::checkPollsClosings() { + const auto now = base::unixtime::now(); + auto closest = 0; + for (auto i = _pollsClosings.begin(); i != _pollsClosings.end();) { + if (i->first <= now) { + if (i->second->closeByTimer()) { + notifyPollUpdateDelayed(i->second); + } + i = _pollsClosings.erase(i); + } else { + if (!closest) { + closest = i->first; + } + ++i; + } + } + if (closest) { + _pollsClosingTimer.callOnce((closest - now) * crl::time(1000)); + } else { + _pollsClosingTimer.cancel(); + } +} + void Session::applyUpdate(const MTPDupdateMessagePoll &update) { const auto updated = [&] { const auto poll = update.vpoll(); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 4b1eb9025..0b591b3c3 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -822,6 +822,8 @@ private: void setWallpapers(const QVector &data, int32 hash); + void checkPollsClosings(); + not_null _session; Storage::DatabasePointer _cache; @@ -943,6 +945,9 @@ private: base::flat_set> _gamesUpdated; base::flat_set> _pollsUpdated; + base::flat_multi_map> _pollsClosings; + base::Timer _pollsClosingTimer; + base::flat_map> _folders; //rpl::variable _defaultFeedId = FeedId(); // #feed