diff --git a/resources/xml/views/video_card_search_pgc.xml b/resources/xml/views/video_card_search_pgc.xml index 59882b1ad..64692feab 100644 --- a/resources/xml/views/video_card_search_pgc.xml +++ b/resources/xml/views/video_card_search_pgc.xml @@ -76,7 +76,7 @@ textColor="@theme/font/grey"/> - ", ""); - nlohmann_json_t.title = pystring::replace(nlohmann_json_t.title, "", ""); - nlohmann_json_t.title = pystring::replace(nlohmann_json_t.title, """, "\""); } typedef std::vector VideoItemSearchListResult; diff --git a/wiliwili/include/fragment/search_tab.hpp b/wiliwili/include/fragment/search_tab.hpp index 1bf29b68b..fcf20bade 100644 --- a/wiliwili/include/fragment/search_tab.hpp +++ b/wiliwili/include/fragment/search_tab.hpp @@ -27,7 +27,39 @@ class SearchHistory; class AutoTabFrame; typedef brls::Event UpdateSearchEvent; -class DataSourceSearchVideoList : public RecyclingGridDataSource { +class titleParser { +public: + /** + * 解析搜索结果标题 + * @param title 带有em标签的标题 + * @return 富文本元素 + */ + static RichTextData parseTitle(const std::string& title) { + static NVGcolor fontColor = brls::Application::getTheme().getColor("brls/text"); + static NVGcolor biliColor = brls::Application::getTheme().getColor("color/bilibili"); + RichTextData d; + std::string res = title; + res = pystring::replace(res, "&", "&"); + res = pystring::replace(res, "<", "<"); + res = pystring::replace(res, ">", ">"); + res = pystring::replace(res, """, "\""); + res = pystring::replace(res, " ", " "); + auto p1 = pystring::split(res, ""); + if (!p1[0].empty()) d.emplace_back(std::make_shared(p1[0], fontColor)); + for (size_t i = 1; i < p1.size(); i++) { + auto p2 = pystring::split(p1[i], "", 1); + if (p2.size() < 2) { + d.emplace_back(std::make_shared(p1[i], fontColor)); + continue; + } + if (!p2[0].empty()) d.emplace_back(std::make_shared(p2[0], biliColor)); + if (!p2[1].empty()) d.emplace_back(std::make_shared(p2[1], fontColor)); + } + return d; + } +}; + +class DataSourceSearchVideoList : public RecyclingGridDataSource, public titleParser { public: explicit DataSourceSearchVideoList(bilibili::VideoItemSearchListResult result) : list(std::move(result)) {} @@ -36,8 +68,9 @@ class DataSourceSearchVideoList : public RecyclingGridDataSource { RecyclingGridItemVideoCard* item = (RecyclingGridItemVideoCard*)recycler->dequeueReusableCell("Cell"); bilibili::VideoItemSearchResult& r = this->list[index]; - item->setCard(r.cover + ImageHelper::h_ext, r.title, r.subtitle, r.pubdate, r.play, r.danmaku, + item->setCard(r.cover + ImageHelper::h_ext, "", r.subtitle, r.pubdate, r.play, r.danmaku, wiliwili::uglyString2Time(r.rightBottomBadge)); + item->setTitle(parseTitle(r.title)); return item; } @@ -62,7 +95,7 @@ class DataSourceSearchVideoList : public RecyclingGridDataSource { bilibili::VideoItemSearchListResult list; }; -class DataSourceSearchPGCList : public RecyclingGridDataSource { +class DataSourceSearchPGCList : public RecyclingGridDataSource, public titleParser { public: DataSourceSearchPGCList(bilibili::VideoItemSearchListResult result) : list(std::move(result)) {} @@ -88,8 +121,9 @@ class DataSourceSearchPGCList : public RecyclingGridDataSource { if (!r.index_show.empty()) subtitles.emplace_back(r.index_show); subtitle = pystring::join(" · ", subtitles); - item->setCard(r.cover + ImageHelper::v_ext, r.title, subtitle, cv, "简介: " + r.desc, r.badge.text, - r.badge.bg_color, score_count, score, r.season_type_name, r.areas); + item->setCard(r.cover + ImageHelper::v_ext, "", subtitle, cv, "简介: " + r.desc, r.badge.text, r.badge.bg_color, + score_count, score, r.season_type_name, r.areas); + item->setTitle(parseTitle(r.title)); return item; } diff --git a/wiliwili/include/view/video_card.hpp b/wiliwili/include/view/video_card.hpp index d09606b4c..5eea8f11f 100644 --- a/wiliwili/include/view/video_card.hpp +++ b/wiliwili/include/view/video_card.hpp @@ -5,9 +5,9 @@ #pragma once #include "view/recycling_grid.hpp" +#include "view/text_box.hpp" class SVGImage; -class TextBox; class BaseVideoCard : public RecyclingGridItem { public: @@ -36,6 +36,12 @@ class RecyclingGridItemVideoCard : public BaseVideoCard { const std::string& viewCount = "", const std::string& danmakuCount = "", const std::string& rightBottomBadge = "", const std::string& extra = ""); + /** + * 设置富文本标题 + * @param title 富文本标题 + */ + void setTitle(const RichTextData& title); + /** * 视频卡片基础信息 * @param title 视频标题 @@ -168,12 +174,18 @@ class RecyclingGridItemSearchPGCVideoCard : public BaseVideoCard { std::string badge_top, std::string badge_color, std::string scoreCount, std::string score, std::string type, std::string bottom); + /** + * 设置富文本标题 + * @param title 富文本标题 + */ + void setTitle(const RichTextData& title); + static RecyclingGridItem* create(); private: BRLS_BIND(brls::Box, boxTop, "video/card/badge/boxTop"); BRLS_BIND(brls::Label, badgeTop, "video/card/badge/top"); - BRLS_BIND(brls::Label, labelTitle, "video/card/label/title"); + BRLS_BIND(TextBox, labelTitle, "video/card/label/title"); BRLS_BIND(brls::Label, labelSubtitle, "video/card/label/subtitle"); BRLS_BIND(brls::Label, labelActor, "video/card/label/actor"); BRLS_BIND(brls::Label, labelDesc, "video/card/label/desc"); diff --git a/wiliwili/source/view/video_card.cpp b/wiliwili/source/view/video_card.cpp index ce4de7b7a..7673bd3dd 100644 --- a/wiliwili/source/view/video_card.cpp +++ b/wiliwili/source/view/video_card.cpp @@ -71,6 +71,10 @@ void RecyclingGridItemVideoCard::setExtraInfo(const std::string& extra, float wi } } +void RecyclingGridItemVideoCard::setTitle(const RichTextData& title) { + this->labelTitle->setRichText(title); +} + void RecyclingGridItemVideoCard::setBasicInfo(const std::string& title, const std::string& pic, const std::string& username) { this->labelTitle->setIsWrapping(true); this->labelTitle->setText(title); @@ -305,6 +309,10 @@ void RecyclingGridItemSearchPGCVideoCard::setCard(std::string pic, std::string t ImageHelper::with(this->picture)->load(pic); } +void RecyclingGridItemSearchPGCVideoCard::setTitle(const RichTextData& title) { + this->labelTitle->setRichText(title); +} + RecyclingGridItem* RecyclingGridItemSearchPGCVideoCard::create() { return new RecyclingGridItemSearchPGCVideoCard(); } /// PGC 查看更多卡片