diff --git a/resources/i18n/en-US/wiliwili.json b/resources/i18n/en-US/wiliwili.json index 99f3fe7d..545d5bc0 100644 --- a/resources/i18n/en-US/wiliwili.json +++ b/resources/i18n/en-US/wiliwili.json @@ -230,6 +230,10 @@ "history_delete": "Delete", "suggest": "Suggest" }, + "history": { + "clear": "Delete search history", + "clear_hint": "Your search history will be permanently deleted from this device" + }, "order": { "all": "All", "click": "Click", diff --git a/resources/i18n/zh-Hans/wiliwili.json b/resources/i18n/zh-Hans/wiliwili.json index b61f1534..bd338af6 100644 --- a/resources/i18n/zh-Hans/wiliwili.json +++ b/resources/i18n/zh-Hans/wiliwili.json @@ -230,6 +230,10 @@ "history_delete": "删除", "suggest": "猜你想搜" }, + "history": { + "clear": "清空历史记录", + "clear_hint": "确认清空历史记录?" + }, "order": { "all": "综合排序", "click": "最多播放", diff --git a/resources/i18n/zh-Hant/wiliwili.json b/resources/i18n/zh-Hant/wiliwili.json index 47599200..955d5bae 100644 --- a/resources/i18n/zh-Hant/wiliwili.json +++ b/resources/i18n/zh-Hant/wiliwili.json @@ -230,6 +230,10 @@ "history_delete": "删除", "suggest": "猜你想搜" }, + "history": { + "clear": "清空歷史記錄", + "clear_hint": "確認清空歷史記錄?" + }, "order": { "all": "綜合排序", "click": "最多播放", diff --git a/wiliwili/include/fragment/search_history.hpp b/wiliwili/include/fragment/search_history.hpp index c9c7f7ca..22cca396 100644 --- a/wiliwili/include/fragment/search_history.hpp +++ b/wiliwili/include/fragment/search_history.hpp @@ -27,5 +27,6 @@ class SearchHistory : public AttachedView { private: UpdateSearchEvent *updateSearchEvent = nullptr; + brls::Event<> clearSearchEvent; BRLS_BIND(RecyclingGrid, recyclingGrid, "search/history/recyclingGrid"); }; diff --git a/wiliwili/source/activity/search_activity_tv.cpp b/wiliwili/source/activity/search_activity_tv.cpp index ecfdb50c..b7e2132b 100644 --- a/wiliwili/source/activity/search_activity_tv.cpp +++ b/wiliwili/source/activity/search_activity_tv.cpp @@ -218,6 +218,10 @@ void TVSearchActivity::onContentAvailable() { searchHots->setSearchCallback(&updateSearchEvent); searchHistory->setSearchCallback(&updateSearchEvent); searchHistory->requestHistory(); + + // 强制设置搜索历史的 TabBar 为输入栏 + // 在清空历史时,会尝试将焦点切换到对应的 TabBar,这时在 TV 搜索页就能刚好将焦点切换到输入栏 + searchHistory->setTabBar((AutoSidebarItem*) inputLabel.getView()->getParent()); } TVSearchActivity::~TVSearchActivity() { brls::Logger::debug("TVSearchActivity: delete"); } diff --git a/wiliwili/source/fragment/search_history.cpp b/wiliwili/source/fragment/search_history.cpp index 85ccf0ae..f3c0e05b 100644 --- a/wiliwili/source/fragment/search_history.cpp +++ b/wiliwili/source/fragment/search_history.cpp @@ -5,10 +5,14 @@ #include "fragment/search_history.hpp" #include +#include +#include #include "view/recycling_grid.hpp" #include "view/hots_card.hpp" #include "utils/config_helper.hpp" +using namespace brls::literals; + SearchHistory::SearchHistory() { this->inflateFromXMLRes("xml/fragment/search_history.xml"); brls::Logger::debug("Fragment SearchHistory: create"); @@ -26,35 +30,63 @@ SearchHistory::~SearchHistory() { class HistoryDataSource : public RecyclingGridDataSource { public: - HistoryDataSource(std::vector result, UpdateSearchEvent **u) - : list(std::move(result)), updateSearchEvent(u) {} + HistoryDataSource(std::vector result, UpdateSearchEvent *u, brls::Event<> *c) + : list(std::move(result)), updateSearchEvent(u), clearSearchEvent(c) {} RecyclingGridItem *cellForRow(RecyclingGrid *recycler, size_t index) override { + if (index == list.size()) { + auto *item = (RecyclingGridItemHotsCard *)recycler->dequeueReusableCell("Cell"); + item->setCard("🤐", "wiliwili/search/history/clear"_i18n, ""); + return item; + } auto *item = (RecyclingGridItemHotsCard *)recycler->dequeueReusableCell("Cell"); item->setCard(std::to_string(index + 1), this->list[index], ""); return item; } void onItemSelected(RecyclingGrid *recycler, size_t index) override { - if (this->updateSearchEvent && *this->updateSearchEvent) { - (*this->updateSearchEvent)->fire(list[index]); + if (index == list.size() && this->clearSearchEvent) { + this->clearSearchEvent->fire(); + return; + } + if (this->updateSearchEvent) { + this->updateSearchEvent->fire(list[index]); } } - size_t getItemCount() override { return list.size(); } + size_t getItemCount() override { + if (list.empty()) return 0; + return list.size() + 1; + } void clearData() override { this->list.clear(); } private: std::vector list; - UpdateSearchEvent **updateSearchEvent = nullptr; + UpdateSearchEvent *updateSearchEvent = nullptr; + brls::Event<> *clearSearchEvent = nullptr; }; void SearchHistory::requestHistory() { - recyclingGrid->setDataSource( - new HistoryDataSource(ProgramConfig::instance().getHistoryList(), &this->updateSearchEvent)); + recyclingGrid->setDataSource(new HistoryDataSource(ProgramConfig::instance().getHistoryList(), + this->updateSearchEvent, &this->clearSearchEvent)); } -void SearchHistory::setSearchCallback(UpdateSearchEvent *event) { this->updateSearchEvent = event; } +void SearchHistory::setSearchCallback(UpdateSearchEvent *UpdateEvent) { + this->updateSearchEvent = UpdateEvent; + + this->clearSearchEvent.subscribe([this]() { + auto dialog = new brls::Dialog("wiliwili/search/history/clear_hint"_i18n); + dialog->addButton("hints/cancel"_i18n, []() {}); + dialog->addButton("hints/ok"_i18n, [this]() { + brls::sync([this]() { + brls::Application::giveFocus(this->getTabBar()); + ProgramConfig::instance().setHistory({}); + this->requestHistory(); + }); + }); + dialog->open(); + }); +} RecyclingGrid *SearchHistory::getRecyclingGrid() { return this->recyclingGrid; }