Better getChatPinnedMessage.

GitOrigin-RevId: 092ac37109dd8e73182dd4b11a98ffe777841dc4
This commit is contained in:
levlam 2018-02-09 01:54:39 +03:00
parent 85da530056
commit 7c4ecdf650
5 changed files with 110 additions and 30 deletions

View File

@ -4213,7 +4213,8 @@ string ContactsManager::get_chat_invite_link(ChatId chat_id) const {
return chat_full->invite_link;
}
string ContactsManager::get_channel_invite_link(ChannelId channel_id) const {
string ContactsManager::get_channel_invite_link(
ChannelId channel_id) { // should be non-const to update ChannelFull cache
auto channel_full = get_channel_full(channel_id);
if (channel_full == nullptr) {
auto it = channel_invite_links_.find(channel_id);
@ -4222,7 +4223,8 @@ string ContactsManager::get_channel_invite_link(ChannelId channel_id) const {
return channel_full->invite_link;
}
MessageId ContactsManager::get_channel_pinned_message_id(ChannelId channel_id) const {
MessageId ContactsManager::get_channel_pinned_message_id(
ChannelId channel_id) { // should be non-const to update ChannelFull cache
auto channel_full = get_channel_full(channel_id);
if (channel_full == nullptr) {
return MessageId();
@ -8247,9 +8249,16 @@ ContactsManager::ChannelFull *ContactsManager::get_channel_full(ChannelId channe
auto p = channels_full_.find(channel_id);
if (p == channels_full_.end()) {
return nullptr;
} else {
return &p->second;
}
auto channel_full = &p->second;
if (channel_full->is_expired()) {
auto input_channel = get_input_channel(channel_id);
CHECK(input_channel != nullptr);
send_get_channel_full_query(channel_id, std::move(input_channel), Auto());
}
return channel_full;
}
bool ContactsManager::get_channel_full(ChannelId channel_id, Promise<Unit> &&promise) {
@ -8265,13 +8274,14 @@ bool ContactsManager::get_channel_full(ChannelId channel_id, Promise<Unit> &&pro
return false;
}
if (channel_full->is_expired()) {
auto input_channel = get_input_channel(channel_id);
CHECK(input_channel != nullptr);
if (td_->auth_manager_->is_bot()) {
auto input_channel = get_input_channel(channel_id);
CHECK(input_channel != nullptr);
send_get_channel_full_query(channel_id, std::move(input_channel), std::move(promise));
return false;
} else {
send_get_channel_full_query(channel_id, std::move(input_channel), Auto());
// request was already sent in get_channel_full
// send_get_channel_full_query(channel_id, std::move(input_channel), Auto());
}
}

View File

@ -304,9 +304,9 @@ class ContactsManager : public Actor {
string get_chat_invite_link(ChatId chat_id) const;
string get_channel_invite_link(ChannelId channel_id) const;
string get_channel_invite_link(ChannelId channel_id);
MessageId get_channel_pinned_message_id(ChannelId channel_id) const;
MessageId get_channel_pinned_message_id(ChannelId channel_id);
ChannelId migrate_chat_to_megagroup(ChatId chat_id, Promise<Unit> &promise);

View File

@ -373,6 +373,76 @@ class GetChannelMessagesQuery : public Td::ResultHandler {
}
};
class GetChannelPinnedMessageQuery : public Td::ResultHandler {
Promise<MessageId> promise_;
ChannelId channel_id_;
public:
explicit GetChannelPinnedMessageQuery(Promise<MessageId> &&promise) : promise_(std::move(promise)) {
}
void send(ChannelId channel_id) {
auto input_channel = td->contacts_manager_->get_input_channel(channel_id);
if (input_channel == nullptr) {
return promise_.set_error(Status::Error(6, "Can't access the chat"));
}
channel_id_ = channel_id;
vector<tl_object_ptr<telegram_api::InputMessage>> input_messages;
input_messages.push_back(make_tl_object<telegram_api::inputMessagePinned>());
send_query(G()->net_query_creator().create(
create_storer(telegram_api::channels_getMessages(std::move(input_channel), std::move(input_messages)))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::channels_getMessages>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(DEBUG) << "Receive result for GetChannelPinnedMessageQuery " << to_string(ptr);
int32 constructor_id = ptr->get_id();
switch (constructor_id) {
case telegram_api::messages_messages::ID:
case telegram_api::messages_messagesSlice::ID:
LOG(ERROR) << "Receive ordinary messages in GetChannelPinnedMessageQuery " << to_string(ptr);
return promise_.set_error(Status::Error(500, "Receive wrong request result"));
case telegram_api::messages_channelMessages::ID: {
auto messages = move_tl_object_as<telegram_api::messages_channelMessages>(ptr);
td->contacts_manager_->on_get_chats(std::move(messages->chats_));
td->contacts_manager_->on_get_users(std::move(messages->users_));
if (messages->messages_.empty()) {
return promise_.set_value(MessageId());
}
if (messages->messages_.size() >= 2) {
LOG(ERROR) << to_string(ptr);
return promise_.set_error(Status::Error(500, "More than 1 pinned message received"));
}
auto full_message_id = td->messages_manager_->on_get_message(std::move(messages->messages_[0]), false, true,
false, false, "get channel pinned messages");
if (full_message_id.get_dialog_id().is_valid() && full_message_id.get_dialog_id() != DialogId(channel_id_)) {
LOG(ERROR) << full_message_id << " " << to_string(ptr);
return promise_.set_error(Status::Error(500, "Receive pinned message in a wrong chat"));
}
return promise_.set_value(full_message_id.get_message_id());
}
default:
UNREACHABLE();
}
}
void on_error(uint64 id, Status status) override {
if (status.message() == "MESSAGE_IDS_EMPTY") {
promise_.set_value(MessageId());
return;
}
td->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelPinnedMessageQuery");
promise_.set_error(std::move(status));
}
};
class ExportChannelMessageLinkQuery : public Td::ResultHandler {
Promise<Unit> promise_;
ChannelId channel_id_;
@ -10966,31 +11036,23 @@ MessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId mes
return replied_message_id;
}
MessageId MessagesManager::get_dialog_pinned_message(DialogId dialog_id, bool force, Promise<Unit> &&promise) {
void MessagesManager::get_dialog_pinned_message(DialogId dialog_id, Promise<MessageId> &&promise) {
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
promise.set_error(Status::Error(6, "Chat not found"));
return MessageId();
return promise.set_error(Status::Error(6, "Chat not found"));
}
if (dialog_id.get_type() != DialogType::Channel) {
promise.set_value(Unit());
return MessageId();
return promise.set_value(MessageId());
}
auto channel_id = dialog_id.get_channel_id();
auto message_id = td_->contacts_manager_->get_channel_pinned_message_id(channel_id);
if (!message_id.is_valid()) {
if (force) {
promise.set_value(Unit());
} else {
td_->contacts_manager_->get_channel_full(channel_id, std::move(promise));
}
return MessageId();
if (get_message_force(d, message_id) == nullptr) {
return td_->create_handler<GetChannelPinnedMessageQuery>(std::move(promise))->send(channel_id);
}
get_message_force_from_server(d, message_id, std::move(promise));
return message_id;
promise.set_value(std::move(message_id));
}
bool MessagesManager::get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise) {
@ -11076,6 +11138,7 @@ void MessagesManager::get_messages_from_server(vector<FullMessageId> &&message_i
auto input_channel = td_->contacts_manager_->get_input_channel(it.first);
if (input_channel == nullptr) {
LOG(ERROR) << "Can't find info about " << it.first << " to get a message from it";
promise.set_error(Status::Error(6, "Can't access the chat"));
continue;
}
td_->create_handler<GetChannelMessagesQuery>(std::move(promise))

View File

@ -1105,7 +1105,7 @@ class MessagesManager : public Actor {
MessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise);
MessageId get_dialog_pinned_message(DialogId dialog_id, bool force, Promise<Unit> &&promise);
void get_dialog_pinned_message(DialogId dialog_id, Promise<MessageId> &&promise);
bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise);

View File

@ -1056,14 +1056,22 @@ class GetRepliedMessageRequest : public RequestOnceActor {
}
};
class GetChatPinnedMessageRequest : public RequestActor<> {
class GetChatPinnedMessageRequest : public RequestActor<MessageId> {
DialogId dialog_id_;
MessageId pinned_message_id_;
void do_run(Promise<Unit> &&promise) override {
pinned_message_id_ =
td->messages_manager_->get_dialog_pinned_message(dialog_id_, get_tries() < 3, std::move(promise));
void do_run(Promise<MessageId> &&promise) override {
if (get_tries() < 2) {
promise.set_value(std::move(pinned_message_id_));
return;
}
td->messages_manager_->get_dialog_pinned_message(dialog_id_, std::move(promise));
}
void do_set_result(MessageId &&result) override {
pinned_message_id_ = result;
}
void do_send_result() override {
@ -1072,8 +1080,7 @@ class GetChatPinnedMessageRequest : public RequestActor<> {
public:
GetChatPinnedMessageRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id)
: RequestActor<>(std::move(td), request_id), dialog_id_(dialog_id) {
set_tries(3);
: RequestActor(std::move(td), request_id), dialog_id_(dialog_id) {
}
};