Improve handling of Instant View anchors.
GitOrigin-RevId: 9293ea4c1c7f4767c7f91421b3719e00d836470c
This commit is contained in:
parent
c36b6948b0
commit
5dee42c734
@ -843,8 +843,14 @@ richTextPhoneNumber text:RichText phone_number:string = RichText;
|
||||
//@height Height of a bounding box in which the image should be shown; 0 if unknown
|
||||
richTextIcon document:document width:int32 height:int32 = RichText;
|
||||
|
||||
//@description A rich text anchor @text Text @name Anchor name
|
||||
richTextAnchor text:RichText name:string = RichText;
|
||||
//@description A rich text reference of a text on the same web page @text The text @reference_text The text to show on click
|
||||
richTextReference text:RichText reference_text:RichText = RichText;
|
||||
|
||||
//@description An anchor @name Anchor name
|
||||
richTextAnchor name:string = RichText;
|
||||
|
||||
//@description A link to an anchor on the same web page @text The link text @name The anchor name
|
||||
richTextAnchorLink text:RichText name:string = RichText;
|
||||
|
||||
//@description A concatenation of rich texts @texts Texts
|
||||
richTexts texts:vector<RichText> = RichText;
|
||||
@ -980,10 +986,9 @@ pageBlockMap location:location zoom:int32 width:int32 height:int32 caption:pageB
|
||||
|
||||
//@description Describes an instant view page for a web page @page_blocks Content of the web page
|
||||
//@version Version of the instant view, currently can be 1 or 2
|
||||
//@url Instant view URL; may be different from WebPage.url and must be used for the correct anchors handling
|
||||
//@is_rtl True, if the instant view must be shown from right to left
|
||||
//@is_full True, if the instant view contains the full page. A network request might be needed to get the full web page instant view
|
||||
webPageInstantView page_blocks:vector<PageBlock> version:int32 url:string is_rtl:Bool is_full:Bool = WebPageInstantView;
|
||||
webPageInstantView page_blocks:vector<PageBlock> version:int32 is_rtl:Bool is_full:Bool = WebPageInstantView;
|
||||
|
||||
|
||||
//@description Describes a web page preview
|
||||
|
Binary file not shown.
@ -38,8 +38,15 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
class RichText;
|
||||
|
||||
struct GetWebPageBlockObjectContext {
|
||||
Td *td_;
|
||||
Td *td_ = nullptr;
|
||||
Slice base_url_;
|
||||
|
||||
bool is_first_pass_ = true;
|
||||
bool has_anchor_urls_ = false;
|
||||
std::unordered_map<Slice, const RichText *, SliceHash> anchors_; // anchor -> text
|
||||
};
|
||||
|
||||
static vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects(
|
||||
@ -49,8 +56,6 @@ static vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects(
|
||||
});
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class RichText {
|
||||
static vector<td_api::object_ptr<td_api::RichText>> get_rich_text_objects(const vector<RichText> &rich_texts,
|
||||
GetWebPageBlockObjectContext *context) {
|
||||
@ -112,6 +117,23 @@ class RichText {
|
||||
case RichText::Type::Fixed:
|
||||
return make_tl_object<td_api::richTextFixed>(texts[0].get_rich_text_object(context));
|
||||
case RichText::Type::Url:
|
||||
if (!context->base_url_.empty() && begins_with(content, context->base_url_) &&
|
||||
content.size() > context->base_url_.size() + 1 && content[context->base_url_.size()] == '#') {
|
||||
if (context->is_first_pass_) {
|
||||
context->has_anchor_urls_ = true;
|
||||
} else {
|
||||
auto anchor = Slice(content).substr(context->base_url_.size() + 1);
|
||||
auto it = context->anchors_.find(anchor);
|
||||
if (it != context->anchors_.end()) {
|
||||
if (it->second == nullptr) {
|
||||
return make_tl_object<td_api::richTextAnchorLink>(texts[0].get_rich_text_object(context), anchor.str());
|
||||
} else {
|
||||
return make_tl_object<td_api::richTextReference>(texts[0].get_rich_text_object(context),
|
||||
it->second->get_rich_text_object(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return make_tl_object<td_api::richTextUrl>(texts[0].get_rich_text_object(context), content,
|
||||
web_page_id.is_valid());
|
||||
case RichText::Type::EmailAddress:
|
||||
@ -134,7 +156,13 @@ class RichText {
|
||||
context->td_->documents_manager_->get_document_object(document_file_id), width, height);
|
||||
}
|
||||
case RichText::Type::Anchor:
|
||||
return make_tl_object<td_api::richTextAnchor>(texts[0].get_rich_text_object(context), content);
|
||||
if (context->is_first_pass_) {
|
||||
context->anchors_.emplace(Slice(content), texts[0].empty() ? nullptr : &texts[0]);
|
||||
}
|
||||
if (texts[0].empty()) {
|
||||
return make_tl_object<td_api::richTextAnchor>(content);
|
||||
}
|
||||
return texts[0].get_rich_text_object(context);
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
@ -177,6 +205,8 @@ class RichText {
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
class WebPageBlockCaption {
|
||||
public:
|
||||
RichText text;
|
||||
@ -740,6 +770,9 @@ class WebPageBlockAnchor : public WebPageBlock {
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::PageBlock> get_page_block_object(Context *context) const override {
|
||||
if (context->is_first_pass_) {
|
||||
context->anchors_.emplace(name, nullptr);
|
||||
}
|
||||
return make_tl_object<td_api::pageBlockAnchor>(name);
|
||||
}
|
||||
|
||||
@ -2348,9 +2381,16 @@ vector<unique_ptr<WebPageBlock>> get_web_page_blocks(
|
||||
}
|
||||
|
||||
vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects(
|
||||
const vector<unique_ptr<WebPageBlock>> &page_blocks, Td *td) {
|
||||
const vector<unique_ptr<WebPageBlock>> &page_blocks, Td *td, Slice base_url) {
|
||||
GetWebPageBlockObjectContext context;
|
||||
context.td_ = td;
|
||||
context.base_url_ = base_url;
|
||||
auto blocks = get_page_block_objects(page_blocks, &context);
|
||||
if (context.anchors_.empty() || !context.has_anchor_urls_) {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
context.is_first_pass_ = false;
|
||||
return get_page_block_objects(page_blocks, &context);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/telegram/Photo.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@ -103,6 +104,6 @@ vector<unique_ptr<WebPageBlock>> get_web_page_blocks(
|
||||
const std::unordered_map<int64, FileId> &videos, const std::unordered_map<int64, FileId> &voice_notes);
|
||||
|
||||
vector<td_api::object_ptr<td_api::PageBlock>> get_page_block_objects(
|
||||
const vector<unique_ptr<WebPageBlock>> &page_blocks, Td *td);
|
||||
const vector<unique_ptr<WebPageBlock>> &page_blocks, Td *td, Slice base_url);
|
||||
|
||||
} // namespace td
|
||||
|
@ -1226,9 +1226,9 @@ tl_object_ptr<td_api::webPageInstantView> WebPagesManager::get_web_page_instant_
|
||||
LOG(ERROR) << "Trying to get not loaded web page instant view";
|
||||
return nullptr;
|
||||
}
|
||||
return make_tl_object<td_api::webPageInstantView>(get_page_block_objects(web_page_instant_view->page_blocks, td_),
|
||||
web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->url,
|
||||
web_page_instant_view->is_rtl, web_page_instant_view->is_full);
|
||||
return td_api::make_object<td_api::webPageInstantView>(
|
||||
get_page_block_objects(web_page_instant_view->page_blocks, td_, web_page_instant_view->url),
|
||||
web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->is_rtl, web_page_instant_view->is_full);
|
||||
}
|
||||
|
||||
void WebPagesManager::on_web_page_changed(WebPageId web_page_id, bool have_web_page) {
|
||||
|
Reference in New Issue
Block a user