Support PageBlockTable.

GitOrigin-RevId: 602d58aaba14e6433c624fe08f8d12be20b2f1b2
This commit is contained in:
levlam 2019-02-07 02:58:27 +03:00
parent 7dbb666a3b
commit 558a0f9b35
6 changed files with 273 additions and 1 deletions

View File

@ -711,6 +711,33 @@ pageBlockCaption text:RichText credit:RichText = PageBlockCaption;
//@description Describes an item of a list page block @label Item label, can be empty @page_blocks Item blocks //@description Describes an item of a list page block @label Item label, can be empty @page_blocks Item blocks
pageBlockListItem label:string page_blocks:vector<PageBlock> = PageBlockListItem; pageBlockListItem label:string page_blocks:vector<PageBlock> = PageBlockListItem;
//@class PageBlockHorizontalAlignment @description Describes a horizontal alignment of a table cell content
//@description The content should be left-aligned
pageBlockHorizontalAlignmentLeft = PageBlockHorizontalAlignment;
//@description The content should be center-aligned
pageBlockHorizontalAlignmentCenter = PageBlockHorizontalAlignment;
//@description The content should be right-aligned
pageBlockHorizontalAlignmentRight = PageBlockHorizontalAlignment;
//@class PageBlockVerticalAlignment @description Describes a Vertical alignment of a table cell content
//@description The content should be top-aligned
pageBlockVerticalAlignmentTop = PageBlockVerticalAlignment;
//@description The content should be middle-aligned
pageBlockVerticalAlignmentMiddle = PageBlockVerticalAlignment;
//@description The content should be bottom-aligned
pageBlockVerticalAlignmentBottom = PageBlockVerticalAlignment;
//@description Represents a cell of a table @text Cell text @is_header True, if it is a header cell
//@colspan The number of columns the cell should span @rowspan The number of rows the cell should span
//@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;
//@class PageBlock @description Describes a block of an instant view web page //@class PageBlock @description Describes a block of an instant view web page
@ -786,6 +813,9 @@ pageBlockSlideshow page_blocks:vector<PageBlock> caption:pageBlockCaption = Page
//@description A link to a chat @title Chat title @photo Chat photo; may be null @username Chat username, by which all other information about the chat should be resolved //@description A link to a chat @title Chat title @photo Chat photo; may be null @username Chat username, by which all other information about the chat should be resolved
pageBlockChatLink title:string photo:chatPhoto username:string = PageBlock; pageBlockChatLink title:string photo:chatPhoto username:string = PageBlock;
//@description A table @title Table title @cells Table cells @is_bordered True, if the table is bordered @is_striped True, if the table is striped
pageBlockTable title:RichText cells:vector<vector<pageBlockTableCell>> is_bordered:Bool is_striped:Bool = 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 //@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 //@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

Binary file not shown.

View File

@ -427,6 +427,10 @@ class WebPagesManager::RichText {
FileId document_file_id; FileId document_file_id;
WebPageId web_page_id; WebPageId web_page_id;
bool empty() const {
return type == Type::Plain && content.empty();
}
template <class T> template <class T>
void store(T &storer) const { void store(T &storer) const {
using ::td::store; using ::td::store;
@ -488,6 +492,78 @@ class WebPagesManager::PageBlockCaption {
} }
}; };
class WebPagesManager::PageBlockTableCell {
public:
RichText text;
bool is_header = false;
bool align_left = false;
bool align_center = false;
bool align_right = false;
bool valign_top = false;
bool valign_middle = false;
bool valign_bottom = false;
int32 colspan = 1;
int32 rowspan = 1;
template <class T>
void store(T &storer) const {
using ::td::store;
bool has_text = !text.empty();
bool has_colspan = colspan != 1;
bool has_rowspan = rowspan != 1;
BEGIN_STORE_FLAGS();
STORE_FLAG(is_header);
STORE_FLAG(align_left);
STORE_FLAG(align_center);
STORE_FLAG(align_right);
STORE_FLAG(valign_top);
STORE_FLAG(valign_middle);
STORE_FLAG(valign_bottom);
STORE_FLAG(has_text);
STORE_FLAG(has_colspan);
STORE_FLAG(has_rowspan);
END_STORE_FLAGS();
if (has_text) {
store(text, storer);
}
if (has_colspan) {
store(colspan, storer);
}
if (has_rowspan) {
store(rowspan, storer);
}
}
template <class T>
void parse(T &parser) {
using ::td::parse;
bool has_text;
bool has_colspan;
bool has_rowspan;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_header);
PARSE_FLAG(align_left);
PARSE_FLAG(align_center);
PARSE_FLAG(align_right);
PARSE_FLAG(valign_top);
PARSE_FLAG(valign_middle);
PARSE_FLAG(valign_bottom);
PARSE_FLAG(has_text);
PARSE_FLAG(has_colspan);
PARSE_FLAG(has_rowspan);
END_PARSE_FLAGS();
if (has_text) {
parse(text, parser);
}
if (has_colspan) {
parse(colspan, parser);
}
if (has_rowspan) {
parse(rowspan, parser);
}
}
};
class WebPagesManager::PageBlock { class WebPagesManager::PageBlock {
public: public:
enum class Type : int32 { enum class Type : int32 {
@ -514,7 +590,8 @@ class WebPagesManager::PageBlock {
Slideshow, Slideshow,
ChatLink, ChatLink,
Audio, Audio,
Kicker Kicker,
Table
}; };
virtual Type get_type() const = 0; virtual Type get_type() const = 0;
@ -537,6 +614,7 @@ class WebPagesManager::PageBlock {
store(type, storer); store(type, storer);
call_impl(type, this, [&](const auto *object) { store(*object, storer); }); call_impl(type, this, [&](const auto *object) { store(*object, storer); });
} }
template <class T> template <class T>
static unique_ptr<PageBlock> parse(T &parser) { static unique_ptr<PageBlock> parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -593,6 +671,7 @@ class WebPagesManager::PageBlockTitle : public PageBlock {
using ::td::store; using ::td::store;
store(title, storer); store(title, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -625,6 +704,7 @@ class WebPagesManager::PageBlockSubtitle : public PageBlock {
using ::td::store; using ::td::store;
store(subtitle, storer); store(subtitle, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -659,6 +739,7 @@ class WebPagesManager::PageBlockAuthorDate : public PageBlock {
store(author, storer); store(author, storer);
store(date, storer); store(date, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -692,6 +773,7 @@ class WebPagesManager::PageBlockHeader : public PageBlock {
using ::td::store; using ::td::store;
store(header, storer); store(header, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -724,6 +806,7 @@ class WebPagesManager::PageBlockSubheader : public PageBlock {
using ::td::store; using ::td::store;
store(subheader, storer); store(subheader, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -756,6 +839,7 @@ class WebPagesManager::PageBlockKicker : public PageBlock {
using ::td::store; using ::td::store;
store(kicker, storer); store(kicker, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -788,6 +872,7 @@ class WebPagesManager::PageBlockParagraph : public PageBlock {
using ::td::store; using ::td::store;
store(text, storer); store(text, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -822,6 +907,7 @@ class WebPagesManager::PageBlockPreformatted : public PageBlock {
store(text, storer); store(text, storer);
store(language, storer); store(language, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -855,6 +941,7 @@ class WebPagesManager::PageBlockFooter : public PageBlock {
using ::td::store; using ::td::store;
store(footer, storer); store(footer, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -874,9 +961,11 @@ class WebPagesManager::PageBlockDivider : public PageBlock {
tl_object_ptr<td_api::PageBlock> get_page_block_object() const override { tl_object_ptr<td_api::PageBlock> get_page_block_object() const override {
return make_tl_object<td_api::pageBlockDivider>(); return make_tl_object<td_api::pageBlockDivider>();
} }
template <class T> template <class T>
void store(T &storer) const { void store(T &storer) const {
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
} }
@ -900,11 +989,13 @@ class WebPagesManager::PageBlockAnchor : public PageBlock {
tl_object_ptr<td_api::PageBlock> get_page_block_object() const override { tl_object_ptr<td_api::PageBlock> get_page_block_object() const override {
return make_tl_object<td_api::pageBlockAnchor>(name); return make_tl_object<td_api::pageBlockAnchor>(name);
} }
template <class T> template <class T>
void store(T &storer) const { void store(T &storer) const {
using ::td::store; using ::td::store;
store(name, storer); store(name, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -924,6 +1015,7 @@ class WebPagesManager::PageBlockList : public PageBlock {
store(label, storer); store(label, storer);
store(page_blocks, storer); store(page_blocks, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -966,6 +1058,7 @@ class WebPagesManager::PageBlockList : public PageBlock {
using ::td::store; using ::td::store;
store(items, storer); store(items, storer);
} }
template <class T> template <class T>
void parse(T &parser) { void parse(T &parser) {
using ::td::parse; using ::td::parse;
@ -1408,6 +1501,7 @@ class WebPagesManager::PageBlockEmbeddedPost : public PageBlock {
url, author, get_photo_object(G()->td().get_actor_unsafe()->file_manager_.get(), &author_photo), date, url, author, get_photo_object(G()->td().get_actor_unsafe()->file_manager_.get(), &author_photo), date,
get_page_block_objects(page_blocks), get_page_block_caption_object(caption)); get_page_block_objects(page_blocks), get_page_block_caption_object(caption));
} }
template <class T> template <class T>
void store(T &storer) const { void store(T &storer) const {
using ::td::store; using ::td::store;
@ -1623,6 +1717,63 @@ class WebPagesManager::PageBlockAudio : public PageBlock {
} }
}; };
class WebPagesManager::PageBlockTable : public PageBlock {
RichText title;
vector<vector<PageBlockTableCell>> cells;
bool is_bordered = false;
bool is_striped = false;
public:
PageBlockTable() = default;
PageBlockTable(RichText &&title, vector<vector<PageBlockTableCell>> &&cells, bool is_bordered, bool is_striped)
: title(std::move(title)), cells(std::move(cells)), is_bordered(is_bordered), is_striped(is_striped) {
}
Type get_type() const override {
return Type::Table;
}
void append_file_ids(vector<FileId> &file_ids) const override {
append_rich_text_file_ids(title, file_ids);
for (auto &row : cells) {
for (auto &cell : row) {
append_rich_text_file_ids(cell.text, file_ids);
}
}
}
tl_object_ptr<td_api::PageBlock> get_page_block_object() const override {
auto cell_objects = transform(cells, [&](const vector<PageBlockTableCell> &row) {
return transform(row, [&](const PageBlockTableCell &cell) { return get_page_block_table_cell_object(cell); });
});
return make_tl_object<td_api::pageBlockTable>(get_rich_text_object(title), std::move(cell_objects), is_bordered,
is_striped);
}
template <class T>
void store(T &storer) const {
using ::td::store;
BEGIN_STORE_FLAGS();
STORE_FLAG(is_bordered);
STORE_FLAG(is_striped);
END_STORE_FLAGS();
store(title, storer);
store(cells, storer);
}
template <class T>
void parse(T &parser) {
using ::td::parse;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_bordered);
PARSE_FLAG(is_striped);
END_PARSE_FLAGS();
parse(title, parser);
parse(cells, parser);
}
};
template <class F> template <class F>
void WebPagesManager::PageBlock::call_impl(Type type, const PageBlock *ptr, F &&f) { void WebPagesManager::PageBlock::call_impl(Type type, const PageBlock *ptr, F &&f) {
switch (type) { switch (type) {
@ -1674,6 +1825,8 @@ void WebPagesManager::PageBlock::call_impl(Type type, const PageBlock *ptr, F &&
return f(static_cast<const WebPagesManager::PageBlockChatLink *>(ptr)); return f(static_cast<const WebPagesManager::PageBlockChatLink *>(ptr));
case Type::Audio: case Type::Audio:
return f(static_cast<const WebPagesManager::PageBlockAudio *>(ptr)); return f(static_cast<const WebPagesManager::PageBlockAudio *>(ptr));
case Type::Table:
return f(static_cast<const WebPagesManager::PageBlockTable *>(ptr));
} }
UNREACHABLE(); UNREACHABLE();
} }
@ -2676,6 +2829,38 @@ td_api::object_ptr<td_api::pageBlockCaption> WebPagesManager::get_page_block_cap
get_rich_text_object(caption.credit)); get_rich_text_object(caption.credit));
} }
td_api::object_ptr<td_api::pageBlockTableCell> WebPagesManager::get_page_block_table_cell_object(
const PageBlockTableCell &cell) {
auto align = [&]() -> td_api::object_ptr<td_api::PageBlockHorizontalAlignment> {
if (cell.align_left) {
return td_api::make_object<td_api::pageBlockHorizontalAlignmentLeft>();
}
if (cell.align_center) {
return td_api::make_object<td_api::pageBlockHorizontalAlignmentCenter>();
}
if (cell.align_right) {
return td_api::make_object<td_api::pageBlockHorizontalAlignmentRight>();
}
UNREACHABLE();
return nullptr;
}();
auto valign = [&]() -> td_api::object_ptr<td_api::PageBlockVerticalAlignment> {
if (cell.valign_top) {
return td_api::make_object<td_api::pageBlockVerticalAlignmentTop>();
}
if (cell.valign_middle) {
return td_api::make_object<td_api::pageBlockVerticalAlignmentMiddle>();
}
if (cell.valign_bottom) {
return td_api::make_object<td_api::pageBlockVerticalAlignmentBottom>();
}
UNREACHABLE();
return nullptr;
}();
return td_api::make_object<td_api::pageBlockTableCell>(get_rich_text_object(cell.text), cell.is_header, cell.colspan,
cell.rowspan, std::move(align), std::move(valign));
}
vector<tl_object_ptr<td_api::PageBlock>> WebPagesManager::get_page_block_objects( vector<tl_object_ptr<td_api::PageBlock>> WebPagesManager::get_page_block_objects(
const vector<unique_ptr<PageBlock>> &page_blocks) { const vector<unique_ptr<PageBlock>> &page_blocks) {
return transform(page_blocks, return transform(page_blocks,
@ -2927,6 +3112,45 @@ unique_ptr<WebPagesManager::PageBlock> WebPagesManager::get_page_block(
return make_unique<PageBlockAudio>(audio_file_id, return make_unique<PageBlockAudio>(audio_file_id,
get_page_block_caption(std::move(page_block->caption_), documents)); get_page_block_caption(std::move(page_block->caption_), documents));
} }
case telegram_api::pageBlockTable::ID: {
auto page_block = move_tl_object_as<telegram_api::pageBlockTable>(page_block_ptr);
auto is_bordered = (page_block->flags_ & telegram_api::pageBlockTable::BORDERED_MASK) != 0;
auto is_striped = (page_block->flags_ & telegram_api::pageBlockTable::STRIPED_MASK) != 0;
auto cells = transform(std::move(page_block->rows_), [&](tl_object_ptr<telegram_api::pageTableRow> &&row) {
return transform(std::move(row->cells_), [&](tl_object_ptr<telegram_api::pageTableCell> &&table_cell) {
PageBlockTableCell cell;
auto flags = table_cell->flags_;
cell.is_header = (flags & telegram_api::pageTableCell::HEADER_MASK) != 0;
cell.align_center = (flags & telegram_api::pageTableCell::ALIGN_CENTER_MASK) != 0;
if (!cell.align_center) {
cell.align_right = (flags & telegram_api::pageTableCell::ALIGN_RIGHT_MASK) != 0;
if (!cell.align_right) {
cell.align_left = true;
}
}
cell.valign_middle = (flags & telegram_api::pageTableCell::VALIGN_MIDDLE_MASK) != 0;
if (!cell.valign_middle) {
cell.valign_bottom = (flags & telegram_api::pageTableCell::VALIGN_BOTTOM_MASK) != 0;
if (!cell.valign_bottom) {
cell.valign_top = true;
}
}
if (table_cell->text_ != nullptr) {
cell.text = get_rich_text(std::move(table_cell->text_), documents);
}
if ((flags & telegram_api::pageTableCell::COLSPAN_MASK) != 0) {
cell.colspan = table_cell->colspan_;
}
if ((flags & telegram_api::pageTableCell::ROWSPAN_MASK) != 0) {
cell.rowspan = table_cell->rowspan_;
}
return cell;
});
});
return td::make_unique<PageBlockTable>(get_rich_text(std::move(page_block->title_), documents), std::move(cells),
is_bordered, is_striped);
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }

View File

@ -101,6 +101,7 @@ class WebPagesManager : public Actor {
class RichText; class RichText;
class PageBlockCaption; class PageBlockCaption;
class PageBlockTableCell;
class PageBlock; class PageBlock;
class PageBlockTitle; class PageBlockTitle;
@ -127,6 +128,7 @@ class WebPagesManager : public Actor {
class PageBlockSlideshow; class PageBlockSlideshow;
class PageBlockChatLink; class PageBlockChatLink;
class PageBlockAudio; class PageBlockAudio;
class PageBlockTable;
class WebPageInstantView; class WebPageInstantView;
@ -178,6 +180,9 @@ class WebPagesManager : public Actor {
static td_api::object_ptr<td_api::pageBlockCaption> get_page_block_caption_object(const PageBlockCaption &caption); static td_api::object_ptr<td_api::pageBlockCaption> get_page_block_caption_object(const PageBlockCaption &caption);
static td_api::object_ptr<td_api::pageBlockTableCell> get_page_block_table_cell_object(
const PageBlockTableCell &cell);
static vector<tl_object_ptr<td_api::PageBlock>> get_page_block_objects( static vector<tl_object_ptr<td_api::PageBlock>> get_page_block_objects(
const vector<unique_ptr<PageBlock>> &page_blocks); const vector<unique_ptr<PageBlock>> &page_blocks);

View File

@ -26,6 +26,7 @@ static jclass StringClass;
static jclass ObjectClass; static jclass ObjectClass;
jclass ArrayKeyboardButtonClass; jclass ArrayKeyboardButtonClass;
jclass ArrayInlineKeyboardButtonClass; jclass ArrayInlineKeyboardButtonClass;
jclass ArrayPageBlockTableCellClass;
jmethodID GetConstructorID; jmethodID GetConstructorID;
jmethodID BooleanGetValueMethodID; jmethodID BooleanGetValueMethodID;
jmethodID IntegerGetValueMethodID; jmethodID IntegerGetValueMethodID;
@ -103,6 +104,8 @@ void init_vars(JNIEnv *env, const char *td_api_java_package) {
get_jclass(env, (PSLICE() << "[L" << td_api_java_package << "/TdApi$KeyboardButton;").c_str()); get_jclass(env, (PSLICE() << "[L" << td_api_java_package << "/TdApi$KeyboardButton;").c_str());
ArrayInlineKeyboardButtonClass = ArrayInlineKeyboardButtonClass =
get_jclass(env, (PSLICE() << "[L" << td_api_java_package << "/TdApi$InlineKeyboardButton;").c_str()); get_jclass(env, (PSLICE() << "[L" << td_api_java_package << "/TdApi$InlineKeyboardButton;").c_str());
ArrayPageBlockTableCellClass =
get_jclass(env, (PSLICE() << "[L" << td_api_java_package << "/TdApi$PageBlockTableCell;").c_str());
GetConstructorID = get_method_id(env, ObjectClass, "getConstructor", "()I"); GetConstructorID = get_method_id(env, ObjectClass, "getConstructor", "()I");
BooleanGetValueMethodID = get_method_id(env, BooleanClass, "booleanValue", "()Z"); BooleanGetValueMethodID = get_method_id(env, BooleanClass, "booleanValue", "()Z");
IntegerGetValueMethodID = get_method_id(env, IntegerClass, "intValue", "()I"); IntegerGetValueMethodID = get_method_id(env, IntegerClass, "intValue", "()I");

View File

@ -17,6 +17,7 @@ namespace td {
namespace td_api { namespace td_api {
class keyboardButton; class keyboardButton;
class inlineKeyboardButton; class inlineKeyboardButton;
class pageBlockTableCell;
} // namespace td_api } // namespace td_api
namespace jni { namespace jni {
@ -25,6 +26,7 @@ extern thread_local bool parse_error;
extern jclass ArrayKeyboardButtonClass; extern jclass ArrayKeyboardButtonClass;
extern jclass ArrayInlineKeyboardButtonClass; extern jclass ArrayInlineKeyboardButtonClass;
extern jclass ArrayPageBlockTableCellClass;
extern jmethodID GetConstructorID; extern jmethodID GetConstructorID;
extern jmethodID BooleanGetValueMethodID; extern jmethodID BooleanGetValueMethodID;
extern jmethodID IntegerGetValueMethodID; extern jmethodID IntegerGetValueMethodID;
@ -143,6 +145,14 @@ class get_array_class<td_api::inlineKeyboardButton> {
} }
}; };
template <>
class get_array_class<td_api::pageBlockTableCell> {
public:
static jclass get() {
return ArrayPageBlockTableCellClass;
}
};
template <class T> template <class T>
jobjectArray store_vector(JNIEnv *env, const std::vector<std::vector<T>> &v) { jobjectArray store_vector(JNIEnv *env, const std::vector<std::vector<T>> &v) {
jint length = static_cast<jint>(v.size()); jint length = static_cast<jint>(v.size());