Support quote position for replies.
This commit is contained in:
parent
9207ba4c78
commit
95304c611c
@ -1236,13 +1236,14 @@ messageSendingStateFailed error:error can_retry:Bool need_another_sender:Bool ne
|
|||||||
//@chat_id The identifier of the chat to which the message belongs; may be 0 if the replied message is in unknown chat
|
//@chat_id The identifier of the chat to which the message belongs; may be 0 if the replied message is in unknown chat
|
||||||
//@message_id The identifier of the message; may be 0 if the replied message is in unknown chat
|
//@message_id The identifier of the message; may be 0 if the replied message is in unknown chat
|
||||||
//@quote Manually or automatically chosen quote from the replied message; may be null if none. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities can be present in the quote
|
//@quote Manually or automatically chosen quote from the replied message; may be null if none. Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities can be present in the quote
|
||||||
|
//@quote_position Approximate quote position in UTF-16 code units
|
||||||
//@is_quote_manual True, if the quote was manually chosen by the message sender
|
//@is_quote_manual True, if the quote was manually chosen by the message sender
|
||||||
//@origin Information about origin of the message if the message was from another chat or topic; may be null for messages from the same chat
|
//@origin Information about origin of the message if the message was from another chat or topic; may be null for messages from the same chat
|
||||||
//@origin_send_date Point in time (Unix timestamp) when the message was sent if the message was from another chat or topic; 0 for messages from the same chat
|
//@origin_send_date Point in time (Unix timestamp) when the message was sent if the message was from another chat or topic; 0 for messages from the same chat
|
||||||
//@content Media content of the message if the message was from another chat or topic; may be null for messages from the same chat and messages without media.
|
//@content Media content of the message if the message was from another chat or topic; may be null for messages from the same chat and messages without media.
|
||||||
//-Can be only one of the following types: messageAnimation, messageAudio, messageContact, messageDice, messageDocument, messageGame, messageInvoice, messageLocation,
|
//-Can be only one of the following types: messageAnimation, messageAudio, messageContact, messageDice, messageDocument, messageGame, messageInvoice, messageLocation,
|
||||||
//-messagePhoto, messagePoll, messagePremiumGiveaway, messageSticker, messageStory, messageText (for link preview), messageVenue, messageVideo, messageVideoNote, or messageVoiceNote
|
//-messagePhoto, messagePoll, messagePremiumGiveaway, messageSticker, messageStory, messageText (for link preview), messageVenue, messageVideo, messageVideoNote, or messageVoiceNote
|
||||||
messageReplyToMessage chat_id:int53 message_id:int53 quote:formattedText is_quote_manual:Bool origin:MessageOrigin origin_send_date:int32 content:MessageContent = MessageReplyTo;
|
messageReplyToMessage chat_id:int53 message_id:int53 quote:formattedText quote_position:int32 is_quote_manual:Bool origin:MessageOrigin origin_send_date:int32 content:MessageContent = MessageReplyTo;
|
||||||
|
|
||||||
//@description Describes a story replied by a given message @story_sender_chat_id The identifier of the sender of the story @story_id The identifier of the story
|
//@description Describes a story replied by a given message @story_sender_chat_id The identifier of the sender of the story @story_id The identifier of the story
|
||||||
messageReplyToStory story_sender_chat_id:int53 story_id:int32 = MessageReplyTo;
|
messageReplyToStory story_sender_chat_id:int53 story_id:int32 = MessageReplyTo;
|
||||||
@ -1255,7 +1256,8 @@ messageReplyToStory story_sender_chat_id:int53 story_id:int32 = MessageReplyTo;
|
|||||||
//@message_id The identifier of the message to be replied in the same or the specified chat
|
//@message_id The identifier of the message to be replied in the same or the specified chat
|
||||||
//@quote Manually chosen quote from the message to be replied; pass null if none; 0-getOption("message_reply_quote_length_max") characters. Must always be null for replies in secret chats.
|
//@quote Manually chosen quote from the message to be replied; pass null if none; 0-getOption("message_reply_quote_length_max") characters. Must always be null for replies in secret chats.
|
||||||
//-Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed to be kept and must be kept in the quote
|
//-Only Bold, Italic, Underline, Strikethrough, Spoiler, and CustomEmoji entities are allowed to be kept and must be kept in the quote
|
||||||
inputMessageReplyToMessage chat_id:int53 message_id:int53 quote:formattedText = InputMessageReplyTo;
|
//@quote_position Quote position in UTF-16 code units
|
||||||
|
inputMessageReplyToMessage chat_id:int53 message_id:int53 quote:formattedText quote_position:int32 = 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
|
//@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;
|
inputMessageReplyToStory story_sender_chat_id:int53 story_id:int32 = InputMessageReplyTo;
|
||||||
@ -7074,7 +7076,8 @@ forwardMessages chat_id:int53 message_thread_id:int53 from_chat_id:int53 message
|
|||||||
//@chat_id Identifier of the chat to send messages
|
//@chat_id Identifier of the chat to send messages
|
||||||
//@message_ids Identifiers of the messages to resend. Message identifiers must be in a strictly increasing order
|
//@message_ids Identifiers of the messages to resend. Message identifiers must be in a strictly increasing order
|
||||||
//@quote New manually chosen quote from the message to be replied; pass null if none. Ignored if more than one message is re-sent, or if messageSendingStateFailed.need_another_reply_quote == false
|
//@quote New manually chosen quote from the message to be replied; pass null if none. Ignored if more than one message is re-sent, or if messageSendingStateFailed.need_another_reply_quote == false
|
||||||
resendMessages chat_id:int53 message_ids:vector<int53> quote:formattedText = Messages;
|
//@quote_position New quote position in UTF-16 code units
|
||||||
|
resendMessages chat_id:int53 message_ids:vector<int53> quote:formattedText quote_position:int32 = Messages;
|
||||||
|
|
||||||
//@description Adds a local message to a chat. The message is persistent across application restarts only if the message database is used. Returns the added message
|
//@description Adds a local message to a chat. The message is persistent across application restarts only if the message database is used. Returns the added message
|
||||||
//@chat_id Target chat
|
//@chat_id Target chat
|
||||||
|
@ -53,7 +53,7 @@ void DraftMessage::parse(ParserT &parser) {
|
|||||||
if (has_legacy_reply_to_message_id) {
|
if (has_legacy_reply_to_message_id) {
|
||||||
MessageId legacy_reply_to_message_id;
|
MessageId legacy_reply_to_message_id;
|
||||||
td::parse(legacy_reply_to_message_id, parser);
|
td::parse(legacy_reply_to_message_id, parser);
|
||||||
message_input_reply_to_ = MessageInputReplyTo{legacy_reply_to_message_id, DialogId(), FormattedText()};
|
message_input_reply_to_ = MessageInputReplyTo{legacy_reply_to_message_id, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
if (has_input_message_text) {
|
if (has_input_message_text) {
|
||||||
td::parse(input_message_text_, parser);
|
td::parse(input_message_text_, parser);
|
||||||
|
@ -73,6 +73,7 @@ MessageInputReplyTo::MessageInputReplyTo(Td *td,
|
|||||||
}
|
}
|
||||||
quote_ = FormattedText{std::move(reply_to->quote_text_), std::move(entities)};
|
quote_ = FormattedText{std::move(reply_to->quote_text_), std::move(entities)};
|
||||||
remove_unallowed_quote_entities(quote_);
|
remove_unallowed_quote_entities(quote_);
|
||||||
|
quote_position_ = max(0, reply_to->quote_offset_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -129,9 +130,12 @@ telegram_api::object_ptr<telegram_api::InputReplyTo> MessageInputReplyTo::get_in
|
|||||||
if (!quote_entities.empty()) {
|
if (!quote_entities.empty()) {
|
||||||
flags |= telegram_api::inputReplyToMessage::QUOTE_ENTITIES_MASK;
|
flags |= telegram_api::inputReplyToMessage::QUOTE_ENTITIES_MASK;
|
||||||
}
|
}
|
||||||
|
if (quote_position_ != 0) {
|
||||||
|
flags |= telegram_api::inputReplyToMessage::QUOTE_OFFSET_MASK;
|
||||||
|
}
|
||||||
return telegram_api::make_object<telegram_api::inputReplyToMessage>(
|
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(),
|
flags, reply_to_message_id.get_server_message_id().get(), top_thread_message_id.get_server_message_id().get(),
|
||||||
std::move(input_peer), quote_.text, std::move(quote_entities), 0);
|
std::move(input_peer), quote_.text, std::move(quote_entities), quote_position_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only for draft messages
|
// only for draft messages
|
||||||
@ -150,7 +154,7 @@ td_api::object_ptr<td_api::InputMessageReplyTo> MessageInputReplyTo::get_input_m
|
|||||||
}
|
}
|
||||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(
|
return td_api::make_object<td_api::inputMessageReplyToMessage>(
|
||||||
td->messages_manager_->get_chat_id_object(dialog_id_, "inputMessageReplyToMessage"), message_id_.get(),
|
td->messages_manager_->get_chat_id_object(dialog_id_, "inputMessageReplyToMessage"), message_id_.get(),
|
||||||
std::move(quote));
|
std::move(quote), quote_position_);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageId MessageInputReplyTo::get_same_chat_reply_to_message_id() const {
|
MessageId MessageInputReplyTo::get_same_chat_reply_to_message_id() const {
|
||||||
@ -167,7 +171,8 @@ MessageFullId MessageInputReplyTo::get_reply_message_full_id(DialogId owner_dial
|
|||||||
|
|
||||||
bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
||||||
return lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ &&
|
return lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ &&
|
||||||
lhs.story_full_id_ == rhs.story_full_id_ && lhs.quote_ == rhs.quote_;
|
lhs.story_full_id_ == rhs.story_full_id_ && lhs.quote_ == rhs.quote_ &&
|
||||||
|
lhs.quote_position_ == rhs.quote_position_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) {
|
||||||
@ -182,6 +187,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReply
|
|||||||
}
|
}
|
||||||
if (!input_reply_to.quote_.text.empty()) {
|
if (!input_reply_to.quote_.text.empty()) {
|
||||||
string_builder << " with " << input_reply_to.quote_.text.size() << " quoted bytes";
|
string_builder << " with " << input_reply_to.quote_.text.size() << " quoted bytes";
|
||||||
|
if (input_reply_to.quote_position_ != 0) {
|
||||||
|
string_builder << " at position " << input_reply_to.quote_position_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return string_builder;
|
return string_builder;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ class MessageInputReplyTo {
|
|||||||
MessageId message_id_;
|
MessageId message_id_;
|
||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
FormattedText quote_;
|
FormattedText quote_;
|
||||||
|
int32 quote_position_ = 0;
|
||||||
// or
|
// or
|
||||||
StoryFullId story_full_id_;
|
StoryFullId story_full_id_;
|
||||||
|
|
||||||
@ -44,8 +45,11 @@ class MessageInputReplyTo {
|
|||||||
MessageInputReplyTo &operator=(MessageInputReplyTo &&) = default;
|
MessageInputReplyTo &operator=(MessageInputReplyTo &&) = default;
|
||||||
~MessageInputReplyTo();
|
~MessageInputReplyTo();
|
||||||
|
|
||||||
MessageInputReplyTo(MessageId message_id, DialogId dialog_id, FormattedText &"e)
|
MessageInputReplyTo(MessageId message_id, DialogId dialog_id, FormattedText &"e, int32 quote_position)
|
||||||
: message_id_(message_id), dialog_id_(dialog_id), quote_(std::move(quote)) {
|
: message_id_(message_id)
|
||||||
|
, dialog_id_(dialog_id)
|
||||||
|
, quote_(std::move(quote))
|
||||||
|
, quote_position_(max(0, quote_position)) {
|
||||||
remove_unallowed_quote_entities(quote_);
|
remove_unallowed_quote_entities(quote_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,8 +70,9 @@ class MessageInputReplyTo {
|
|||||||
return !quote_.text.empty();
|
return !quote_.text.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_quote(FormattedText &"e) {
|
void set_quote(FormattedText &"e, int32 quote_position) {
|
||||||
quote_ = std::move(quote);
|
quote_ = std::move(quote);
|
||||||
|
quote_position_ = max(0, quote_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
StoryFullId get_story_full_id() const {
|
StoryFullId get_story_full_id() const {
|
||||||
|
@ -20,11 +20,13 @@ void MessageInputReplyTo::store(StorerT &storer) const {
|
|||||||
bool has_story_full_id = story_full_id_.is_valid();
|
bool has_story_full_id = story_full_id_.is_valid();
|
||||||
bool has_quote = !quote_.text.empty();
|
bool has_quote = !quote_.text.empty();
|
||||||
bool has_dialog_id = dialog_id_.is_valid();
|
bool has_dialog_id = dialog_id_.is_valid();
|
||||||
|
bool has_quote_position = quote_position_ != 0;
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(has_message_id);
|
STORE_FLAG(has_message_id);
|
||||||
STORE_FLAG(has_story_full_id);
|
STORE_FLAG(has_story_full_id);
|
||||||
STORE_FLAG(has_quote);
|
STORE_FLAG(has_quote);
|
||||||
STORE_FLAG(has_dialog_id);
|
STORE_FLAG(has_dialog_id);
|
||||||
|
STORE_FLAG(has_quote_position);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
if (has_message_id) {
|
if (has_message_id) {
|
||||||
td::store(message_id_, storer);
|
td::store(message_id_, storer);
|
||||||
@ -38,6 +40,9 @@ void MessageInputReplyTo::store(StorerT &storer) const {
|
|||||||
if (has_dialog_id) {
|
if (has_dialog_id) {
|
||||||
td::store(dialog_id_, storer);
|
td::store(dialog_id_, storer);
|
||||||
}
|
}
|
||||||
|
if (has_quote_position) {
|
||||||
|
td::store(quote_position_, storer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
@ -46,11 +51,13 @@ void MessageInputReplyTo::parse(ParserT &parser) {
|
|||||||
bool has_story_full_id;
|
bool has_story_full_id;
|
||||||
bool has_quote;
|
bool has_quote;
|
||||||
bool has_dialog_id;
|
bool has_dialog_id;
|
||||||
|
bool has_quote_position;
|
||||||
BEGIN_PARSE_FLAGS();
|
BEGIN_PARSE_FLAGS();
|
||||||
PARSE_FLAG(has_message_id);
|
PARSE_FLAG(has_message_id);
|
||||||
PARSE_FLAG(has_story_full_id);
|
PARSE_FLAG(has_story_full_id);
|
||||||
PARSE_FLAG(has_quote);
|
PARSE_FLAG(has_quote);
|
||||||
PARSE_FLAG(has_dialog_id);
|
PARSE_FLAG(has_dialog_id);
|
||||||
|
PARSE_FLAG(has_quote_position);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
if (has_message_id) {
|
if (has_message_id) {
|
||||||
td::parse(message_id_, parser);
|
td::parse(message_id_, parser);
|
||||||
@ -65,6 +72,9 @@ void MessageInputReplyTo::parse(ParserT &parser) {
|
|||||||
if (has_dialog_id) {
|
if (has_dialog_id) {
|
||||||
td::parse(dialog_id_, parser);
|
td::parse(dialog_id_, parser);
|
||||||
}
|
}
|
||||||
|
if (has_quote_position) {
|
||||||
|
td::parse(quote_position_, parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -5180,7 +5180,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
|
|||||||
if (reply_to_story_full_id.is_valid()) {
|
if (reply_to_story_full_id.is_valid()) {
|
||||||
input_reply_to = MessageInputReplyTo(reply_to_story_full_id);
|
input_reply_to = MessageInputReplyTo(reply_to_story_full_id);
|
||||||
} else if (legacy_reply_to_message_id.is_valid()) {
|
} else if (legacy_reply_to_message_id.is_valid()) {
|
||||||
input_reply_to = MessageInputReplyTo{legacy_reply_to_message_id, DialogId(), FormattedText()};
|
input_reply_to = MessageInputReplyTo{legacy_reply_to_message_id, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_replied_message_info) {
|
if (has_replied_message_info) {
|
||||||
@ -24518,7 +24518,7 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
|||||||
}
|
}
|
||||||
if (reply_to == nullptr) {
|
if (reply_to == nullptr) {
|
||||||
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
||||||
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText()};
|
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -24546,7 +24546,7 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
|||||||
if (!message_id.is_valid()) {
|
if (!message_id.is_valid()) {
|
||||||
if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() &&
|
if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() &&
|
||||||
top_thread_message_id.is_server()) {
|
top_thread_message_id.is_server()) {
|
||||||
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText()};
|
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -24566,10 +24566,12 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
FormattedText quote;
|
FormattedText quote;
|
||||||
|
int32 quote_position = 0;
|
||||||
auto r_quote = get_formatted_text(td_, get_my_dialog_id(), std::move(reply_to_message->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);
|
td_->auth_manager_->is_bot(), true, true, true);
|
||||||
if (r_quote.is_ok() && d->dialog_id.get_type() != DialogType::SecretChat) {
|
if (r_quote.is_ok() && d->dialog_id.get_type() != DialogType::SecretChat) {
|
||||||
quote = r_quote.move_as_ok();
|
quote = r_quote.move_as_ok();
|
||||||
|
quote_position = reply_to_message->quote_position_;
|
||||||
}
|
}
|
||||||
const Message *m = get_message_force(reply_d, message_id, "get_message_input_reply_to 2");
|
const Message *m = get_message_force(reply_d, message_id, "get_message_input_reply_to 2");
|
||||||
if (m == nullptr || m->message_id.is_yet_unsent() ||
|
if (m == nullptr || m->message_id.is_yet_unsent() ||
|
||||||
@ -24579,10 +24581,10 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
|||||||
(reply_d->notification_info != nullptr &&
|
(reply_d->notification_info != nullptr &&
|
||||||
message_id <= reply_d->notification_info->max_push_notification_message_id_)) {
|
message_id <= reply_d->notification_info->max_push_notification_message_id_)) {
|
||||||
// allow to reply yet unreceived server message in the same chat
|
// allow to reply yet unreceived server message in the same chat
|
||||||
return MessageInputReplyTo{message_id, reply_dialog_id, std::move(quote)};
|
return MessageInputReplyTo{message_id, reply_dialog_id, std::move(quote), quote_position};
|
||||||
}
|
}
|
||||||
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) {
|
||||||
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText()};
|
return MessageInputReplyTo{top_thread_message_id, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
LOG(INFO) << "Can't find " << message_id << " in " << reply_d->dialog_id;
|
LOG(INFO) << "Can't find " << message_id << " in " << reply_d->dialog_id;
|
||||||
|
|
||||||
@ -24594,7 +24596,7 @@ MessageInputReplyTo MessagesManager::get_message_input_reply_to(
|
|||||||
LOG(INFO) << "Can't reply in another chat " << m->message_id << " in " << reply_d->dialog_id;
|
LOG(INFO) << "Can't reply in another chat " << m->message_id << " in " << reply_d->dialog_id;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return MessageInputReplyTo{m->message_id, reply_dialog_id, std::move(quote)};
|
return MessageInputReplyTo{m->message_id, reply_dialog_id, std::move(quote), quote_position};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -24711,7 +24713,7 @@ void MessagesManager::cancel_send_message_query(DialogId dialog_id, Message *m)
|
|||||||
CHECK(input_reply_to != nullptr);
|
CHECK(input_reply_to != nullptr);
|
||||||
CHECK(input_reply_to->get_reply_message_full_id(reply_d->dialog_id) == MessageFullId(dialog_id, m->message_id));
|
CHECK(input_reply_to->get_reply_message_full_id(reply_d->dialog_id) == MessageFullId(dialog_id, m->message_id));
|
||||||
set_message_reply(reply_d, replied_m,
|
set_message_reply(reply_d, replied_m,
|
||||||
MessageInputReplyTo{replied_m->top_thread_message_id, DialogId(), FormattedText()}, true);
|
MessageInputReplyTo{replied_m->top_thread_message_id, DialogId(), FormattedText(), 0}, true);
|
||||||
}
|
}
|
||||||
replied_yet_unsent_messages_.erase(it);
|
replied_yet_unsent_messages_.erase(it);
|
||||||
}
|
}
|
||||||
@ -28252,7 +28254,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) {
|
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);
|
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()) {
|
if (it != forwarded_message_id_to_new_message_id.end()) {
|
||||||
input_reply_to = MessageInputReplyTo{it->second, DialogId(), FormattedText()};
|
input_reply_to = MessageInputReplyTo{it->second, DialogId(), FormattedText(), 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28308,7 +28310,8 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result<vector<MessageId>> MessagesManager::resend_messages(DialogId dialog_id, vector<MessageId> message_ids,
|
Result<vector<MessageId>> MessagesManager::resend_messages(DialogId dialog_id, vector<MessageId> message_ids,
|
||||||
td_api::object_ptr<td_api::formattedText> &"e) {
|
td_api::object_ptr<td_api::formattedText> &"e,
|
||||||
|
int32 quote_position) {
|
||||||
if (message_ids.empty()) {
|
if (message_ids.empty()) {
|
||||||
return Status::Error(400, "There are no messages to resend");
|
return Status::Error(400, "There are no messages to resend");
|
||||||
}
|
}
|
||||||
@ -28407,7 +28410,7 @@ Result<vector<MessageId>> MessagesManager::resend_messages(DialogId dialog_id, v
|
|||||||
auto r_quote =
|
auto r_quote =
|
||||||
get_formatted_text(td_, get_my_dialog_id(), std::move(quote), td_->auth_manager_->is_bot(), true, true, true);
|
get_formatted_text(td_, get_my_dialog_id(), std::move(quote), td_->auth_manager_->is_bot(), true, true, true);
|
||||||
if (r_quote.is_ok()) {
|
if (r_quote.is_ok()) {
|
||||||
message->input_reply_to.set_quote(r_quote.move_as_ok());
|
message->input_reply_to.set_quote(r_quote.move_as_ok(), quote_position);
|
||||||
}
|
}
|
||||||
} else if (need_drop_reply) {
|
} else if (need_drop_reply) {
|
||||||
message->input_reply_to = {};
|
message->input_reply_to = {};
|
||||||
@ -39424,7 +39427,7 @@ void MessagesManager::restore_message_reply_to_message_id(Dialog *d, Message *m)
|
|||||||
if (message_id.is_valid() || message_id.is_valid_scheduled()) {
|
if (message_id.is_valid() || message_id.is_valid_scheduled()) {
|
||||||
update_message_reply_to_message_id(d, m, message_id, false);
|
update_message_reply_to_message_id(d, m, message_id, false);
|
||||||
} else {
|
} else {
|
||||||
set_message_reply(d, m, MessageInputReplyTo{m->top_thread_message_id, DialogId(), FormattedText()}, false);
|
set_message_reply(d, m, MessageInputReplyTo{m->top_thread_message_id, DialogId(), FormattedText(), 0}, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +466,8 @@ class MessagesManager final : public Actor {
|
|||||||
vector<MessageCopyOptions> &©_options) TD_WARN_UNUSED_RESULT;
|
vector<MessageCopyOptions> &©_options) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids,
|
Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids,
|
||||||
td_api::object_ptr<td_api::formattedText> &"e) TD_WARN_UNUSED_RESULT;
|
td_api::object_ptr<td_api::formattedText> &"e,
|
||||||
|
int32 quote_position) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise<Unit> &&promise);
|
void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ RepliedMessageInfo::RepliedMessageInfo(Td *td, tl_object_ptr<telegram_api::messa
|
|||||||
entities.clear();
|
entities.clear();
|
||||||
}
|
}
|
||||||
quote_ = FormattedText{std::move(reply_header->quote_text_), std::move(entities)};
|
quote_ = FormattedText{std::move(reply_header->quote_text_), std::move(entities)};
|
||||||
|
quote_position_ = max(0, reply_header->quote_offset_);
|
||||||
remove_unallowed_quote_entities(quote_);
|
remove_unallowed_quote_entities(quote_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +162,7 @@ RepliedMessageInfo::RepliedMessageInfo(Td *td, const MessageInputReplyTo &input_
|
|||||||
message_id_ = input_reply_to.message_id_;
|
message_id_ = input_reply_to.message_id_;
|
||||||
if (!input_reply_to.quote_.text.empty()) {
|
if (!input_reply_to.quote_.text.empty()) {
|
||||||
quote_ = input_reply_to.quote_;
|
quote_ = input_reply_to.quote_;
|
||||||
|
quote_position_ = input_reply_to.quote_position_;
|
||||||
is_quote_manual_ = true;
|
is_quote_manual_ = true;
|
||||||
}
|
}
|
||||||
if (input_reply_to.dialog_id_ != DialogId()) {
|
if (input_reply_to.dialog_id_ != DialogId()) {
|
||||||
@ -206,6 +208,7 @@ RepliedMessageInfo RepliedMessageInfo::clone(Td *td) const {
|
|||||||
MessageContentDupType::Forward, MessageCopyOptions());
|
MessageContentDupType::Forward, MessageCopyOptions());
|
||||||
}
|
}
|
||||||
result.quote_ = quote_;
|
result.quote_ = quote_;
|
||||||
|
result.quote_position_ = quote_position_;
|
||||||
result.is_quote_manual_ = is_quote_manual_;
|
result.is_quote_manual_ = is_quote_manual_;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -227,6 +230,12 @@ bool RepliedMessageInfo::need_reply_changed_warning(
|
|||||||
// only signature can change in the message origin
|
// only signature can change in the message origin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (old_info.quote_position_ != new_info.quote_position_ &&
|
||||||
|
max(old_info.quote_position_, new_info.quote_position_) <
|
||||||
|
static_cast<int32>(min(old_info.quote_.text.size(), new_info.quote_.text.size()))) {
|
||||||
|
// quote position can't change
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (old_info.is_quote_manual_ != new_info.is_quote_manual_) {
|
if (old_info.is_quote_manual_ != new_info.is_quote_manual_) {
|
||||||
// quote manual property can't change
|
// quote manual property can't change
|
||||||
return true;
|
return true;
|
||||||
@ -336,8 +345,12 @@ td_api::object_ptr<td_api::messageReplyToMessage> RepliedMessageInfo::get_messag
|
|||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::formattedText> quote;
|
td_api::object_ptr<td_api::formattedText> quote;
|
||||||
|
int32 quote_position = 0;
|
||||||
|
bool is_quote_manual = false;
|
||||||
if (!quote_.text.empty()) {
|
if (!quote_.text.empty()) {
|
||||||
quote = get_formatted_text_object(quote_, true, -1);
|
quote = get_formatted_text_object(quote_, true, -1);
|
||||||
|
quote_position = quote_position_;
|
||||||
|
is_quote_manual = is_quote_manual_;
|
||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::MessageOrigin> origin;
|
td_api::object_ptr<td_api::MessageOrigin> origin;
|
||||||
@ -357,14 +370,14 @@ td_api::object_ptr<td_api::messageReplyToMessage> RepliedMessageInfo::get_messag
|
|||||||
}
|
}
|
||||||
|
|
||||||
return td_api::make_object<td_api::messageReplyToMessage>(chat_id, message_id_.get(), std::move(quote),
|
return td_api::make_object<td_api::messageReplyToMessage>(chat_id, message_id_.get(), std::move(quote),
|
||||||
is_quote_manual_, std::move(origin), origin_date_,
|
quote_position, is_quote_manual, std::move(origin),
|
||||||
std::move(content));
|
origin_date_, std::move(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageInputReplyTo RepliedMessageInfo::get_input_reply_to() const {
|
MessageInputReplyTo RepliedMessageInfo::get_input_reply_to() const {
|
||||||
CHECK(!is_external());
|
CHECK(!is_external());
|
||||||
if (message_id_.is_valid()) {
|
if (message_id_.is_valid()) {
|
||||||
return MessageInputReplyTo{message_id_, dialog_id_, FormattedText{quote_}};
|
return MessageInputReplyTo{message_id_, dialog_id_, FormattedText{quote_}, quote_position_};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -404,7 +417,7 @@ void RepliedMessageInfo::unregister_content(Td *td) const {
|
|||||||
bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs) {
|
bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs) {
|
||||||
if (!(lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ &&
|
if (!(lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ &&
|
||||||
lhs.origin_date_ == rhs.origin_date_ && lhs.origin_ == rhs.origin_ && lhs.quote_ == rhs.quote_ &&
|
lhs.origin_date_ == rhs.origin_date_ && lhs.origin_ == rhs.origin_ && lhs.quote_ == rhs.quote_ &&
|
||||||
lhs.is_quote_manual_ == rhs.is_quote_manual_)) {
|
lhs.quote_position_ == rhs.quote_position_ && lhs.is_quote_manual_ == rhs.is_quote_manual_)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool need_update = false;
|
bool need_update = false;
|
||||||
@ -431,6 +444,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const RepliedMessageInf
|
|||||||
if (!info.quote_.text.empty()) {
|
if (!info.quote_.text.empty()) {
|
||||||
string_builder << " with " << info.quote_.text.size() << (info.is_quote_manual_ ? " manually" : "")
|
string_builder << " with " << info.quote_.text.size() << (info.is_quote_manual_ ? " manually" : "")
|
||||||
<< " quoted bytes";
|
<< " quoted bytes";
|
||||||
|
if (info.quote_position_ != 0) {
|
||||||
|
string_builder << " at position " << info.quote_position_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (info.content_ != nullptr) {
|
if (info.content_ != nullptr) {
|
||||||
string_builder << " and content of the type " << info.content_->get_type();
|
string_builder << " and content of the type " << info.content_->get_type();
|
||||||
|
@ -37,6 +37,7 @@ class RepliedMessageInfo {
|
|||||||
MessageOrigin origin_; // for replies in other chats
|
MessageOrigin origin_; // for replies in other chats
|
||||||
unique_ptr<MessageContent> content_; // for replies in other chats
|
unique_ptr<MessageContent> content_; // for replies in other chats
|
||||||
FormattedText quote_;
|
FormattedText quote_;
|
||||||
|
int32 quote_position_ = 0;
|
||||||
bool is_quote_manual_ = false;
|
bool is_quote_manual_ = false;
|
||||||
|
|
||||||
friend bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs);
|
friend bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs);
|
||||||
|
@ -24,6 +24,7 @@ void RepliedMessageInfo::store(StorerT &storer) const {
|
|||||||
bool has_origin = !origin_.is_empty();
|
bool has_origin = !origin_.is_empty();
|
||||||
bool has_quote = !quote_.text.empty();
|
bool has_quote = !quote_.text.empty();
|
||||||
bool has_content = content_ != nullptr;
|
bool has_content = content_ != nullptr;
|
||||||
|
bool has_quote_position = quote_position_ != 0;
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(has_message_id);
|
STORE_FLAG(has_message_id);
|
||||||
STORE_FLAG(has_dialog_id);
|
STORE_FLAG(has_dialog_id);
|
||||||
@ -32,6 +33,7 @@ void RepliedMessageInfo::store(StorerT &storer) const {
|
|||||||
STORE_FLAG(has_quote);
|
STORE_FLAG(has_quote);
|
||||||
STORE_FLAG(is_quote_manual_);
|
STORE_FLAG(is_quote_manual_);
|
||||||
STORE_FLAG(has_content);
|
STORE_FLAG(has_content);
|
||||||
|
STORE_FLAG(has_quote_position);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
if (has_message_id) {
|
if (has_message_id) {
|
||||||
td::store(message_id_, storer);
|
td::store(message_id_, storer);
|
||||||
@ -51,6 +53,9 @@ void RepliedMessageInfo::store(StorerT &storer) const {
|
|||||||
if (has_content) {
|
if (has_content) {
|
||||||
store_message_content(content_.get(), storer);
|
store_message_content(content_.get(), storer);
|
||||||
}
|
}
|
||||||
|
if (has_quote_position) {
|
||||||
|
td::store(quote_position_, storer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
@ -61,6 +66,7 @@ void RepliedMessageInfo::parse(ParserT &parser) {
|
|||||||
bool has_origin;
|
bool has_origin;
|
||||||
bool has_quote;
|
bool has_quote;
|
||||||
bool has_content;
|
bool has_content;
|
||||||
|
bool has_quote_position;
|
||||||
BEGIN_PARSE_FLAGS();
|
BEGIN_PARSE_FLAGS();
|
||||||
PARSE_FLAG(has_message_id);
|
PARSE_FLAG(has_message_id);
|
||||||
PARSE_FLAG(has_dialog_id);
|
PARSE_FLAG(has_dialog_id);
|
||||||
@ -69,6 +75,7 @@ void RepliedMessageInfo::parse(ParserT &parser) {
|
|||||||
PARSE_FLAG(has_quote);
|
PARSE_FLAG(has_quote);
|
||||||
PARSE_FLAG(is_quote_manual_);
|
PARSE_FLAG(is_quote_manual_);
|
||||||
PARSE_FLAG(has_content);
|
PARSE_FLAG(has_content);
|
||||||
|
PARSE_FLAG(has_quote_position);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
if (has_message_id) {
|
if (has_message_id) {
|
||||||
td::parse(message_id_, parser);
|
td::parse(message_id_, parser);
|
||||||
@ -89,6 +96,9 @@ void RepliedMessageInfo::parse(ParserT &parser) {
|
|||||||
if (has_content) {
|
if (has_content) {
|
||||||
parse_message_content(content_, parser);
|
parse_message_content(content_, parser);
|
||||||
}
|
}
|
||||||
|
if (has_quote_position) {
|
||||||
|
td::parse(quote_position_, parser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -5915,7 +5915,7 @@ void Td::on_request(uint64 id, td_api::forwardMessages &request) {
|
|||||||
void Td::on_request(uint64 id, td_api::resendMessages &request) {
|
void Td::on_request(uint64 id, td_api::resendMessages &request) {
|
||||||
DialogId dialog_id(request.chat_id_);
|
DialogId dialog_id(request.chat_id_);
|
||||||
auto r_message_ids = messages_manager_->resend_messages(dialog_id, MessageId::get_message_ids(request.message_ids_),
|
auto r_message_ids = messages_manager_->resend_messages(dialog_id, MessageId::get_message_ids(request.message_ids_),
|
||||||
std::move(request.quote_));
|
std::move(request.quote_), request.quote_position_);
|
||||||
if (r_message_ids.is_error()) {
|
if (r_message_ids.is_error()) {
|
||||||
return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error());
|
return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error());
|
||||||
}
|
}
|
||||||
|
@ -925,8 +925,8 @@ class CliClient final : public Actor {
|
|||||||
|
|
||||||
td_api::object_ptr<td_api::InputMessageReplyTo> get_input_message_reply_to() const {
|
td_api::object_ptr<td_api::InputMessageReplyTo> get_input_message_reply_to() const {
|
||||||
if (reply_message_id_ != 0) {
|
if (reply_message_id_ != 0) {
|
||||||
return td_api::make_object<td_api::inputMessageReplyToMessage>(reply_chat_id_, reply_message_id_,
|
return td_api::make_object<td_api::inputMessageReplyToMessage>(
|
||||||
as_formatted_text(reply_quote_));
|
reply_chat_id_, reply_message_id_, as_formatted_text(reply_quote_), reply_quote_position_);
|
||||||
}
|
}
|
||||||
if (reply_user_id_ != 0 || reply_story_id_ != 0) {
|
if (reply_user_id_ != 0 || reply_story_id_ != 0) {
|
||||||
return td_api::make_object<td_api::inputMessageReplyToStory>(reply_user_id_, reply_story_id_);
|
return td_api::make_object<td_api::inputMessageReplyToStory>(reply_user_id_, reply_story_id_);
|
||||||
@ -3722,9 +3722,10 @@ class CliClient final : public Actor {
|
|||||||
ChatId chat_id;
|
ChatId chat_id;
|
||||||
string message_ids;
|
string message_ids;
|
||||||
string quote;
|
string quote;
|
||||||
get_args(args, chat_id, message_ids, quote);
|
int32 quote_position;
|
||||||
send_request(
|
get_args(args, chat_id, message_ids, quote, quote_position);
|
||||||
td_api::make_object<td_api::resendMessages>(chat_id, as_message_ids(message_ids), as_formatted_text(quote)));
|
send_request(td_api::make_object<td_api::resendMessages>(chat_id, as_message_ids(message_ids),
|
||||||
|
as_formatted_text(quote), quote_position));
|
||||||
} else if (op == "csc" || op == "CreateSecretChat") {
|
} else if (op == "csc" || op == "CreateSecretChat") {
|
||||||
send_request(td_api::make_object<td_api::createSecretChat>(as_secret_chat_id(args)));
|
send_request(td_api::make_object<td_api::createSecretChat>(as_secret_chat_id(args)));
|
||||||
} else if (op == "cnsc" || op == "CreateNewSecretChat") {
|
} else if (op == "cnsc" || op == "CreateNewSecretChat") {
|
||||||
@ -4506,6 +4507,8 @@ class CliClient final : public Actor {
|
|||||||
get_args(args, reply_message_id_, reply_chat_id_);
|
get_args(args, reply_message_id_, reply_chat_id_);
|
||||||
} else if (op == "smrq") {
|
} else if (op == "smrq") {
|
||||||
reply_quote_ = args;
|
reply_quote_ = args;
|
||||||
|
} else if (op == "smrqp") {
|
||||||
|
reply_quote_position_ = to_integer<int32>(args);
|
||||||
} else if (op == "smrs") {
|
} else if (op == "smrs") {
|
||||||
get_args(args, reply_user_id_, reply_story_id_);
|
get_args(args, reply_user_id_, reply_story_id_);
|
||||||
} else if (op == "slpo") {
|
} else if (op == "slpo") {
|
||||||
@ -6297,6 +6300,7 @@ class CliClient final : public Actor {
|
|||||||
ChatId reply_chat_id_;
|
ChatId reply_chat_id_;
|
||||||
MessageId reply_message_id_;
|
MessageId reply_message_id_;
|
||||||
string reply_quote_;
|
string reply_quote_;
|
||||||
|
int32 reply_quote_position_ = 0;
|
||||||
UserId reply_user_id_;
|
UserId reply_user_id_;
|
||||||
StoryId reply_story_id_;
|
StoryId reply_story_id_;
|
||||||
string link_preview_url_;
|
string link_preview_url_;
|
||||||
|
Loading…
Reference in New Issue
Block a user