Add inputMessageReplyToMessage.quote.
This commit is contained in:
parent
d43fd3beb3
commit
ec231f0c99
@ -1246,7 +1246,8 @@ messageReplyToStory story_sender_chat_id:int53 story_id:int32 = MessageReplyTo;
|
||||
|
||||
//@description Describes a message to be replied
|
||||
//@message_id The identifier of the message to be replied in the same chat
|
||||
inputMessageReplyToMessage message_id:int53 = InputMessageReplyTo;
|
||||
//@quote Manually chosen quote from the replied message; pass null if none; 0-getOption("message_reply_quote_length_max") characters
|
||||
inputMessageReplyToMessage message_id:int53 quote:formattedText = InputMessageReplyTo;
|
||||
|
||||
//@description Describes a story to be replied @story_sender_chat_id The identifier of the sender of the story. Currently, stories can be replied only in the sender's chat @story_id The identifier of the story
|
||||
inputMessageReplyToStory story_sender_chat_id:int53 story_id:int32 = InputMessageReplyTo;
|
||||
|
@ -49,7 +49,7 @@ void DraftMessage::parse(ParserT &parser) {
|
||||
if (has_legacy_reply_to_message_id) {
|
||||
MessageId legacy_reply_to_message_id;
|
||||
td::parse(legacy_reply_to_message_id, parser);
|
||||
message_input_reply_to_ = MessageInputReplyTo(legacy_reply_to_message_id);
|
||||
message_input_reply_to_ = MessageInputReplyTo(legacy_reply_to_message_id, FormattedText());
|
||||
}
|
||||
if (has_input_message_text) {
|
||||
td::parse(input_message_text_, parser);
|
||||
|
@ -2468,12 +2468,8 @@ static Result<InputMessageContent> create_input_message_content(
|
||||
if (correct_option_id < 0 || correct_option_id >= static_cast<int32>(input_poll->options_.size())) {
|
||||
return Status::Error(400, "Wrong correct option ID specified");
|
||||
}
|
||||
auto r_explanation =
|
||||
get_formatted_text(td, dialog_id, std::move(type->explanation_), is_bot, true, true, false);
|
||||
if (r_explanation.is_error()) {
|
||||
return r_explanation.move_as_error();
|
||||
}
|
||||
explanation = r_explanation.move_as_ok();
|
||||
TRY_RESULT_ASSIGN(
|
||||
explanation, get_formatted_text(td, dialog_id, std::move(type->explanation_), is_bot, true, true, false));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/InputDialogId.h"
|
||||
#include "td/telegram/MessagesManager.h"
|
||||
#include "td/telegram/misc.h"
|
||||
#include "td/telegram/StoryId.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
@ -52,8 +53,20 @@ MessageInputReplyTo::MessageInputReplyTo(Td *td,
|
||||
return;
|
||||
}
|
||||
}
|
||||
// TODO quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity>
|
||||
message_id_ = message_id;
|
||||
|
||||
if (!reply_to->quote_text_.empty()) {
|
||||
auto entities = get_message_entities(td->contacts_manager_.get(), std::move(reply_to->quote_entities_),
|
||||
"inputReplyToMessage");
|
||||
auto status = fix_formatted_text(reply_to->quote_text_, entities, true, true, true, true, false);
|
||||
if (status.is_error()) {
|
||||
if (!clean_input_string(reply_to->quote_text_)) {
|
||||
reply_to->quote_text_.clear();
|
||||
}
|
||||
entities.clear();
|
||||
}
|
||||
quote_ = FormattedText{std::move(reply_to->quote_text_), std::move(entities)};
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -87,9 +100,16 @@ telegram_api::object_ptr<telegram_api::InputReplyTo> MessageInputReplyTo::get_in
|
||||
CHECK(top_thread_message_id.is_server());
|
||||
flags |= telegram_api::inputReplyToMessage::TOP_MSG_ID_MASK;
|
||||
}
|
||||
if (!quote_.text.empty()) {
|
||||
flags |= telegram_api::inputReplyToMessage::QUOTE_TEXT_MASK;
|
||||
}
|
||||
auto quote_entities = get_input_message_entities(td->contacts_manager_.get(), quote_.entities, "get_input_reply_to");
|
||||
if (!quote_entities.empty()) {
|
||||
flags |= telegram_api::inputReplyToMessage::QUOTE_ENTITIES_MASK;
|
||||
}
|
||||
return telegram_api::make_object<telegram_api::inputReplyToMessage>(
|
||||
flags, reply_to_message_id.get_server_message_id().get(), top_thread_message_id.get_server_message_id().get(),
|
||||
nullptr, string(), Auto());
|
||||
nullptr, quote_.text, std::move(quote_entities));
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::InputMessageReplyTo> MessageInputReplyTo::get_input_message_reply_to_object(
|
||||
@ -103,7 +123,11 @@ td_api::object_ptr<td_api::InputMessageReplyTo> MessageInputReplyTo::get_input_m
|
||||
if (!message_id_.is_valid() && !message_id_.is_valid_scheduled()) {
|
||||
return nullptr;
|
||||
}
|
||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(message_id_.get());
|
||||
td_api::object_ptr<td_api::formattedText> quote;
|
||||
if (!quote_.text.empty()) {
|
||||
quote = get_formatted_text_object(quote_, true, -1);
|
||||
}
|
||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(message_id_.get(), std::move(quote));
|
||||
}
|
||||
|
||||
MessageId MessageInputReplyTo::get_same_chat_reply_to_message_id() const {
|
||||
@ -118,7 +142,7 @@ MessageFullId MessageInputReplyTo::get_reply_message_full_id(DialogId owner_dial
|
||||
}
|
||||
|
||||
bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
||||
return lhs.message_id_ == rhs.message_id_ && lhs.story_full_id_ == rhs.story_full_id_;
|
||||
return lhs.message_id_ == rhs.message_id_ && lhs.story_full_id_ == rhs.story_full_id_ && lhs.quote_ == rhs.quote_;
|
||||
}
|
||||
|
||||
bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
||||
@ -127,7 +151,11 @@ bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs)
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo &input_reply_to) {
|
||||
if (input_reply_to.message_id_.is_valid() || input_reply_to.message_id_.is_valid_scheduled()) {
|
||||
return string_builder << input_reply_to.message_id_;
|
||||
string_builder << input_reply_to.message_id_;
|
||||
if (!input_reply_to.quote_.text.empty()) {
|
||||
string_builder << " with " << input_reply_to.quote_.text.size() << " quoted bytes";
|
||||
}
|
||||
return string_builder;
|
||||
}
|
||||
if (input_reply_to.story_full_id_.is_valid()) {
|
||||
return string_builder << input_reply_to.story_full_id_;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/MessageFullId.h"
|
||||
#include "td/telegram/MessageId.h"
|
||||
#include "td/telegram/StoryFullId.h"
|
||||
@ -22,6 +23,7 @@ class Td;
|
||||
|
||||
class MessageInputReplyTo {
|
||||
MessageId message_id_;
|
||||
FormattedText quote_;
|
||||
// or
|
||||
StoryFullId story_full_id_;
|
||||
|
||||
@ -39,7 +41,7 @@ class MessageInputReplyTo {
|
||||
MessageInputReplyTo &operator=(MessageInputReplyTo &&) = default;
|
||||
~MessageInputReplyTo();
|
||||
|
||||
explicit MessageInputReplyTo(MessageId message_id) : message_id_(message_id) {
|
||||
MessageInputReplyTo(MessageId message_id, FormattedText &"e) : message_id_(message_id), quote_(std::move(quote)) {
|
||||
}
|
||||
|
||||
explicit MessageInputReplyTo(StoryFullId story_full_id) : story_full_id_(story_full_id) {
|
||||
@ -56,7 +58,7 @@ class MessageInputReplyTo {
|
||||
}
|
||||
|
||||
bool is_same_chat_reply() const {
|
||||
return message_id_.is_valid();
|
||||
return message_id_.is_valid() || message_id_.is_valid_scheduled();
|
||||
}
|
||||
|
||||
StoryFullId get_story_full_id() const {
|
||||
|
@ -18,9 +18,11 @@ template <class StorerT>
|
||||
void MessageInputReplyTo::store(StorerT &storer) const {
|
||||
bool has_message_id = message_id_.is_valid();
|
||||
bool has_story_full_id = story_full_id_.is_valid();
|
||||
bool has_quote = !quote_.text.empty();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(has_message_id);
|
||||
STORE_FLAG(has_story_full_id);
|
||||
STORE_FLAG(has_quote);
|
||||
END_STORE_FLAGS();
|
||||
if (has_message_id) {
|
||||
td::store(message_id_, storer);
|
||||
@ -28,15 +30,20 @@ void MessageInputReplyTo::store(StorerT &storer) const {
|
||||
if (has_story_full_id) {
|
||||
td::store(story_full_id_, storer);
|
||||
}
|
||||
if (has_quote) {
|
||||
td::store(quote_, storer);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void MessageInputReplyTo::parse(ParserT &parser) {
|
||||
bool has_message_id = message_id_.is_valid();
|
||||
bool has_story_full_id = story_full_id_.is_valid();
|
||||
bool has_message_id;
|
||||
bool has_story_full_id;
|
||||
bool has_quote;
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(has_message_id);
|
||||
PARSE_FLAG(has_story_full_id);
|
||||
PARSE_FLAG(has_quote);
|
||||
END_PARSE_FLAGS();
|
||||
if (has_message_id) {
|
||||
td::parse(message_id_, parser);
|
||||
@ -44,6 +51,9 @@ void MessageInputReplyTo::parse(ParserT &parser) {
|
||||
if (has_story_full_id) {
|
||||
td::parse(story_full_id_, parser);
|
||||
}
|
||||
if (has_quote) {
|
||||
td::parse(quote_, parser);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -5168,7 +5168,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
||||
if (reply_to_story_full_id.is_valid()) {
|
||||
input_reply_to = MessageInputReplyTo(reply_to_story_full_id);
|
||||
} else if (legacy_reply_to_message_id.is_valid()) {
|
||||
input_reply_to = MessageInputReplyTo(legacy_reply_to_message_id);
|
||||
input_reply_to = MessageInputReplyTo{legacy_reply_to_message_id, FormattedText()};
|
||||
}
|
||||
}
|
||||
if (has_replied_message_info) {
|
||||
@ -24489,57 +24489,74 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
||||
!have_message_force(d, top_thread_message_id, "get_message_input_reply_to 1")) {
|
||||
LOG(INFO) << "Have reply in the thread of unknown " << top_thread_message_id;
|
||||
}
|
||||
if (reply_to != nullptr && reply_to->get_id() == td_api::inputMessageReplyToStory::ID) {
|
||||
if (for_draft) {
|
||||
return {};
|
||||
}
|
||||
auto reply_to_story = td_api::move_object_as<td_api::inputMessageReplyToStory>(reply_to);
|
||||
auto story_id = StoryId(reply_to_story->story_id_);
|
||||
auto sender_dialog_id = DialogId(reply_to_story->story_sender_chat_id_);
|
||||
if (d->dialog_id != sender_dialog_id || sender_dialog_id.get_type() != DialogType::User) {
|
||||
LOG(INFO) << "Ignore reply to story from " << sender_dialog_id << " in a wrong " << d->dialog_id;
|
||||
return {};
|
||||
}
|
||||
if (!story_id.is_server()) {
|
||||
LOG(INFO) << "Ignore reply to invalid " << story_id;
|
||||
return {};
|
||||
}
|
||||
return MessageInputReplyTo{StoryFullId(sender_dialog_id, story_id)};
|
||||
}
|
||||
MessageId message_id;
|
||||
if (reply_to != nullptr && reply_to->get_id() == td_api::inputMessageReplyToMessage::ID) {
|
||||
auto reply_to_message = td_api::move_object_as<td_api::inputMessageReplyToMessage>(reply_to);
|
||||
message_id = MessageId(reply_to_message->message_id_);
|
||||
}
|
||||
if (!message_id.is_valid()) {
|
||||
if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() &&
|
||||
top_thread_message_id.is_server()) {
|
||||
return MessageInputReplyTo{top_thread_message_id};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
message_id = get_persistent_message_id(d, message_id);
|
||||
if (message_id == MessageId(ServerMessageId(1)) && d->dialog_id.get_type() == DialogType::Channel) {
|
||||
return {};
|
||||
}
|
||||
const Message *m = get_message_force(d, message_id, "get_message_input_reply_to 2");
|
||||
if (m == nullptr || m->message_id.is_yet_unsent() ||
|
||||
(m->message_id.is_local() && d->dialog_id.get_type() != DialogType::SecretChat)) {
|
||||
if (message_id.is_server() && d->dialog_id.get_type() != DialogType::SecretChat &&
|
||||
message_id > d->last_new_message_id &&
|
||||
(d->notification_info != nullptr && message_id <= d->notification_info->max_push_notification_message_id_)) {
|
||||
// allow to reply yet unreceived server message
|
||||
return MessageInputReplyTo{message_id};
|
||||
}
|
||||
if (reply_to == nullptr) {
|
||||
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
||||
return MessageInputReplyTo{top_thread_message_id};
|
||||
return MessageInputReplyTo{top_thread_message_id, FormattedText()};
|
||||
}
|
||||
|
||||
// TODO local replies to local messages can be allowed
|
||||
// TODO replies to yet unsent messages can be allowed with special handling of them on application restart
|
||||
return {};
|
||||
}
|
||||
return MessageInputReplyTo{m->message_id};
|
||||
switch (reply_to->get_id()) {
|
||||
case td_api::inputMessageReplyToStory::ID: {
|
||||
if (for_draft) {
|
||||
return {};
|
||||
}
|
||||
auto reply_to_story = td_api::move_object_as<td_api::inputMessageReplyToStory>(reply_to);
|
||||
auto story_id = StoryId(reply_to_story->story_id_);
|
||||
auto sender_dialog_id = DialogId(reply_to_story->story_sender_chat_id_);
|
||||
if (d->dialog_id != sender_dialog_id || sender_dialog_id.get_type() != DialogType::User) {
|
||||
LOG(INFO) << "Ignore reply to story from " << sender_dialog_id << " in a wrong " << d->dialog_id;
|
||||
return {};
|
||||
}
|
||||
if (!story_id.is_server()) {
|
||||
LOG(INFO) << "Ignore reply to invalid " << story_id;
|
||||
return {};
|
||||
}
|
||||
return MessageInputReplyTo{StoryFullId(sender_dialog_id, story_id)};
|
||||
}
|
||||
case td_api::inputMessageReplyToMessage::ID: {
|
||||
auto reply_to_message = td_api::move_object_as<td_api::inputMessageReplyToMessage>(reply_to);
|
||||
auto message_id = MessageId(reply_to_message->message_id_);
|
||||
if (!message_id.is_valid()) {
|
||||
if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() &&
|
||||
top_thread_message_id.is_server()) {
|
||||
return MessageInputReplyTo{top_thread_message_id, FormattedText()};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
message_id = get_persistent_message_id(d, message_id);
|
||||
if (message_id == MessageId(ServerMessageId(1)) && d->dialog_id.get_type() == DialogType::Channel) {
|
||||
return {};
|
||||
}
|
||||
FormattedText quote;
|
||||
auto r_quote = get_formatted_text(td_, get_my_dialog_id(), std::move(reply_to_message->quote_),
|
||||
td_->auth_manager_->is_bot(), true, true, true);
|
||||
if (r_quote.is_ok()) {
|
||||
quote = r_quote.move_as_ok();
|
||||
}
|
||||
const Message *m = get_message_force(d, message_id, "get_message_input_reply_to 2");
|
||||
if (m == nullptr || m->message_id.is_yet_unsent() ||
|
||||
(m->message_id.is_local() && d->dialog_id.get_type() != DialogType::SecretChat)) {
|
||||
if (message_id.is_server() && d->dialog_id.get_type() != DialogType::SecretChat &&
|
||||
message_id > d->last_new_message_id &&
|
||||
(d->notification_info != nullptr &&
|
||||
message_id <= d->notification_info->max_push_notification_message_id_)) {
|
||||
// allow to reply yet unreceived server message
|
||||
return MessageInputReplyTo{message_id, std::move(quote)};
|
||||
}
|
||||
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
||||
return MessageInputReplyTo{top_thread_message_id, FormattedText()};
|
||||
}
|
||||
|
||||
// TODO local replies to local messages can be allowed
|
||||
// TODO replies to yet unsent messages can be allowed with special handling of them on application restart
|
||||
return {};
|
||||
}
|
||||
return MessageInputReplyTo{m->message_id, std::move(quote)};
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
const MessageInputReplyTo *MessagesManager::get_message_input_reply_to(const Message *m) {
|
||||
@ -28097,9 +28114,9 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
Message *m;
|
||||
if (message_send_options.only_preview) {
|
||||
message = create_message_to_send(
|
||||
to_dialog, top_thread_message_id, MessageInputReplyTo{reply_to_message_id}, message_send_options,
|
||||
std::move(content), forwarded_message_contents[j].invert_media, j + 1 != forwarded_message_contents.size(),
|
||||
std::move(forward_info), false, DialogId());
|
||||
to_dialog, top_thread_message_id, MessageInputReplyTo{reply_to_message_id, FormattedText()},
|
||||
message_send_options, std::move(content), forwarded_message_contents[j].invert_media,
|
||||
j + 1 != forwarded_message_contents.size(), std::move(forward_info), false, DialogId());
|
||||
MessageId new_message_id =
|
||||
message_send_options.schedule_date != 0
|
||||
? get_next_yet_unsent_scheduled_message_id(to_dialog, message_send_options.schedule_date)
|
||||
@ -28107,10 +28124,10 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
message->message_id = new_message_id;
|
||||
m = message.get();
|
||||
} else {
|
||||
m = get_message_to_send(to_dialog, top_thread_message_id, MessageInputReplyTo{reply_to_message_id},
|
||||
message_send_options, std::move(content), forwarded_message_contents[j].invert_media,
|
||||
&need_update_dialog_pos, j + 1 != forwarded_message_contents.size(),
|
||||
std::move(forward_info));
|
||||
m = get_message_to_send(to_dialog, top_thread_message_id,
|
||||
MessageInputReplyTo{reply_to_message_id, FormattedText()}, message_send_options,
|
||||
std::move(content), forwarded_message_contents[j].invert_media, &need_update_dialog_pos,
|
||||
j + 1 != forwarded_message_contents.size(), std::move(forward_info));
|
||||
}
|
||||
fix_forwarded_message(m, to_dialog_id, forwarded_message, forwarded_message_contents[j].media_album_id,
|
||||
drop_author);
|
||||
@ -28153,7 +28170,7 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
if (!input_reply_to.is_valid() && copied_message.original_reply_to_message_id.is_valid() && is_secret) {
|
||||
auto it = forwarded_message_id_to_new_message_id.find(copied_message.original_reply_to_message_id);
|
||||
if (it != forwarded_message_id_to_new_message_id.end()) {
|
||||
input_reply_to = MessageInputReplyTo{it->second};
|
||||
input_reply_to = MessageInputReplyTo{it->second, FormattedText()};
|
||||
}
|
||||
}
|
||||
|
||||
@ -39152,7 +39169,7 @@ void MessagesManager::set_message_reply(const Dialog *d, Message *m, MessageId r
|
||||
}
|
||||
}
|
||||
if (!m->message_id.is_server()) {
|
||||
m->input_reply_to = MessageInputReplyTo(reply_to_message_id);
|
||||
m->input_reply_to = MessageInputReplyTo{reply_to_message_id, FormattedText()};
|
||||
}
|
||||
if (is_message_in_dialog) {
|
||||
register_message_reply(d->dialog_id, m);
|
||||
|
@ -155,6 +155,10 @@ RepliedMessageInfo::RepliedMessageInfo(Td *td, const MessageInputReplyTo &input_
|
||||
return;
|
||||
}
|
||||
message_id_ = input_reply_to.message_id_;
|
||||
if (!input_reply_to.quote_.text.empty()) {
|
||||
quote_ = input_reply_to.quote_;
|
||||
is_quote_manual_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool RepliedMessageInfo::need_reget() const {
|
||||
|
@ -942,7 +942,7 @@ class CliClient final : public Actor {
|
||||
return nullptr;
|
||||
}
|
||||
if (message_id != 0) {
|
||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(message_id);
|
||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(message_id, nullptr);
|
||||
} else {
|
||||
return td_api::make_object<td_api::inputMessageReplyToStory>(user_id, story_id);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user