diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 425b8a7c0..64dc8f803 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -738,6 +738,9 @@ pageBlockVerticalAlignmentBottom = PageBlockVerticalAlignment; //@align Horizontal cell content alignment @valign Vertical cell content alignment pageBlockTableCell text:RichText is_header:Bool colspan:int32 rowspan:int32 align:PageBlockHorizontalAlignment valign:PageBlockVerticalAlignment = PageBlockTableCell; +//@description Contains information about a related article @url Related article URL @title Article title; can be empty @param_description Article description, can be empty @photo Article photo; may be null +pageBlockRelatedArticle url:string title:string description:string photo:photo = PageBlockRelatedArticle; + //@class PageBlock @description Describes a block of an instant view web page @@ -819,6 +822,9 @@ pageBlockTable caption:RichText cells:vector> is_bord //@description A collapsible block @header Always visible heading for the block @page_blocks Block contents @is_open True, if the block is open by default pageBlockDetails header:RichText page_blocks:vector is_open:Bool = PageBlock; +//@description Related articles @header Block header @articles List of related articles +pageBlockRelatedArticles header:RichText articles:vector = PageBlock; + //@description Describes an instant view page for a web page @page_blocks Content of the web page @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 diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index ce0b30d0c..f34ab6666 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index 4b80265da..20822fc64 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -564,6 +564,65 @@ class WebPagesManager::PageBlockTableCell { } }; +class WebPagesManager::RelatedArticle { + public: + string url; + WebPageId web_page_id; + string title; + string description; + Photo photo; + + template + void store(T &storer) const { + using ::td::store; + bool has_title = !title.empty(); + bool has_description = !description.empty(); + bool has_photo = photo.id != -2; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_title); + STORE_FLAG(has_description); + STORE_FLAG(has_photo); + END_STORE_FLAGS(); + store(url, storer); + store(web_page_id, storer); + if (has_title) { + store(title, storer); + } + if (has_description) { + store(description, storer); + } + if (has_photo) { + store(photo, storer); + } + } + + template + void parse(T &parser) { + using ::td::parse; + bool has_title; + bool has_description; + bool has_photo; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_title); + PARSE_FLAG(has_description); + PARSE_FLAG(has_photo); + END_PARSE_FLAGS(); + parse(url, parser); + parse(web_page_id, parser); + if (has_title) { + parse(title, parser); + } + if (has_description) { + parse(description, parser); + } + if (has_photo) { + parse(photo, parser); + } else { + photo.id = -2; + } + } +}; + class WebPagesManager::PageBlock { public: enum class Type : int32 { @@ -592,7 +651,8 @@ class WebPagesManager::PageBlock { Audio, Kicker, Table, - Details + Details, + RelatedArticles }; virtual Type get_type() const = 0; @@ -1823,6 +1883,54 @@ class WebPagesManager::PageBlockDetails : public PageBlock { } }; +class WebPagesManager::PageBlockRelatedArticles : public PageBlock { + RichText header; + vector related_articles; + + public: + PageBlockRelatedArticles() = default; + PageBlockRelatedArticles(RichText &&header, vector &&related_articles) + : header(std::move(header)), related_articles(std::move(related_articles)) { + } + + Type get_type() const override { + return Type::RelatedArticles; + } + + void append_file_ids(vector &file_ids) const override { + append_rich_text_file_ids(header, file_ids); + for (auto &article : related_articles) { + if (article.photo.id != -2) { + append(file_ids, photo_get_file_ids(article.photo)); + } + } + } + + tl_object_ptr get_page_block_object() const override { + auto related_article_objects = transform(related_articles, [](const RelatedArticle &article) { + return td_api::make_object( + article.url, article.title, article.description, + get_photo_object(G()->td().get_actor_unsafe()->file_manager_.get(), &article.photo)); + }); + return make_tl_object(get_rich_text_object(header), + std::move(related_article_objects)); + } + + template + void store(T &storer) const { + using ::td::store; + store(header, storer); + store(related_articles, storer); + } + + template + void parse(T &parser) { + using ::td::parse; + parse(header, parser); + parse(related_articles, parser); + } +}; + template void WebPagesManager::PageBlock::call_impl(Type type, const PageBlock *ptr, F &&f) { switch (type) { @@ -1878,6 +1986,8 @@ void WebPagesManager::PageBlock::call_impl(Type type, const PageBlock *ptr, F && return f(static_cast(ptr)); case Type::Details: return f(static_cast(ptr)); + case Type::RelatedArticles: + return f(static_cast(ptr)); } UNREACHABLE(); } @@ -3208,6 +3318,28 @@ unique_ptr WebPagesManager::get_page_block( get_rich_text(std::move(page_block->title_), documents), get_page_blocks(std::move(page_block->blocks_), animations, audios, documents, photos, videos), is_open); } + case telegram_api::pageBlockRelatedArticles::ID: { + auto page_block = move_tl_object_as(page_block_ptr); + auto articles = transform( + std::move(page_block->articles_), [&](tl_object_ptr &&related_article) { + RelatedArticle article; + article.url = std::move(related_article->url_); + article.web_page_id = WebPageId(related_article->webpage_id_); + article.title = std::move(related_article->title_); + article.description = std::move(related_article->description_); + auto it = (related_article->flags_ & telegram_api::pageRelatedArticle::PHOTO_ID_MASK) != 0 + ? photos.find(related_article->photo_id_) + : photos.end(); + if (it == photos.end()) { + article.photo.id = -2; + } else { + article.photo = it->second; + } + return article; + }); + return td::make_unique(get_rich_text(std::move(page_block->title_), documents), + std::move(articles)); + } default: UNREACHABLE(); } diff --git a/td/telegram/WebPagesManager.h b/td/telegram/WebPagesManager.h index 1564ed379..35b020477 100644 --- a/td/telegram/WebPagesManager.h +++ b/td/telegram/WebPagesManager.h @@ -102,6 +102,7 @@ class WebPagesManager : public Actor { class PageBlockCaption; class PageBlockTableCell; + class RelatedArticle; class PageBlock; class PageBlockTitle; @@ -130,6 +131,7 @@ class WebPagesManager : public Actor { class PageBlockAudio; class PageBlockTable; class PageBlockDetails; + class PageBlockRelatedArticles; class WebPageInstantView;