Support message links for forum topics.

This commit is contained in:
levlam 2022-11-04 14:40:57 +03:00
parent 8f9275858f
commit 939d43129c
4 changed files with 43 additions and 6 deletions

View File

@ -3912,11 +3912,11 @@ messageLink link:string is_public:Bool = MessageLink;
//@description Contains information about a link to a message in a chat
//@is_public True, if the link is a public link for a message in a chat
//@chat_id If found, identifier of the chat to which the message belongs, 0 otherwise
//@message_thread_id If found, identifier of the message thread in which to open the message, or which to open in case of a missing message
//@message If found, the linked message; may be null
//@media_timestamp Timestamp from which the video/audio/video note/voice note playing must start, in seconds; 0 if not specified. The media can be in the message content or in its web page preview
//@for_album True, if the whole media album to which the message belongs is linked
//@for_comment True, if the message is linked as a channel post comment or from a message thread
messageLinkInfo is_public:Bool chat_id:int53 message:message media_timestamp:int32 for_album:Bool for_comment:Bool = MessageLinkInfo;
messageLinkInfo is_public:Bool chat_id:int53 message_thread_id:int53 message:message media_timestamp:int32 for_album:Bool = MessageLinkInfo;
//@description Contains a part of a file @data File bytes

View File

@ -1752,6 +1752,7 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
Slice channel_id_slice;
Slice message_id_slice;
Slice comment_message_id_slice = "0";
Slice top_thread_message_id_slice;
Slice media_timestamp_slice;
bool is_single = false;
bool for_comment = false;
@ -1803,10 +1804,12 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
}
if (key_value.first == "thread") {
for_comment = true;
top_thread_message_id_slice = key_value.second;
}
}
} else {
// /c/123456789/12345
// /c/123456789/1234/12345
// /username/12345?single
CHECK(!url.empty() && url[0] == '/');
@ -1845,9 +1848,15 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
}
if (key_value.first == "thread") {
for_comment = true;
top_thread_message_id_slice = key_value.second;
}
}
}
auto slash_pos = message_id_slice.find('/');
if (slash_pos != Slice::npos) {
top_thread_message_id_slice = message_id_slice.substr(0, slash_pos);
message_id_slice.remove_prefix(slash_pos + 1);
}
}
ChannelId channel_id;
@ -1864,6 +1873,18 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
return Status::Error("Wrong message ID");
}
int32 top_thread_message_id = 0;
if (!top_thread_message_id_slice.empty()) {
auto r_top_thread_message_id = to_integer_safe<int32>(top_thread_message_id_slice);
if (r_top_thread_message_id.is_error()) {
return Status::Error("Wrong message thread ID");
}
top_thread_message_id = r_top_thread_message_id.ok();
if (!ServerMessageId(top_thread_message_id).is_valid()) {
return Status::Error("Invalid message thread ID");
}
}
auto r_comment_message_id = to_integer_safe<int32>(comment_message_id_slice);
if (r_comment_message_id.is_error() ||
!(r_comment_message_id.ok() == 0 || ServerMessageId(r_comment_message_id.ok()).is_valid())) {
@ -1912,6 +1933,7 @@ Result<MessageLinkInfo> LinkManager::get_message_link_info(Slice url) {
info.channel_id = channel_id;
info.message_id = MessageId(ServerMessageId(r_message_id.ok()));
info.comment_message_id = MessageId(ServerMessageId(r_comment_message_id.ok()));
info.top_thread_message_id = MessageId(ServerMessageId(top_thread_message_id));
info.media_timestamp = is_media_timestamp_invalid ? 0 : media_timestamp;
info.is_single = is_single;
info.for_comment = for_comment;

View File

@ -23,6 +23,8 @@ struct MessageLinkInfo {
bool is_single = false;
int32 media_timestamp = 0;
MessageId top_thread_message_id;
DialogId comment_dialog_id;
MessageId comment_message_id;
bool for_comment = false;

View File

@ -19513,32 +19513,45 @@ td_api::object_ptr<td_api::messageLinkInfo> MessagesManager::get_message_link_in
DialogId dialog_id = info.comment_dialog_id.is_valid()
? info.comment_dialog_id
: (is_public ? resolve_dialog_username(info.username) : DialogId(info.channel_id));
MessageId top_thread_message_id;
MessageId message_id = info.comment_dialog_id.is_valid() ? info.comment_message_id : info.message_id;
td_api::object_ptr<td_api::message> message;
int32 media_timestamp = 0;
bool for_album = false;
bool for_comment = false;
const Dialog *d = get_dialog(dialog_id);
if (d == nullptr) {
dialog_id = DialogId();
top_thread_message_id = MessageId();
} else {
const Message *m = get_message(d, message_id);
if (m != nullptr) {
message = get_message_object(dialog_id, m, "get_message_link_info_object");
for_album = !info.is_single && m->media_album_id != 0;
for_comment = (info.comment_dialog_id.is_valid() || info.for_comment) && m->top_thread_message_id.is_valid();
if (info.comment_dialog_id.is_valid() || info.for_comment || m->is_topic_message) {
top_thread_message_id = m->top_thread_message_id;
} else {
top_thread_message_id = MessageId();
}
if (can_message_content_have_media_timestamp(m->content.get())) {
auto duration = get_message_content_media_duration(m->content.get(), td_);
if (duration == 0 || info.media_timestamp <= duration) {
media_timestamp = info.media_timestamp;
}
}
if (m->content->get_type() == MessageContentType::TopicCreate && m->top_thread_message_id.is_valid()) {
message = nullptr;
CHECK(!for_album);
CHECK(media_timestamp == 0);
}
} else if (!info.comment_dialog_id.is_valid() && dialog_id.get_type() == DialogType::Channel &&
!is_broadcast_channel(dialog_id)) {
top_thread_message_id = info.top_thread_message_id;
}
}
return td_api::make_object<td_api::messageLinkInfo>(is_public, dialog_id.get(), std::move(message), media_timestamp,
for_album, for_comment);
return td_api::make_object<td_api::messageLinkInfo>(is_public, dialog_id.get(), top_thread_message_id.get(),
std::move(message), media_timestamp, for_album);
}
InputDialogId MessagesManager::get_input_dialog_id(DialogId dialog_id) const {