diff --git a/loader/src/ui/mods/GeodeStyle.cpp b/loader/src/ui/mods/GeodeStyle.cpp index 907ff90c..247b6ae9 100644 --- a/loader/src/ui/mods/GeodeStyle.cpp +++ b/loader/src/ui/mods/GeodeStyle.cpp @@ -69,14 +69,17 @@ bool GeodeSquareSprite::init(CCSprite* top, bool* state) { return true; } +void GeodeSquareSprite::updateImage() { + this->setTexture(CCTextureCache::get()->addImage( + (m_state ? "GJ_button_02.png" : (isGeodeTheme() ? "GE_button_05.png"_spr : "GJ_button_01.png")), + true + )); +} void GeodeSquareSprite::update(float dt) { CCSprite::update(dt); if (m_stateSrc && m_state != *m_stateSrc) { m_state = *m_stateSrc; - this->setTexture(CCTextureCache::get()->addImage( - (m_state ? "GJ_button_02.png" : (isGeodeTheme() ? "GE_button_05.png"_spr : "GJ_button_01.png")), - true - )); + this->updateImage(); } } @@ -89,7 +92,6 @@ GeodeSquareSprite* GeodeSquareSprite::create(const char* top, bool* state) { CC_SAFE_DELETE(ret); return nullptr; } - GeodeSquareSprite* GeodeSquareSprite::createWithSpriteFrameName(const char* top, bool* state) { auto ret = new GeodeSquareSprite(); if (ret && ret->init(CCSprite::createWithSpriteFrameName(top), state)) { @@ -104,6 +106,13 @@ CCSprite* GeodeSquareSprite::getTopSprite() const { return m_topSprite; } +void GeodeSquareSprite::setState(bool state) { + if (!m_stateSrc) { + m_state = state; + this->updateImage(); + } +} + class LoadingSpinner : public CCNode { protected: CCSprite* m_spinner; diff --git a/loader/src/ui/mods/GeodeStyle.hpp b/loader/src/ui/mods/GeodeStyle.hpp index d3b2d252..75b0d069 100644 --- a/loader/src/ui/mods/GeodeStyle.hpp +++ b/loader/src/ui/mods/GeodeStyle.hpp @@ -50,12 +50,14 @@ protected: bool init(CCSprite* top, bool* state); void update(float dt) override; + void updateImage(); public: static GeodeSquareSprite* create(const char* top, bool* state = nullptr); static GeodeSquareSprite* createWithSpriteFrameName(const char* top, bool* state = nullptr); CCSprite* getTopSprite() const; + void setState(bool state); }; CCNode* createLoadingCircle(float sideLength, const char* id = "loading-spinner"); diff --git a/loader/src/ui/mods/list/ModList.cpp b/loader/src/ui/mods/list/ModList.cpp index 24660904..af298df0 100644 --- a/loader/src/ui/mods/list/ModList.cpp +++ b/loader/src/ui/mods/list/ModList.cpp @@ -200,24 +200,24 @@ bool ModList::init(ModListSource* src, CCSize const& size) { ); if (!typeinfo_cast<ServerModListSource*>(m_source)) { sortBtn->setEnabled(false); - sortSpr->setColor({ 150, 150, 150 }); + sortSpr->setColor(ccGRAY); sortSpr->setOpacity(105); - sortSpr->getTopSprite()->setColor({ 150, 150, 150 }); + sortSpr->getTopSprite()->setColor(ccGRAY); sortSpr->getTopSprite()->setOpacity(105); } searchFiltersMenu->addChild(sortBtn); - auto filterBtn = CCMenuItemSpriteExtra::create( + m_filtersBtn = CCMenuItemSpriteExtra::create( GeodeSquareSprite::createWithSpriteFrameName("GJ_filterIcon_001.png"), this, menu_selector(ModList::onFilters) ); - searchFiltersMenu->addChild(filterBtn); + searchFiltersMenu->addChild(m_filtersBtn); - auto clearFiltersBtn = CCMenuItemSpriteExtra::create( + m_clearFiltersBtn = CCMenuItemSpriteExtra::create( GeodeSquareSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png"), this, menu_selector(ModList::onClearFilters) ); - searchFiltersMenu->addChild(clearFiltersBtn); + searchFiltersMenu->addChild(m_clearFiltersBtn); searchFiltersMenu->setLayout( RowLayout::create() @@ -522,6 +522,18 @@ void ModList::updateState() { m_pagePrevBtn->setVisible(pageCount && m_page > 0); m_pageNextBtn->setVisible(pageCount && m_page < pageCount.value() - 1); + // Update filter button states + auto isDefaultQuery = m_source->isDefaultQuery(); + + auto filterSpr = static_cast<GeodeSquareSprite*>(m_filtersBtn->getNormalImage()); + filterSpr->setState(!isDefaultQuery); + + auto clearSpr = static_cast<GeodeSquareSprite*>(m_clearFiltersBtn->getNormalImage()); + clearSpr->setColor(isDefaultQuery ? ccGRAY : ccWHITE); + clearSpr->setOpacity(isDefaultQuery ? 90 : 255); + clearSpr->getTopSprite()->setColor(isDefaultQuery ? ccGRAY : ccWHITE); + clearSpr->getTopSprite()->setOpacity(isDefaultQuery ? 90 : 255); + // Post the update page number event UpdateModListStateEvent(UpdatePageNumberState()).post(); } @@ -573,17 +585,13 @@ void ModList::showStatus(ModListStatus status, std::string const& message, std:: void ModList::onFilters(CCObject*) { FiltersPopup::create(m_source)->show(); } - void ModList::onSort(CCObject*) { SortPopup::create(m_source)->show(); } - void ModList::onClearFilters(CCObject*) { - // FIXME: reloads twice - m_source->setModTags({}); - m_searchInput->setString("", true); + m_searchInput->setString("", false); + m_source->reset(); } - void ModList::onToggleUpdates(CCObject*) { if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) { auto mut = src->getQueryMut(); @@ -592,7 +600,6 @@ void ModList::onToggleUpdates(CCObject*) { InstalledModListType::OnlyUpdates; } } - void ModList::onToggleErrors(CCObject*) { if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) { auto mut = src->getQueryMut(); @@ -601,7 +608,6 @@ void ModList::onToggleErrors(CCObject*) { InstalledModListType::OnlyErrors; } } - void ModList::onUpdateAll(CCObject*) { server::ModDownloadManager::get()->startUpdateAll(); } diff --git a/loader/src/ui/mods/list/ModList.hpp b/loader/src/ui/mods/list/ModList.hpp index 830fa222..34167ea9 100644 --- a/loader/src/ui/mods/list/ModList.hpp +++ b/loader/src/ui/mods/list/ModList.hpp @@ -42,6 +42,8 @@ protected: CCMenuItemToggler* m_toggleErrorsOnlyBtn = nullptr; TextArea* m_updateCountLabel = nullptr; TextInput* m_searchInput; + CCMenuItemSpriteExtra* m_filtersBtn; + CCMenuItemSpriteExtra* m_clearFiltersBtn; EventListener<InvalidateCacheFilter> m_invalidateCacheListener; EventListener<server::ServerRequest<std::vector<std::string>>> m_checkUpdatesListener; EventListener<server::ModDownloadFilter> m_downloadListener; diff --git a/loader/src/ui/mods/popups/DevPopup.cpp b/loader/src/ui/mods/popups/DevPopup.cpp index 20c5eda2..b9c5a82b 100644 --- a/loader/src/ui/mods/popups/DevPopup.cpp +++ b/loader/src/ui/mods/popups/DevPopup.cpp @@ -10,7 +10,7 @@ bool DevListPopup::setup(ModMetadata const& meta) { for (auto dev : meta.getDevelopers()) { auto menu = CCMenu::create(); - menu->setContentWidth(90); + menu->setContentWidth(m_size.width - 30); auto label = CCLabelBMFont::create(dev.c_str(), "bigFont.fnt"); label->setLayoutOptions(AxisLayoutOptions::create()->setScalePriority(1)); @@ -55,7 +55,7 @@ void DevListPopup::onMoreByThisDev(CCObject* sender) { DevListPopup* DevListPopup::create(ModMetadata const& meta) { auto ret = new DevListPopup(); - if (ret && ret->init(200, 180, meta)) { + if (ret && ret->init(220, 220, meta)) { ret->autorelease(); return ret; } diff --git a/loader/src/ui/mods/popups/FiltersPopup.cpp b/loader/src/ui/mods/popups/FiltersPopup.cpp index 1539b978..ca0dc534 100644 --- a/loader/src/ui/mods/popups/FiltersPopup.cpp +++ b/loader/src/ui/mods/popups/FiltersPopup.cpp @@ -1,5 +1,4 @@ #include "FiltersPopup.hpp" -#include <Geode/ui/TextInput.hpp> bool FiltersPopup::setup(ModListSource* src) { m_noElasticity = true; @@ -55,68 +54,82 @@ bool FiltersPopup::setup(ModListSource* src) { m_mainLayer->addChildAtPosition(tagsContainer, Anchor::Top, ccp(0, -85)); - auto optionsContainer = CCNode::create(); - optionsContainer->setContentSize(ccp(160, 35)); - optionsContainer->setAnchorPoint({ .5f, .5f }); - optionsContainer->setVisible(false); + if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) { + auto optionsContainer = CCNode::create(); + optionsContainer->setContentSize(ccp(160, 35)); + optionsContainer->setAnchorPoint({ .5f, .5f }); - auto optionsBG = CCScale9Sprite::create("square02b_001.png"); - optionsBG->setColor({ 0, 0, 0 }); - optionsBG->setOpacity(75); - optionsBG->setScale(.3f); - optionsBG->setContentSize(optionsContainer->getContentSize() / optionsBG->getScale()); - optionsContainer->addChildAtPosition(optionsBG, Anchor::Center); + auto optionsBG = CCScale9Sprite::create("square02b_001.png"); + optionsBG->setColor({ 0, 0, 0 }); + optionsBG->setOpacity(75); + optionsBG->setScale(.3f); + optionsBG->setContentSize(optionsContainer->getContentSize() / optionsBG->getScale()); + optionsContainer->addChildAtPosition(optionsBG, Anchor::Center); - auto optionsMenu = CCMenu::create(); - optionsMenu->setContentSize(optionsContainer->getContentSize() - ccp(10, 10)); + auto optionsMenu = CCMenu::create(); + optionsMenu->setContentSize(optionsContainer->getContentSize() - ccp(10, 10)); - if (typeinfo_cast<InstalledModListSource*>(m_source)) { - auto enabledOnlyToggle = CCMenuItemToggler::createWithStandardSprites( - this, menu_selector(FiltersPopup::onToggle), .6f - ); - enabledOnlyToggle->m_notClickable = true; - enabledOnlyToggle->setUserData(reinterpret_cast<void*>(+[](ModListSource* src) -> bool { - auto mut = static_cast<InstalledModListSource*>(src)->getQueryMut(); - mut->enabledOnly = mut->enabledOnly.has_value() ? std::nullopt : std::optional(true); - return mut->enabledOnly.value_or(false); - })); - enabledOnlyToggle->toggle(static_cast<InstalledModListSource*>(src)->getQuery().enabledOnly.has_value()); - optionsMenu->addChildAtPosition(enabledOnlyToggle, Anchor::Left, ccp(15, 0)); + m_enabledModsOnly = CCMenuItemToggler::createWithStandardSprites(this, nullptr, .6f); + m_enabledModsOnly->toggle(src->getQuery().enabledOnly.has_value()); + optionsMenu->addChildAtPosition(m_enabledModsOnly, Anchor::Left, ccp(15, 0)); auto enabledOnlyLabel = CCLabelBMFont::create("Enabled Mods Only", "bigFont.fnt"); enabledOnlyLabel->setScale(.35f); optionsMenu->addChildAtPosition(enabledOnlyLabel, Anchor::Left, ccp(30, 0), ccp(0, .5f)); - optionsContainer->setVisible(true); + optionsContainer->addChildAtPosition(optionsMenu, Anchor::Center); + + auto optionsTitleMenu = CCMenu::create(); + optionsTitleMenu->setAnchorPoint({ .5f, 0 }); + optionsTitleMenu->setContentWidth(optionsContainer->getContentWidth()); + + auto optionsTitle = CCLabelBMFont::create("Options", "bigFont.fnt"); + optionsTitleMenu->addChild(optionsTitle); + + optionsTitleMenu->addChild(SpacerNode::create()); + + optionsTitleMenu->setLayout( + RowLayout::create() + ->setDefaultScaleLimits(.1f, .4f) + ); + optionsContainer->addChildAtPosition(optionsTitleMenu, Anchor::Top, ccp(0, 4)); + + m_mainLayer->addChildAtPosition(optionsContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f)); } - else if (typeinfo_cast<ServerModListSource*>(m_source)) { - auto input = TextInput::create(100, "Developer"); - input->setTextAlign(TextInputAlign::Left); - input->setLabel("Developer Name"); - optionsMenu->addChildAtPosition(input, Anchor::Left, ccp(15, 0)); + else if (auto src = typeinfo_cast<ServerModListSource*>(m_source)) { + auto inputContainer = CCNode::create(); + inputContainer->setContentSize(ccp(160, 35)); + inputContainer->setAnchorPoint({ .5f, .5f }); - optionsContainer->setVisible(true); + m_developerNameInput = TextInput::create(inputContainer->getContentWidth(), "Developer Name"); + m_developerNameInput->setTextAlign(TextInputAlign::Left); + m_developerNameInput->setString(src->getQuery().developer.value_or("")); + inputContainer->addChildAtPosition(m_developerNameInput, Anchor::Center); + + auto inputTitleMenu = CCMenu::create(); + inputTitleMenu->setAnchorPoint({ .5f, 0 }); + inputTitleMenu->setContentWidth(inputContainer->getContentWidth()); + + auto inputTitle = CCLabelBMFont::create("From Developer", "bigFont.fnt"); + inputTitleMenu->addChild(inputTitle); + + inputTitleMenu->addChild(SpacerNode::create()); + + auto resetSpr = CCSprite::createWithSpriteFrameName("GJ_trashBtn_001.png"); + auto resetBtn = CCMenuItemSpriteExtra::create( + resetSpr, this, menu_selector(FiltersPopup::onResetDevName) + ); + inputTitleMenu->addChild(resetBtn); + + inputTitleMenu->setLayout( + RowLayout::create() + ->setDefaultScaleLimits(.1f, .4f) + ); + inputContainer->addChildAtPosition(inputTitleMenu, Anchor::Top, ccp(0, 4)); + + m_mainLayer->addChildAtPosition(inputContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f)); } - optionsContainer->addChildAtPosition(optionsMenu, Anchor::Center); - - auto optionsTitleMenu = CCMenu::create(); - optionsTitleMenu->setAnchorPoint({ .5f, 0 }); - optionsTitleMenu->setContentWidth(optionsContainer->getContentWidth()); - - auto optionsTitle = CCLabelBMFont::create("Options", "bigFont.fnt"); - optionsTitleMenu->addChild(optionsTitle); - - optionsTitleMenu->addChild(SpacerNode::create()); - - optionsTitleMenu->setLayout( - RowLayout::create() - ->setDefaultScaleLimits(.1f, .4f) - ); - optionsContainer->addChildAtPosition(optionsTitleMenu, Anchor::Top, ccp(0, 4)); - - m_mainLayer->addChildAtPosition(optionsContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f)); - auto okSpr = createGeodeButton("OK"); okSpr->setScale(.7f); auto okBtn = CCMenuItemSpriteExtra::create( @@ -158,11 +171,6 @@ void FiltersPopup::onLoadTags(typename server::ServerRequest<std::unordered_set< } } -void FiltersPopup::onToggle(CCObject* sender) { - auto toggle = static_cast<CCMenuItemToggler*>(sender); - auto enabled = reinterpret_cast<bool(*)(ModListSource*)>(toggle->getUserData())(m_source); - toggle->toggle(enabled); -} void FiltersPopup::updateTags() { for (auto node : CCArrayExt<CCNode*>(m_tagsMenu->getChildren())) { if (auto toggle = typeinfo_cast<CCMenuItemToggler*>(node)) { @@ -186,8 +194,22 @@ void FiltersPopup::onResetTags(CCObject*) { m_selectedTags.clear(); this->updateTags(); } +void FiltersPopup::onResetDevName(CCObject*) { + if (m_developerNameInput) { + m_developerNameInput->setString(""); + } +} void FiltersPopup::onClose(CCObject* sender) { m_source->setModTags(m_selectedTags); + if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) { + src->getQueryMut()->enabledOnly = m_enabledModsOnly->isToggled() ? std::optional(true) : std::nullopt; + } + else if (auto src = typeinfo_cast<ServerModListSource*>(m_source)) { + src->getQueryMut()->developer = m_developerNameInput->getString(); + if (src->getQueryMut()->developer->empty()) { + src->getQueryMut()->developer.reset(); + } + } Popup::onClose(sender); } diff --git a/loader/src/ui/mods/popups/FiltersPopup.hpp b/loader/src/ui/mods/popups/FiltersPopup.hpp index c56646e7..cf741f77 100644 --- a/loader/src/ui/mods/popups/FiltersPopup.hpp +++ b/loader/src/ui/mods/popups/FiltersPopup.hpp @@ -1,6 +1,7 @@ #pragma once #include <Geode/ui/Popup.hpp> +#include <Geode/ui/TextInput.hpp> #include "../sources/ModListSource.hpp" #include "../GeodeStyle.hpp" #include <server/Server.hpp> @@ -13,13 +14,15 @@ protected: CCMenu* m_tagsMenu; std::unordered_set<std::string> m_selectedTags; EventListener<server::ServerRequest<std::unordered_set<std::string>>> m_tagsListener; + CCMenuItemToggler* m_enabledModsOnly = nullptr; + TextInput* m_developerNameInput = nullptr; bool setup(ModListSource* src) override; void updateTags(); - void onToggle(CCObject*); void onLoadTags(typename server::ServerRequest<std::unordered_set<std::string>>::Event* event); void onResetTags(CCObject*); + void onResetDevName(CCObject*); void onSelectTag(CCObject* sender); void onClose(CCObject* sender) override; diff --git a/loader/src/ui/mods/sources/InstalledModListSource.cpp b/loader/src/ui/mods/sources/InstalledModListSource.cpp index 78a52988..0aea81f0 100644 --- a/loader/src/ui/mods/sources/InstalledModListSource.cpp +++ b/loader/src/ui/mods/sources/InstalledModListSource.cpp @@ -32,6 +32,9 @@ bool InstalledModsQuery::queryCheck(ModSource const& src, double& weighted) cons // todo: favorites return addToList; } +bool InstalledModsQuery::isDefault() const { + return LocalModsQueryBase::isDefault() && !enabledOnly.has_value(); +} InstalledModListSource::InstalledModListSource(InstalledModListType type) : m_type(type) @@ -116,3 +119,6 @@ InstalledModsQuery const& InstalledModListSource::getQuery() const { InvalidateQueryAfter<InstalledModsQuery> InstalledModListSource::getQueryMut() { return InvalidateQueryAfter(m_query, this); } +bool InstalledModListSource::isDefaultQuery() const { + return m_query.isDefault(); +} diff --git a/loader/src/ui/mods/sources/ModListSource.cpp b/loader/src/ui/mods/sources/ModListSource.cpp index d372a79e..19ced217 100644 --- a/loader/src/ui/mods/sources/ModListSource.cpp +++ b/loader/src/ui/mods/sources/ModListSource.cpp @@ -23,6 +23,10 @@ ListenerResult InvalidateCacheFilter::handle(MiniFunction<Callback> fn, Invalida InvalidateCacheFilter::InvalidateCacheFilter(ModListSource* src) : m_source(src) {} +bool LocalModsQueryBase::isDefault() const { + return !query.has_value() && tags.empty(); +} + typename ModListSource::PageLoadTask ModListSource::loadPage(size_t page, bool forceUpdate) { if (!forceUpdate && m_cachedPages.contains(page)) { return PageLoadTask::immediate(Ok(m_cachedPages.at(page))); @@ -59,8 +63,8 @@ std::optional<size_t> ModListSource::getItemCount() const { } void ModListSource::reset() { - this->clearCache(); this->resetQuery(); + this->clearCache(); } void ModListSource::clearCache() { m_cachedPages.clear(); diff --git a/loader/src/ui/mods/sources/ModListSource.hpp b/loader/src/ui/mods/sources/ModListSource.hpp index e964f664..6b0a35ae 100644 --- a/loader/src/ui/mods/sources/ModListSource.hpp +++ b/loader/src/ui/mods/sources/ModListSource.hpp @@ -65,6 +65,7 @@ public: void reset(); void clearCache(); void search(std::string const& query); + virtual bool isDefaultQuery() const = 0; virtual std::unordered_set<std::string> getModTags() const = 0; virtual void setModTags(std::unordered_set<std::string> const& tags) = 0; @@ -97,9 +98,9 @@ public: struct LocalModsQueryBase { std::optional<std::string> query; std::unordered_set<std::string> tags = {}; - std::optional<bool> enabledOnly; size_t page = 0; size_t pageSize = 10; + bool isDefault() const; }; enum class InstalledModListType { @@ -109,8 +110,10 @@ enum class InstalledModListType { }; struct InstalledModsQuery final : public LocalModsQueryBase { InstalledModListType type = InstalledModListType::All; + std::optional<bool> enabledOnly; bool preCheck(ModSource const& src) const; bool queryCheck(ModSource const& src, double& weighted) const; + bool isDefault() const; }; class InstalledModListSource : public ModListSource { @@ -132,11 +135,13 @@ public: InstalledModsQuery const& getQuery() const; InvalidateQueryAfter<InstalledModsQuery> getQueryMut(); + bool isDefaultQuery() const override; }; struct SuggestedModsQuery final : public LocalModsQueryBase { bool preCheck(ModSource const& src) const; bool queryCheck(ModSource const& src, double& weighted) const; + bool isDefault() const; }; class SuggestedModListSource : public ModListSource { @@ -154,6 +159,7 @@ public: std::unordered_set<std::string> getModTags() const override; void setModTags(std::unordered_set<std::string> const& tags) override; + bool isDefaultQuery() const override; }; enum class ServerModListType { @@ -182,6 +188,7 @@ public: server::ModsQuery const& getQuery() const; InvalidateQueryAfter<server::ModsQuery> getQueryMut(); + bool isDefaultQuery() const override; }; class ModPackListSource : public ModListSource { @@ -197,6 +204,7 @@ public: std::unordered_set<std::string> getModTags() const override; void setModTags(std::unordered_set<std::string> const& tags) override; + bool isDefaultQuery() const override; }; bool weightedFuzzyMatch(std::string const& str, std::string const& kw, double weight, double& out); diff --git a/loader/src/ui/mods/sources/ModPackListSource.cpp b/loader/src/ui/mods/sources/ModPackListSource.cpp index bec26303..6063d4c7 100644 --- a/loader/src/ui/mods/sources/ModPackListSource.cpp +++ b/loader/src/ui/mods/sources/ModPackListSource.cpp @@ -18,3 +18,6 @@ std::unordered_set<std::string> ModPackListSource::getModTags() const { return {}; } void ModPackListSource::setModTags(std::unordered_set<std::string> const& set) {} +bool ModPackListSource::isDefaultQuery() const { + return true; +} diff --git a/loader/src/ui/mods/sources/ServerModListSource.cpp b/loader/src/ui/mods/sources/ServerModListSource.cpp index e737342e..b41504ef 100644 --- a/loader/src/ui/mods/sources/ServerModListSource.cpp +++ b/loader/src/ui/mods/sources/ServerModListSource.cpp @@ -97,3 +97,9 @@ server::ModsQuery const& ServerModListSource::getQuery() const { InvalidateQueryAfter<server::ModsQuery> ServerModListSource::getQueryMut() { return InvalidateQueryAfter(m_query, this); } +bool ServerModListSource::isDefaultQuery() const { + return !m_query.query.has_value() && + !m_query.featured.has_value() && + m_query.tags.empty() && + !m_query.developer.has_value(); +} diff --git a/loader/src/ui/mods/sources/SuggestedModListSource.cpp b/loader/src/ui/mods/sources/SuggestedModListSource.cpp index 56c35af4..e4990eaa 100644 --- a/loader/src/ui/mods/sources/SuggestedModListSource.cpp +++ b/loader/src/ui/mods/sources/SuggestedModListSource.cpp @@ -13,6 +13,9 @@ bool SuggestedModsQuery::queryCheck(ModSource const& src, double& weighted) cons } return true; } +bool SuggestedModsQuery::isDefault() const { + return LocalModsQueryBase::isDefault(); +} void SuggestedModListSource::resetQuery() { m_query = SuggestedModsQuery(); @@ -58,3 +61,7 @@ void SuggestedModListSource::setModTags(std::unordered_set<std::string> const& t m_query.tags = tags; this->clearCache(); } + +bool SuggestedModListSource::isDefaultQuery() const { + return m_query.isDefault(); +}