Support MessageSenders as poll voters.
This commit is contained in:
parent
48d72677d3
commit
38efb6d673
@ -497,13 +497,13 @@ webApp short_name:string title:string description:string photo:photo animation:a
|
|||||||
//@question Poll question; 1-300 characters
|
//@question Poll question; 1-300 characters
|
||||||
//@options List of poll answer options
|
//@options List of poll answer options
|
||||||
//@total_voter_count Total number of voters, participating in the poll
|
//@total_voter_count Total number of voters, participating in the poll
|
||||||
//@recent_voter_user_ids User identifiers of recent voters, if the poll is non-anonymous
|
//@recent_voter_ids Identifiers of recent voters, if the poll is non-anonymous
|
||||||
//@is_anonymous True, if the poll is anonymous
|
//@is_anonymous True, if the poll is anonymous
|
||||||
//@type Type of the poll
|
//@type Type of the poll
|
||||||
//@open_period Amount of time the poll will be active after creation, in seconds
|
//@open_period Amount of time the poll will be active after creation, in seconds
|
||||||
//@close_date Point in time (Unix timestamp) when the poll will automatically be closed
|
//@close_date Point in time (Unix timestamp) when the poll will automatically be closed
|
||||||
//@is_closed True, if the poll is closed
|
//@is_closed True, if the poll is closed
|
||||||
poll id:int64 question:string options:vector<pollOption> total_voter_count:int32 recent_voter_user_ids:vector<int53> is_anonymous:Bool type:PollType open_period:int32 close_date:int32 is_closed:Bool = Poll;
|
poll id:int64 question:string options:vector<pollOption> total_voter_count:int32 recent_voter_ids:vector<MessageSender> is_anonymous:Bool type:PollType open_period:int32 close_date:int32 is_closed:Bool = Poll;
|
||||||
|
|
||||||
|
|
||||||
//@description Describes a chat background
|
//@description Describes a chat background
|
||||||
@ -5692,8 +5692,11 @@ updateNewCustomQuery id:int64 data:string timeout:int32 = Update;
|
|||||||
//@description A poll was updated; for bots only @poll New data about the poll
|
//@description A poll was updated; for bots only @poll New data about the poll
|
||||||
updatePoll poll:poll = Update;
|
updatePoll poll:poll = Update;
|
||||||
|
|
||||||
//@description A user changed the answer to a poll; for bots only @poll_id Unique poll identifier @user_id The user, who changed the answer to the poll @option_ids 0-based identifiers of answer options, chosen by the user
|
//@description A user changed the answer to a poll; for bots only
|
||||||
updatePollAnswer poll_id:int64 user_id:int53 option_ids:vector<int32> = Update;
|
//@poll_id Unique poll identifier
|
||||||
|
//@voter_id Identifier of the message sender that changed the answer to the poll
|
||||||
|
//@option_ids 0-based identifiers of answer options, chosen by the user
|
||||||
|
updatePollAnswer poll_id:int64 voter_id:MessageSender option_ids:vector<int32> = Update;
|
||||||
|
|
||||||
//@description User rights changed in a chat; for bots only
|
//@description User rights changed in a chat; for bots only
|
||||||
//@chat_id Chat identifier
|
//@chat_id Chat identifier
|
||||||
@ -6549,13 +6552,13 @@ getThemeParametersJsonString theme:themeParameters = Text;
|
|||||||
//@option_ids 0-based identifiers of answer options, chosen by the user. User can choose more than 1 answer option only is the poll allows multiple answers
|
//@option_ids 0-based identifiers of answer options, chosen by the user. User can choose more than 1 answer option only is the poll allows multiple answers
|
||||||
setPollAnswer chat_id:int53 message_id:int53 option_ids:vector<int32> = Ok;
|
setPollAnswer chat_id:int53 message_id:int53 option_ids:vector<int32> = Ok;
|
||||||
|
|
||||||
//@description Returns users voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib
|
//@description Returns message senders voted for the specified option in a non-anonymous polls. For optimal performance, the number of returned users is chosen by TDLib
|
||||||
//@chat_id Identifier of the chat to which the poll belongs
|
//@chat_id Identifier of the chat to which the poll belongs
|
||||||
//@message_id Identifier of the message containing the poll
|
//@message_id Identifier of the message containing the poll
|
||||||
//@option_id 0-based identifier of the answer option
|
//@option_id 0-based identifier of the answer option
|
||||||
//@offset Number of users to skip in the result; must be non-negative
|
//@offset Number of voters to skip in the result; must be non-negative
|
||||||
//@limit The maximum number of users to be returned; must be positive and can't be greater than 50. For optimal performance, the number of returned users is chosen by TDLib and can be smaller than the specified limit, even if the end of the voter list has not been reached
|
//@limit The maximum number of voters to be returned; must be positive and can't be greater than 50. For optimal performance, the number of returned voters is chosen by TDLib and can be smaller than the specified limit, even if the end of the voter list has not been reached
|
||||||
getPollVoters chat_id:int53 message_id:int53 option_id:int32 offset:int32 limit:int32 = Users;
|
getPollVoters chat_id:int53 message_id:int53 option_id:int32 offset:int32 limit:int32 = MessageSenders;
|
||||||
|
|
||||||
//@description Stops a poll. A poll in a message can be stopped when the message has can_be_edited flag set
|
//@description Stops a poll. A poll in a message can be stopped when the message has can_be_edited flag set
|
||||||
//@chat_id Identifier of the chat to which the poll belongs
|
//@chat_id Identifier of the chat to which the poll belongs
|
||||||
|
@ -3320,7 +3320,7 @@ void set_message_content_poll_answer(Td *td, const MessageContent *content, Full
|
|||||||
|
|
||||||
void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
int32 option_id, int32 offset, int32 limit,
|
int32 option_id, int32 offset, int32 limit,
|
||||||
Promise<std::pair<int32, vector<UserId>>> &&promise) {
|
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise) {
|
||||||
CHECK(content->get_type() == MessageContentType::Poll);
|
CHECK(content->get_type() == MessageContentType::Poll);
|
||||||
td->poll_manager_->get_poll_voters(static_cast<const MessagePoll *>(content)->poll_id, full_message_id, option_id,
|
td->poll_manager_->get_poll_voters(static_cast<const MessagePoll *>(content)->poll_id, full_message_id, option_id,
|
||||||
offset, limit, std::move(promise));
|
offset, limit, std::move(promise));
|
||||||
|
@ -167,7 +167,7 @@ void set_message_content_poll_answer(Td *td, const MessageContent *content, Full
|
|||||||
|
|
||||||
void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
int32 option_id, int32 offset, int32 limit,
|
int32 option_id, int32 offset, int32 limit,
|
||||||
Promise<std::pair<int32, vector<UserId>>> &&promise);
|
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
|
||||||
|
|
||||||
void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id,
|
||||||
unique_ptr<ReplyMarkup> &&reply_markup, Promise<Unit> &&promise);
|
unique_ptr<ReplyMarkup> &&reply_markup, Promise<Unit> &&promise);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/telegram/MessageReaction.h"
|
#include "td/telegram/MessageReaction.h"
|
||||||
|
#include "td/telegram/MinChannel.hpp"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
|
@ -39913,7 +39913,7 @@ void MessagesManager::set_poll_answer(FullMessageId full_message_id, vector<int3
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
||||||
Promise<std::pair<int32, vector<UserId>>> &&promise) {
|
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise) {
|
||||||
auto m = get_message_force(full_message_id, "get_poll_voters");
|
auto m = get_message_force(full_message_id, "get_poll_voters");
|
||||||
if (m == nullptr) {
|
if (m == nullptr) {
|
||||||
return promise.set_error(Status::Error(400, "Message not found"));
|
return promise.set_error(Status::Error(400, "Message not found"));
|
||||||
|
@ -1021,7 +1021,7 @@ class MessagesManager final : public Actor {
|
|||||||
void set_poll_answer(FullMessageId full_message_id, vector<int32> &&option_ids, Promise<Unit> &&promise);
|
void set_poll_answer(FullMessageId full_message_id, vector<int32> &&option_ids, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
||||||
Promise<std::pair<int32, vector<UserId>>> &&promise);
|
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
|
||||||
|
|
||||||
void stop_poll(FullMessageId full_message_id, td_api::object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
void stop_poll(FullMessageId full_message_id, td_api::object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "td/telegram/Global.h"
|
#include "td/telegram/Global.h"
|
||||||
#include "td/telegram/logevent/LogEvent.h"
|
#include "td/telegram/logevent/LogEvent.h"
|
||||||
#include "td/telegram/MessageId.h"
|
#include "td/telegram/MessageId.h"
|
||||||
|
#include "td/telegram/MessageSender.h"
|
||||||
#include "td/telegram/MessagesManager.h"
|
#include "td/telegram/MessagesManager.h"
|
||||||
#include "td/telegram/misc.h"
|
#include "td/telegram/misc.h"
|
||||||
#include "td/telegram/PollId.hpp"
|
#include "td/telegram/PollId.hpp"
|
||||||
@ -380,8 +381,17 @@ void PollManager::on_load_poll_from_database(PollId poll_id, string value) {
|
|||||||
if (log_event_parse(*poll, value).is_error()) {
|
if (log_event_parse(*poll, value).is_error()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto &user_id : poll->recent_voter_user_ids_) {
|
for (const auto &recent_voter_min_channel : poll->recent_voter_min_channels_) {
|
||||||
td_->contacts_manager_->have_user_force(user_id);
|
LOG(INFO) << "Add min voted " << recent_voter_min_channel.first;
|
||||||
|
td_->contacts_manager_->add_min_channel(recent_voter_min_channel.first, recent_voter_min_channel.second);
|
||||||
|
}
|
||||||
|
Dependencies dependencies;
|
||||||
|
for (auto dialog_id : poll->recent_voter_dialog_ids_) {
|
||||||
|
dependencies.add_message_sender_dependencies(dialog_id);
|
||||||
|
}
|
||||||
|
if (!dependencies.resolve_force(td_, "on_load_poll_from_database")) {
|
||||||
|
poll->recent_voter_dialog_ids_.clear();
|
||||||
|
poll->recent_voter_min_channels_.clear();
|
||||||
}
|
}
|
||||||
if (!poll->is_closed_ && poll->close_date_ != 0) {
|
if (!poll->is_closed_ && poll->close_date_ != 0) {
|
||||||
if (poll->close_date_ <= G()->server_time()) {
|
if (poll->close_date_ <= G()->server_time()) {
|
||||||
@ -613,10 +623,17 @@ td_api::object_ptr<td_api::poll> PollManager::get_poll_object(PollId poll_id, co
|
|||||||
open_period = 0;
|
open_period = 0;
|
||||||
close_date = 0;
|
close_date = 0;
|
||||||
}
|
}
|
||||||
return td_api::make_object<td_api::poll>(
|
|
||||||
poll_id.get(), poll->question_, std::move(poll_options), total_voter_count,
|
vector<td_api::object_ptr<td_api::MessageSender>> recent_voters;
|
||||||
td_->contacts_manager_->get_user_ids_object(poll->recent_voter_user_ids_, "get_poll_object"), poll->is_anonymous_,
|
for (auto dialog_id : poll->recent_voter_dialog_ids_) {
|
||||||
std::move(poll_type), open_period, close_date, poll->is_closed_);
|
auto recent_voter = get_min_message_sender_object(td_, dialog_id, "get_poll_object");
|
||||||
|
if (recent_voter != nullptr) {
|
||||||
|
recent_voters.push_back(std::move(recent_voter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::poll>(poll_id.get(), poll->question_, std::move(poll_options), total_voter_count,
|
||||||
|
std::move(recent_voters), poll->is_anonymous_, std::move(poll_type),
|
||||||
|
open_period, close_date, poll->is_closed_);
|
||||||
}
|
}
|
||||||
|
|
||||||
telegram_api::object_ptr<telegram_api::pollAnswer> PollManager::get_input_poll_option(const PollOption &poll_option) {
|
telegram_api::object_ptr<telegram_api::pollAnswer> PollManager::get_input_poll_option(const PollOption &poll_option) {
|
||||||
@ -1014,8 +1031,21 @@ PollManager::PollOptionVoters &PollManager::get_poll_option_voters(const Poll *p
|
|||||||
return poll_voters[index];
|
return poll_voters[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::messageSenders> PollManager::get_poll_voters_object(
|
||||||
|
int32 total_count, const vector<DialogId> &voter_dialog_ids) const {
|
||||||
|
auto result = td_api::make_object<td_api::messageSenders>();
|
||||||
|
result->total_count_ = total_count;
|
||||||
|
for (auto dialog_id : voter_dialog_ids) {
|
||||||
|
auto message_sender = get_min_message_sender_object(td_, dialog_id, "get_poll_voters_object");
|
||||||
|
if (message_sender != nullptr) {
|
||||||
|
result->senders_.push_back(std::move(message_sender));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset,
|
void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset,
|
||||||
int32 limit, Promise<std::pair<int32, vector<UserId>>> &&promise) {
|
int32 limit, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise) {
|
||||||
if (is_local_poll_id(poll_id)) {
|
if (is_local_poll_id(poll_id)) {
|
||||||
return promise.set_error(Status::Error(400, "Poll results can't be received"));
|
return promise.set_error(Status::Error(400, "Poll results can't be received"));
|
||||||
}
|
}
|
||||||
@ -1040,26 +1070,27 @@ void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id,
|
|||||||
|
|
||||||
auto &voters = get_poll_option_voters(poll, poll_id, option_id);
|
auto &voters = get_poll_option_voters(poll, poll_id, option_id);
|
||||||
if (voters.pending_queries_.empty() && voters.was_invalidated_ && offset == 0) {
|
if (voters.pending_queries_.empty() && voters.was_invalidated_ && offset == 0) {
|
||||||
voters.voter_user_ids_.clear();
|
voters.voter_dialog_ids_.clear();
|
||||||
voters.next_offset_.clear();
|
voters.next_offset_.clear();
|
||||||
voters.was_invalidated_ = false;
|
voters.was_invalidated_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cur_offset = narrow_cast<int32>(voters.voter_user_ids_.size());
|
auto cur_offset = narrow_cast<int32>(voters.voter_dialog_ids_.size());
|
||||||
|
|
||||||
if (offset > cur_offset) {
|
if (offset > cur_offset) {
|
||||||
return promise.set_error(Status::Error(400, "Too big offset specified; voters can be received only consequently"));
|
return promise.set_error(Status::Error(400, "Too big offset specified; voters can be received only consequently"));
|
||||||
}
|
}
|
||||||
if (offset < cur_offset) {
|
if (offset < cur_offset) {
|
||||||
vector<UserId> result;
|
vector<DialogId> result;
|
||||||
for (int32 i = offset; i != cur_offset && i - offset < limit; i++) {
|
for (int32 i = offset; i != cur_offset && i - offset < limit; i++) {
|
||||||
result.push_back(voters.voter_user_ids_[i]);
|
result.push_back(voters.voter_dialog_ids_[i]);
|
||||||
}
|
}
|
||||||
return promise.set_value({max(poll->options_[option_id].voter_count_, cur_offset), std::move(result)});
|
return promise.set_value(
|
||||||
|
get_poll_voters_object(max(poll->options_[option_id].voter_count_, cur_offset), std::move(result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poll->options_[option_id].voter_count_ == 0 || (voters.next_offset_.empty() && cur_offset > 0)) {
|
if (poll->options_[option_id].voter_count_ == 0 || (voters.next_offset_.empty() && cur_offset > 0)) {
|
||||||
return promise.set_value({0, vector<UserId>()});
|
return promise.set_value(get_poll_voters_object(0, vector<DialogId>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
voters.pending_queries_.push_back(std::move(promise));
|
voters.pending_queries_.push_back(std::move(promise));
|
||||||
@ -1122,7 +1153,7 @@ void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, string off
|
|||||||
update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0);
|
update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UserId> user_ids;
|
vector<DialogId> dialog_ids;
|
||||||
for (auto &peer_vote : vote_list->votes_) {
|
for (auto &peer_vote : vote_list->votes_) {
|
||||||
DialogId dialog_id;
|
DialogId dialog_id;
|
||||||
switch (peer_vote->get_id()) {
|
switch (peer_vote->get_id()) {
|
||||||
@ -1153,25 +1184,23 @@ void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, string off
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
if (dialog_id.is_valid()) {
|
if (dialog_id.is_valid()) {
|
||||||
if (dialog_id.get_type() == DialogType::User) {
|
dialog_ids.push_back(dialog_id);
|
||||||
user_ids.push_back(dialog_id.get_user_id());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Receive " << dialog_id << " as voter in " << poll_id;
|
LOG(ERROR) << "Receive " << dialog_id << " as voter in " << poll_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
append(voters.voter_user_ids_, user_ids);
|
append(voters.voter_dialog_ids_, dialog_ids);
|
||||||
if (static_cast<int32>(user_ids.size()) > limit) {
|
if (static_cast<int32>(dialog_ids.size()) > limit) {
|
||||||
user_ids.resize(limit);
|
dialog_ids.resize(limit);
|
||||||
}
|
}
|
||||||
auto known_voter_count = narrow_cast<int32>(voters.voter_user_ids_.size());
|
auto known_voter_count = narrow_cast<int32>(voters.voter_dialog_ids_.size());
|
||||||
if (voters.next_offset_.empty() && known_voter_count != vote_list->count_) {
|
if (voters.next_offset_.empty() && known_voter_count != vote_list->count_) {
|
||||||
// invalidate_poll_option_voters(poll, poll_id, option_id);
|
// invalidate_poll_option_voters(poll, poll_id, option_id);
|
||||||
voters.was_invalidated_ = true;
|
voters.was_invalidated_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &promise : promises) {
|
for (auto &promise : promises) {
|
||||||
promise.set_value({max(vote_list->count_, known_voter_count), vector<UserId>(user_ids)});
|
promise.set_value(get_poll_voters_object(max(vote_list->count_, known_voter_count), vector<DialogId>(dialog_ids)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1772,28 +1801,24 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UserId> recent_voter_user_ids;
|
vector<DialogId> recent_voter_dialog_ids;
|
||||||
if (!is_bot) {
|
if (!is_bot) {
|
||||||
for (auto &peer_id : poll_results->recent_voters_) {
|
for (auto &peer_id : poll_results->recent_voters_) {
|
||||||
DialogId dialog_id(peer_id);
|
DialogId dialog_id(peer_id);
|
||||||
if (dialog_id.get_type() != DialogType::User) {
|
if (dialog_id.is_valid()) {
|
||||||
continue;
|
recent_voter_dialog_ids.push_back(dialog_id);
|
||||||
}
|
|
||||||
auto user_id = dialog_id.get_user_id();
|
|
||||||
if (user_id.is_valid()) {
|
|
||||||
recent_voter_user_ids.push_back(user_id);
|
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Receive " << user_id << " as recent voter in " << poll_id << " from " << source;
|
LOG(ERROR) << "Receive " << dialog_id << " as recent voter in " << poll_id << " from " << source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (poll->is_anonymous_ && !recent_voter_user_ids.empty()) {
|
if (poll->is_anonymous_ && !recent_voter_dialog_ids.empty()) {
|
||||||
LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_user_ids << " from "
|
LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_dialog_ids << " from "
|
||||||
<< source;
|
<< source;
|
||||||
recent_voter_user_ids.clear();
|
recent_voter_dialog_ids.clear();
|
||||||
}
|
}
|
||||||
if (recent_voter_user_ids != poll->recent_voter_user_ids_) {
|
if (recent_voter_dialog_ids != poll->recent_voter_dialog_ids_) {
|
||||||
poll->recent_voter_user_ids_ = std::move(recent_voter_user_ids);
|
poll->recent_voter_dialog_ids_ = std::move(recent_voter_dialog_ids);
|
||||||
invalidate_poll_voters(poll, poll_id);
|
invalidate_poll_voters(poll, poll_id);
|
||||||
is_changed = true;
|
is_changed = true;
|
||||||
}
|
}
|
||||||
@ -1817,13 +1842,13 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
return poll_id;
|
return poll_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::on_get_poll_vote(PollId poll_id, UserId user_id, vector<BufferSlice> &&options) {
|
void PollManager::on_get_poll_vote(PollId poll_id, DialogId dialog_id, vector<BufferSlice> &&options) {
|
||||||
if (!poll_id.is_valid()) {
|
if (!poll_id.is_valid()) {
|
||||||
LOG(ERROR) << "Receive updateMessagePollVote about invalid " << poll_id;
|
LOG(ERROR) << "Receive updateMessagePollVote about invalid " << poll_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!user_id.is_valid()) {
|
if (!dialog_id.is_valid()) {
|
||||||
LOG(ERROR) << "Receive updateMessagePollVote from invalid " << user_id;
|
LOG(ERROR) << "Receive updateMessagePollVote from invalid " << dialog_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!td_->auth_manager_->is_bot()) {
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
@ -1840,10 +1865,10 @@ void PollManager::on_get_poll_vote(PollId poll_id, UserId user_id, vector<Buffer
|
|||||||
option_ids.push_back(static_cast<int32>(slice[0] - '0'));
|
option_ids.push_back(static_cast<int32>(slice[0] - '0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
send_closure(G()->td(), &Td::send_update,
|
send_closure(
|
||||||
|
G()->td(), &Td::send_update,
|
||||||
td_api::make_object<td_api::updatePollAnswer>(
|
td_api::make_object<td_api::updatePollAnswer>(
|
||||||
poll_id.get(), td_->contacts_manager_->get_user_id_object(user_id, "on_get_poll_vote"),
|
poll_id.get(), get_message_sender_object(td_, dialog_id, "on_get_poll_vote"), std::move(option_ids)));
|
||||||
std::move(option_ids)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
void PollManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||||
|
@ -6,14 +6,15 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/DialogId.h"
|
||||||
#include "td/telegram/FullMessageId.h"
|
#include "td/telegram/FullMessageId.h"
|
||||||
#include "td/telegram/MessageEntity.h"
|
#include "td/telegram/MessageEntity.h"
|
||||||
|
#include "td/telegram/MinChannel.h"
|
||||||
#include "td/telegram/net/NetQuery.h"
|
#include "td/telegram/net/NetQuery.h"
|
||||||
#include "td/telegram/PollId.h"
|
#include "td/telegram/PollId.h"
|
||||||
#include "td/telegram/ReplyMarkup.h"
|
#include "td/telegram/ReplyMarkup.h"
|
||||||
#include "td/telegram/td_api.h"
|
#include "td/telegram/td_api.h"
|
||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
#include "td/telegram/UserId.h"
|
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
#include "td/actor/MultiTimeout.h"
|
#include "td/actor/MultiTimeout.h"
|
||||||
@ -65,7 +66,7 @@ class PollManager final : public Actor {
|
|||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
void get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
void get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit,
|
||||||
Promise<std::pair<int32, vector<UserId>>> &&promise);
|
Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
|
||||||
|
|
||||||
void stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr<ReplyMarkup> &&reply_markup,
|
void stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr<ReplyMarkup> &&reply_markup,
|
||||||
Promise<Unit> &&promise);
|
Promise<Unit> &&promise);
|
||||||
@ -81,7 +82,7 @@ class PollManager final : public Actor {
|
|||||||
PollId on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
PollId on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
||||||
tl_object_ptr<telegram_api::pollResults> &&poll_results, const char *source);
|
tl_object_ptr<telegram_api::pollResults> &&poll_results, const char *source);
|
||||||
|
|
||||||
void on_get_poll_vote(PollId poll_id, UserId user_id, vector<BufferSlice> &&options);
|
void on_get_poll_vote(PollId poll_id, DialogId dialog_id, vector<BufferSlice> &&options);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::poll> get_poll_object(PollId poll_id) const;
|
td_api::object_ptr<td_api::poll> get_poll_object(PollId poll_id) const;
|
||||||
|
|
||||||
@ -111,7 +112,8 @@ class PollManager final : public Actor {
|
|||||||
struct Poll {
|
struct Poll {
|
||||||
string question_;
|
string question_;
|
||||||
vector<PollOption> options_;
|
vector<PollOption> options_;
|
||||||
vector<UserId> recent_voter_user_ids_;
|
vector<DialogId> recent_voter_dialog_ids_;
|
||||||
|
vector<std::pair<ChannelId, MinChannel>> recent_voter_min_channels_;
|
||||||
FormattedText explanation_;
|
FormattedText explanation_;
|
||||||
int32 total_voter_count_ = 0;
|
int32 total_voter_count_ = 0;
|
||||||
int32 correct_option_id_ = -1;
|
int32 correct_option_id_ = -1;
|
||||||
@ -131,9 +133,9 @@ class PollManager final : public Actor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PollOptionVoters {
|
struct PollOptionVoters {
|
||||||
vector<UserId> voter_user_ids_;
|
vector<DialogId> voter_dialog_ids_;
|
||||||
string next_offset_;
|
string next_offset_;
|
||||||
vector<Promise<std::pair<int32, vector<UserId>>>> pending_queries_;
|
vector<Promise<td_api::object_ptr<td_api::messageSenders>>> pending_queries_;
|
||||||
bool was_invalidated_ = false; // the list needs to be invalidated when voters are changed
|
bool was_invalidated_ = false; // the list needs to be invalidated when voters are changed
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,6 +211,9 @@ class PollManager final : public Actor {
|
|||||||
|
|
||||||
PollOptionVoters &get_poll_option_voters(const Poll *poll, PollId poll_id, int32 option_id);
|
PollOptionVoters &get_poll_option_voters(const Poll *poll, PollId poll_id, int32 option_id);
|
||||||
|
|
||||||
|
td_api::object_ptr<td_api::messageSenders> get_poll_voters_object(int32 total_count,
|
||||||
|
const vector<DialogId> &voter_dialog_ids) const;
|
||||||
|
|
||||||
void on_get_poll_voters(PollId poll_id, int32 option_id, string offset, int32 limit,
|
void on_get_poll_voters(PollId poll_id, int32 option_id, string offset, int32 limit,
|
||||||
Result<tl_object_ptr<telegram_api::messages_votesList>> &&result);
|
Result<tl_object_ptr<telegram_api::messages_votesList>> &&result);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/telegram/MinChannel.hpp"
|
||||||
#include "td/telegram/PollManager.h"
|
#include "td/telegram/PollManager.h"
|
||||||
#include "td/telegram/Version.h"
|
#include "td/telegram/Version.h"
|
||||||
|
|
||||||
@ -43,20 +44,23 @@ template <class StorerT>
|
|||||||
void PollManager::Poll::store(StorerT &storer) const {
|
void PollManager::Poll::store(StorerT &storer) const {
|
||||||
using ::td::store;
|
using ::td::store;
|
||||||
bool is_public = !is_anonymous_;
|
bool is_public = !is_anonymous_;
|
||||||
bool has_recent_voters = !recent_voter_user_ids_.empty();
|
|
||||||
bool has_open_period = open_period_ != 0;
|
bool has_open_period = open_period_ != 0;
|
||||||
bool has_close_date = close_date_ != 0;
|
bool has_close_date = close_date_ != 0;
|
||||||
bool has_explanation = !explanation_.text.empty();
|
bool has_explanation = !explanation_.text.empty();
|
||||||
|
bool has_recent_voter_dialog_ids = !recent_voter_dialog_ids_.empty();
|
||||||
|
bool has_recent_voter_min_channels = !recent_voter_min_channels_.empty();
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(is_closed_);
|
STORE_FLAG(is_closed_);
|
||||||
STORE_FLAG(is_public);
|
STORE_FLAG(is_public);
|
||||||
STORE_FLAG(allow_multiple_answers_);
|
STORE_FLAG(allow_multiple_answers_);
|
||||||
STORE_FLAG(is_quiz_);
|
STORE_FLAG(is_quiz_);
|
||||||
STORE_FLAG(has_recent_voters);
|
STORE_FLAG(false);
|
||||||
STORE_FLAG(has_open_period);
|
STORE_FLAG(has_open_period);
|
||||||
STORE_FLAG(has_close_date);
|
STORE_FLAG(has_close_date);
|
||||||
STORE_FLAG(has_explanation);
|
STORE_FLAG(has_explanation);
|
||||||
STORE_FLAG(is_updated_after_close_);
|
STORE_FLAG(is_updated_after_close_);
|
||||||
|
STORE_FLAG(has_recent_voter_dialog_ids);
|
||||||
|
STORE_FLAG(has_recent_voter_min_channels);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
|
|
||||||
store(question_, storer);
|
store(question_, storer);
|
||||||
@ -65,9 +69,6 @@ void PollManager::Poll::store(StorerT &storer) const {
|
|||||||
if (is_quiz_) {
|
if (is_quiz_) {
|
||||||
store(correct_option_id_, storer);
|
store(correct_option_id_, storer);
|
||||||
}
|
}
|
||||||
if (has_recent_voters) {
|
|
||||||
store(recent_voter_user_ids_, storer);
|
|
||||||
}
|
|
||||||
if (has_open_period) {
|
if (has_open_period) {
|
||||||
store(open_period_, storer);
|
store(open_period_, storer);
|
||||||
}
|
}
|
||||||
@ -77,26 +78,36 @@ void PollManager::Poll::store(StorerT &storer) const {
|
|||||||
if (has_explanation) {
|
if (has_explanation) {
|
||||||
store(explanation_, storer);
|
store(explanation_, storer);
|
||||||
}
|
}
|
||||||
|
if (has_recent_voter_dialog_ids) {
|
||||||
|
store(recent_voter_dialog_ids_, storer);
|
||||||
|
}
|
||||||
|
if (has_recent_voter_min_channels) {
|
||||||
|
store(recent_voter_min_channels_, storer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void PollManager::Poll::parse(ParserT &parser) {
|
void PollManager::Poll::parse(ParserT &parser) {
|
||||||
using ::td::parse;
|
using ::td::parse;
|
||||||
bool is_public;
|
bool is_public;
|
||||||
bool has_recent_voters;
|
bool has_recent_voter_user_ids;
|
||||||
bool has_open_period;
|
bool has_open_period;
|
||||||
bool has_close_date;
|
bool has_close_date;
|
||||||
bool has_explanation;
|
bool has_explanation;
|
||||||
|
bool has_recent_voter_dialog_ids;
|
||||||
|
bool has_recent_voter_min_channels;
|
||||||
BEGIN_PARSE_FLAGS();
|
BEGIN_PARSE_FLAGS();
|
||||||
PARSE_FLAG(is_closed_);
|
PARSE_FLAG(is_closed_);
|
||||||
PARSE_FLAG(is_public);
|
PARSE_FLAG(is_public);
|
||||||
PARSE_FLAG(allow_multiple_answers_);
|
PARSE_FLAG(allow_multiple_answers_);
|
||||||
PARSE_FLAG(is_quiz_);
|
PARSE_FLAG(is_quiz_);
|
||||||
PARSE_FLAG(has_recent_voters);
|
PARSE_FLAG(has_recent_voter_user_ids);
|
||||||
PARSE_FLAG(has_open_period);
|
PARSE_FLAG(has_open_period);
|
||||||
PARSE_FLAG(has_close_date);
|
PARSE_FLAG(has_close_date);
|
||||||
PARSE_FLAG(has_explanation);
|
PARSE_FLAG(has_explanation);
|
||||||
PARSE_FLAG(is_updated_after_close_);
|
PARSE_FLAG(is_updated_after_close_);
|
||||||
|
PARSE_FLAG(has_recent_voter_dialog_ids);
|
||||||
|
PARSE_FLAG(has_recent_voter_min_channels);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
is_anonymous_ = !is_public;
|
is_anonymous_ = !is_public;
|
||||||
|
|
||||||
@ -109,8 +120,10 @@ void PollManager::Poll::parse(ParserT &parser) {
|
|||||||
parser.set_error("Wrong correct_option_id");
|
parser.set_error("Wrong correct_option_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_recent_voters) {
|
if (has_recent_voter_user_ids) {
|
||||||
parse(recent_voter_user_ids_, parser);
|
vector<UserId> recent_voter_user_ids;
|
||||||
|
parse(recent_voter_user_ids, parser);
|
||||||
|
recent_voter_dialog_ids_ = transform(recent_voter_user_ids, [](UserId user_id) { return DialogId(user_id); });
|
||||||
}
|
}
|
||||||
if (has_open_period) {
|
if (has_open_period) {
|
||||||
parse(open_period_, parser);
|
parse(open_period_, parser);
|
||||||
@ -121,6 +134,12 @@ void PollManager::Poll::parse(ParserT &parser) {
|
|||||||
if (has_explanation) {
|
if (has_explanation) {
|
||||||
parse(explanation_, parser);
|
parse(explanation_, parser);
|
||||||
}
|
}
|
||||||
|
if (has_recent_voter_dialog_ids) {
|
||||||
|
parse(recent_voter_dialog_ids_, parser);
|
||||||
|
}
|
||||||
|
if (has_recent_voter_min_channels) {
|
||||||
|
parse(recent_voter_min_channels_, parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
|
@ -7839,16 +7839,8 @@ void Td::on_request(uint64 id, td_api::setPollAnswer &request) {
|
|||||||
void Td::on_request(uint64 id, td_api::getPollVoters &request) {
|
void Td::on_request(uint64 id, td_api::getPollVoters &request) {
|
||||||
CHECK_IS_USER();
|
CHECK_IS_USER();
|
||||||
CREATE_REQUEST_PROMISE();
|
CREATE_REQUEST_PROMISE();
|
||||||
auto query_promise = PromiseCreator::lambda(
|
|
||||||
[promise = std::move(promise), td = this](Result<std::pair<int32, vector<UserId>>> result) mutable {
|
|
||||||
if (result.is_error()) {
|
|
||||||
promise.set_error(result.move_as_error());
|
|
||||||
} else {
|
|
||||||
promise.set_value(td->contacts_manager_->get_users_object(result.ok().first, result.ok().second));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
messages_manager_->get_poll_voters({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.option_id_,
|
messages_manager_->get_poll_voters({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.option_id_,
|
||||||
request.offset_, request.limit_, std::move(query_promise));
|
request.offset_, request.limit_, std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::stopPoll &request) {
|
void Td::on_request(uint64 id, td_api::stopPoll &request) {
|
||||||
|
@ -2687,10 +2687,7 @@ void UpdatesManager::process_qts_update(tl_object_ptr<telegram_api::Update> &&up
|
|||||||
case telegram_api::updateMessagePollVote::ID: {
|
case telegram_api::updateMessagePollVote::ID: {
|
||||||
auto update = move_tl_object_as<telegram_api::updateMessagePollVote>(update_ptr);
|
auto update = move_tl_object_as<telegram_api::updateMessagePollVote>(update_ptr);
|
||||||
DialogId dialog_id(update->peer_);
|
DialogId dialog_id(update->peer_);
|
||||||
if (dialog_id.get_type() == DialogType::User) {
|
td_->poll_manager_->on_get_poll_vote(PollId(update->poll_id_), dialog_id, std::move(update->options_));
|
||||||
td_->poll_manager_->on_get_poll_vote(PollId(update->poll_id_), dialog_id.get_user_id(),
|
|
||||||
std::move(update->options_));
|
|
||||||
}
|
|
||||||
add_qts(qts).set_value(Unit());
|
add_qts(qts).set_value(Unit());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user