Support local draft messages in message threads.

GitOrigin-RevId: f75e36f803b0aea5c6aff83831c31e0a312898db
This commit is contained in:
levlam 2020-09-22 19:45:27 +03:00
parent 4aa10dbcc5
commit a83a356e44
6 changed files with 67 additions and 13 deletions

View File

@ -975,8 +975,10 @@ loginUrlInfoOpen url:string skip_confirm:Bool = LoginUrlInfo;
loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int32 request_write_access:Bool = LoginUrlInfo;
//@description Contains information about a message thread @messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id)
messageThreadInfo messages:vector<message> = MessageThreadInfo;
//@description Contains information about a message thread
//@messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id)
//@draft_message A draft of a message in the message thread; may be null
messageThreadInfo messages:vector<message> draft_message:draftMessage = MessageThreadInfo;
//@class RichText @description Describes a text object inside an instant-view web page
@ -4001,8 +4003,8 @@ setChatPhoto chat_id:int53 photo:InputChatPhoto = Ok;
//@chat_id Chat identifier @permissions New non-administrator members permissions in the chat
setChatPermissions chat_id:int53 permissions:chatPermissions = Ok;
//@description Changes the draft message in a chat @chat_id Chat identifier @draft_message New draft message; may be null
setChatDraftMessage chat_id:int53 draft_message:draftMessage = Ok;
//@description Changes the draft message in a chat @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier in which the draft was changed @draft_message New draft message; may be null
setChatDraftMessage chat_id:int53 message_thread_id:int53 draft_message:draftMessage = Ok;
//@description Changes the notification settings of a chat. Notification settings of a chat with the current user (Saved Messages) can't be changed
//@chat_id Chat identifier @notification_settings New notification settings for the chat. If the chat is muted for more than 1 week, it is considered to be muted forever

Binary file not shown.

View File

@ -4443,6 +4443,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
bool has_sender_dialog_id = sender_dialog_id.is_valid();
bool has_reply_in_dialog_id = is_reply && reply_in_dialog_id.is_valid();
bool has_top_reply_message_id = top_reply_message_id.is_valid();
bool has_thread_draft_message = thread_draft_message != nullptr;
BEGIN_STORE_FLAGS();
STORE_FLAG(is_channel_post);
STORE_FLAG(is_outgoing);
@ -4496,6 +4497,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
STORE_FLAG(has_sender_dialog_id);
STORE_FLAG(has_reply_in_dialog_id);
STORE_FLAG(has_top_reply_message_id);
STORE_FLAG(has_thread_draft_message);
END_STORE_FLAGS();
}
@ -4589,6 +4591,9 @@ void MessagesManager::Message::store(StorerT &storer) const {
if (has_top_reply_message_id) {
store(top_reply_message_id, storer);
}
if (has_thread_draft_message) {
store(thread_draft_message, storer);
}
store_message_content(content.get(), storer);
if (has_reply_markup) {
store(reply_markup, storer);
@ -4627,6 +4632,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
bool has_sender_dialog_id = false;
bool has_reply_in_dialog_id = false;
bool has_top_reply_message_id = false;
bool has_thread_draft_message = false;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_channel_post);
PARSE_FLAG(is_outgoing);
@ -4680,6 +4686,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
PARSE_FLAG(has_sender_dialog_id);
PARSE_FLAG(has_reply_in_dialog_id);
PARSE_FLAG(has_top_reply_message_id);
PARSE_FLAG(has_thread_draft_message);
END_PARSE_FLAGS();
}
@ -4779,6 +4786,9 @@ void MessagesManager::Message::parse(ParserT &parser) {
if (has_top_reply_message_id) {
parse(top_reply_message_id, parser);
}
if (has_thread_draft_message) {
parse(thread_draft_message, parser);
}
parse_message_content(content, parser);
if (has_reply_markup) {
parse(reply_markup, parser);
@ -15889,10 +15899,23 @@ td_api::object_ptr<td_api::messageThreadInfo> MessagesManager::get_message_threa
const MessageThreadInfo &info) {
Dialog *d = get_dialog(info.dialog_id);
CHECK(d != nullptr);
auto messages = transform(info.message_ids, [this, d](MessageId message_id) {
return get_message_object(d->dialog_id, get_message_force(d, message_id, "get_message_thread_info_object"));
});
return td_api::make_object<td_api::messageThreadInfo>(std::move(messages));
vector<td_api::object_ptr<td_api::message>> messages;
messages.reserve(info.message_ids.size());
for (auto message_id : info.message_ids) {
auto message = get_message_object(d->dialog_id, get_message_force(d, message_id, "get_message_thread_info_object"));
if (message != nullptr) {
messages.push_back(std::move(message));
}
}
td_api::object_ptr<td_api::draftMessage> draft_message;
if (!info.message_ids.empty() && can_send_message(d->dialog_id).is_ok()) {
const Message *m = get_message_force(d, info.message_ids.back(), "get_message_thread_info_object 2");
if (m != nullptr && !m->reply_info.is_comment && is_active_message_reply_info(d->dialog_id, m->reply_info)) {
draft_message = get_draft_message_object(m->thread_draft_message);
}
}
return td_api::make_object<td_api::messageThreadInfo>(std::move(messages), std::move(draft_message));
}
void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise) {
@ -17260,7 +17283,7 @@ class MessagesManager::SaveDialogDraftMessageOnServerLogEvent {
}
};
Status MessagesManager::set_dialog_draft_message(DialogId dialog_id,
Status MessagesManager::set_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id,
tl_object_ptr<td_api::draftMessage> &&draft_message) {
if (td_->auth_manager_->is_bot()) {
return Status::Error(6, "Bots can't change chat draft message");
@ -17294,6 +17317,28 @@ Status MessagesManager::set_dialog_draft_message(DialogId dialog_id,
}
}
if (top_thread_message_id != MessageId()) {
if (!top_thread_message_id.is_valid()) {
return Status::Error(6, "Invalid message thread specified");
}
auto m = get_message_force(d, top_thread_message_id, "set_dialog_draft_message");
if (m == nullptr || m->message_id.is_scheduled() || m->reply_info.is_comment ||
!is_active_message_reply_info(dialog_id, m->reply_info)) {
return Status::OK();
}
auto &old_draft_message = m->thread_draft_message;
if (((new_draft_message == nullptr) != (old_draft_message == nullptr)) ||
(new_draft_message != nullptr &&
(old_draft_message->reply_to_message_id != new_draft_message->reply_to_message_id ||
old_draft_message->input_message_text != new_draft_message->input_message_text))) {
old_draft_message = std::move(new_draft_message);
on_message_changed(d, m, false, "set_dialog_draft_message");
}
return Status::OK();
}
if (update_dialog_draft_message(d, std::move(new_draft_message), false, true)) {
if (dialog_id.get_type() != DialogType::SecretChat) {
if (G()->parameters().use_message_db) {

View File

@ -627,7 +627,7 @@ class MessagesManager : public Actor {
Status delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) TD_WARN_UNUSED_RESULT;
Status set_dialog_draft_message(DialogId dialog_id,
Status set_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id,
tl_object_ptr<td_api::draftMessage> &&draft_message) TD_WARN_UNUSED_RESULT;
void clear_all_draft_messages(bool exclude_secret_chats, Promise<Unit> &&promise);
@ -1071,6 +1071,7 @@ class MessagesManager : public Actor {
int32 view_count = 0;
int32 forward_count = 0;
MessageReplyInfo reply_info;
unique_ptr<DraftMessage> thread_draft_message;
int32 legacy_layer = 0;

View File

@ -6016,7 +6016,8 @@ void Td::on_request(uint64 id, const td_api::setChatPermissions &request) {
void Td::on_request(uint64 id, td_api::setChatDraftMessage &request) {
CHECK_IS_USER();
answer_ok_query(
id, messages_manager_->set_dialog_draft_message(DialogId(request.chat_id_), std::move(request.draft_message_)));
id, messages_manager_->set_dialog_draft_message(DialogId(request.chat_id_), MessageId(request.message_thread_id_),
std::move(request.draft_message_)));
}
void Td::on_request(uint64 id, const td_api::toggleChatIsPinned &request) {

View File

@ -2883,11 +2883,15 @@ class CliClient final : public Actor {
op_not_found_count++;
}
if (op == "scdm") {
if (op == "scdm" || op == "scdmt") {
string chat_id;
string message_thread_id;
string reply_to_message_id;
string message;
std::tie(chat_id, args) = split(args);
if (op == "scdmt") {
std::tie(message_thread_id, args) = split(args);
}
std::tie(reply_to_message_id, message) = split(args);
td_api::object_ptr<td_api::draftMessage> draft_message;
if (!reply_to_message_id.empty() || !message.empty()) {
@ -2900,7 +2904,8 @@ class CliClient final : public Actor {
td_api::make_object<td_api::inputMessageText>(as_formatted_text(message, std::move(entities)), true,
false));
}
send_request(td_api::make_object<td_api::setChatDraftMessage>(as_chat_id(chat_id), std::move(draft_message)));
send_request(td_api::make_object<td_api::setChatDraftMessage>(
as_chat_id(chat_id), as_message_thread_id(message_thread_id), std::move(draft_message)));
} else if (op == "cadm") {
send_request(td_api::make_object<td_api::clearAllDraftMessages>());
} else if (op == "tcip" || op == "tcipa" || begins_with(op, "tcip-")) {