From 79bcfb4915c8126fccbca3eead01959b418337cf Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 25 May 2021 19:05:17 +0300 Subject: [PATCH] Add internalLinkTypeMessageDraft. --- td/generate/scheme/td_api.tl | 4 +++ td/telegram/LinkManager.cpp | 64 ++++++++++++++++++++++++++++++++++-- td/telegram/LinkManager.h | 5 ++- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e98361d31..e0cfc4306 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3006,6 +3006,10 @@ internalLinkTypeBackground background_name:string = InternalLinkType; //@description The link is a link to a Telegram message. Call getMessageLinkInfo to process the link internalLinkTypeMessage = InternalLinkType; +//@description The link contains a message draft text. A share screen needs to be shown to the user, then the chosen chat should be open and the text should be added to the input field +//@text Message draft text @contains_link True, if the first line of the text contains a link. If true, the input field needs to be focused and the text after the link should be selected +internalLinkTypeMessageDraft text:formattedText contains_link:Bool = InternalLinkType; + //@description Contains an HTTPS link to a message in a supergroup or channel @link Message link @is_public True, if the link will work for non-members of the chat messageLink link:string is_public:Bool = MessageLink; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 1576f3849..634ba0958 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -10,6 +10,7 @@ #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" +#include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" @@ -34,7 +35,7 @@ class LinkManager::InternalLinkBackground : public InternalLink { } public: - explicit InternalLinkBackground(string background_name) : background_name_(background_name) { + explicit InternalLinkBackground(string background_name) : background_name_(std::move(background_name)) { } }; @@ -48,6 +49,24 @@ class LinkManager::InternalLinkMessage : public InternalLink { } }; +class LinkManager::InternalLinkMessageDraft : public InternalLink { + FormattedText text_; + bool contains_link_ = false; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(get_formatted_text_object(text_), contains_link_); + } + + InternalLinkType get_type() const final { + return InternalLinkType::MessageDraft; + } + + public: + InternalLinkMessageDraft(FormattedText &&text, bool contains_link) + : text_(std::move(text)), contains_link_(contains_link) { + } +}; + class RequestUrlAuthQuery : public Td::ResultHandler { Promise> promise_; string url_; @@ -283,8 +302,14 @@ LinkManager::LinkInfo LinkManager::get_link_info(Slice link) { } } + // host is already lowercased + Slice host = http_url.host_; + if (begins_with(host, "www.")) { + host.remove_prefix(4); + } + for (auto t_me_url : t_me_urls) { - if (http_url.host_ == t_me_url) { + if (host == t_me_url) { result.is_internal_ = true; result.is_tg_ = false; result.query_ = http_url.query_; @@ -347,6 +372,10 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que << copy_arg("mode") << copy_arg("intensity") << copy_arg("bg_color") << copy_arg("rotation")); } + } else if (path.size() == 1 && (path[0] == "share" || path[0] == "msg" || path[0] == "msg_url")) { + // msg_url?url= + // msg_url?url=&text= + return get_internal_link_message_draft(url_query.get_arg("url"), url_query.get_arg("text")); } return nullptr; } @@ -365,6 +394,11 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /bg/?mode=blur+motion // /bg/?intensity=...&bg_color=...&mode=blur+motion return td::make_unique(query.substr(4).str()); + } else if (path.size() >= 1 && (path[0] == "share" || path[0] == "msg") && + (path.size() == 1 || (path[1] != "bookmarklet" && path[1] != "embed"))) { + // /share?url= + // /share/url?url=&text= + return get_internal_link_message_draft(url_query.get_arg("url"), url_query.get_arg("text")); } else if (path.size() == 2 && !path[0].empty()) { // //12345?single return td::make_unique(); @@ -372,6 +406,32 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q return nullptr; } +unique_ptr LinkManager::get_internal_link_message_draft(Slice url, Slice text) { + if (url.empty() && text.empty()) { + return nullptr; + } + while (!text.empty() && text.back() == '\n') { + text.remove_suffix(1); + } + url = trim(url); + if (url.empty()) { + url = text; + text = Slice(); + } + FormattedText full_text; + bool contains_url = false; + if (!text.empty()) { + contains_url = true; + full_text.text = PSTRING() << url << '\n' << text; + } else { + full_text.text = url.str(); + } + if (fix_formatted_text(full_text.text, full_text.entities, false, false, false, true).is_error()) { + return nullptr; + } + return td::make_unique(std::move(full_text), contains_url); +} + void LinkManager::get_login_url_info(DialogId dialog_id, MessageId message_id, int32 button_id, Promise> &&promise) { TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(dialog_id, message_id, button_id)); diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 1c13817b3..aaef73093 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -33,7 +33,7 @@ class LinkManager : public Actor { LinkManager &operator=(LinkManager &&) = delete; ~LinkManager() override; - enum class InternalLinkType : int32 { Background, Message }; + enum class InternalLinkType : int32 { Background, Message, MessageDraft }; class InternalLink { public: @@ -79,11 +79,14 @@ class LinkManager : public Actor { class InternalLinkBackground; class InternalLinkMessage; + class InternalLinkMessageDraft; static unique_ptr parse_tg_link_query(Slice query); static unique_ptr parse_t_me_link_query(Slice query); + static unique_ptr get_internal_link_message_draft(Slice url, Slice text); + Td *td_; ActorShared<> parent_; };