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
|
//@height Height of a bounding box in which the image should be shown; 0 if unknown
|
||||||
richTextIcon document:document width:int32 height:int32 = RichText;
|
richTextIcon document:document width:int32 height:int32 = RichText;
|
||||||
|
|
||||||
//@description A rich text anchor @text Text @name Anchor name
|
//@description A rich text reference of a text on the same web page @text The text @reference_text The text to show on click
|
||||||
richTextAnchor text:RichText name:string = RichText;
|
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
|
//@description A concatenation of rich texts @texts Texts
|
||||||
richTexts texts:vector<RichText> = RichText;
|
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
|
//@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
|
//@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_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
|
//@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
|
//@description Describes a web page preview
|
||||||
|
Binary file not shown.
@ -38,8 +38,15 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
class RichText;
|
||||||
|
|
||||||
struct GetWebPageBlockObjectContext {
|
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(
|
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 {
|
class RichText {
|
||||||
static vector<td_api::object_ptr<td_api::RichText>> get_rich_text_objects(const vector<RichText> &rich_texts,
|
static vector<td_api::object_ptr<td_api::RichText>> get_rich_text_objects(const vector<RichText> &rich_texts,
|
||||||
GetWebPageBlockObjectContext *context) {
|
GetWebPageBlockObjectContext *context) {
|
||||||
@ -112,6 +117,23 @@ class RichText {
|
|||||||
case RichText::Type::Fixed:
|
case RichText::Type::Fixed:
|
||||||
return make_tl_object<td_api::richTextFixed>(texts[0].get_rich_text_object(context));
|
return make_tl_object<td_api::richTextFixed>(texts[0].get_rich_text_object(context));
|
||||||
case RichText::Type::Url:
|
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,
|
return make_tl_object<td_api::richTextUrl>(texts[0].get_rich_text_object(context), content,
|
||||||
web_page_id.is_valid());
|
web_page_id.is_valid());
|
||||||
case RichText::Type::EmailAddress:
|
case RichText::Type::EmailAddress:
|
||||||
@ -134,7 +156,13 @@ class RichText {
|
|||||||
context->td_->documents_manager_->get_document_object(document_file_id), width, height);
|
context->td_->documents_manager_->get_document_object(document_file_id), width, height);
|
||||||
}
|
}
|
||||||
case RichText::Type::Anchor:
|
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();
|
UNREACHABLE();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -177,6 +205,8 @@ class RichText {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class WebPageBlockCaption {
|
class WebPageBlockCaption {
|
||||||
public:
|
public:
|
||||||
RichText text;
|
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 {
|
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);
|
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(
|
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;
|
GetWebPageBlockObjectContext context;
|
||||||
context.td_ = td;
|
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);
|
return get_page_block_objects(page_blocks, &context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "td/telegram/Photo.h"
|
#include "td/telegram/Photo.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#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);
|
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(
|
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
|
} // 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";
|
LOG(ERROR) << "Trying to get not loaded web page instant view";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return make_tl_object<td_api::webPageInstantView>(get_page_block_objects(web_page_instant_view->page_blocks, td_),
|
return td_api::make_object<td_api::webPageInstantView>(
|
||||||
web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->url,
|
get_page_block_objects(web_page_instant_view->page_blocks, td_, web_page_instant_view->url),
|
||||||
web_page_instant_view->is_rtl, web_page_instant_view->is_full);
|
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) {
|
void WebPagesManager::on_web_page_changed(WebPageId web_page_id, bool have_web_page) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user