Replace "Recommended" with "Featured" tab ()

* replace recommended with featured

* remove suggested source, update popup

* remove featured from isDefaultQuery
This commit is contained in:
Fleeym 2024-06-14 19:52:14 +03:00 committed by GitHub
parent 9679b4010d
commit 274b8d743f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 83 additions and 141 deletions

View file

@ -16,6 +16,7 @@
#include <Geode/binding/MenuLayer.hpp>
#include "popups/ConfirmInstall.hpp"
#include "GeodeStyle.hpp"
#include "ui/mods/sources/ModListSource.hpp"
bool ModsStatusNode::init() {
if (!CCNode::init())
@ -427,7 +428,7 @@ bool ModsLayer::init() {
for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*>> {
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button" },
{ "GJ_starsIcon_001.png", "Recommended", SuggestedModListSource::get(), "recommended-button" },
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button" },
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button" },
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button" },
}) {

View file

@ -52,7 +52,7 @@ protected:
CCMenuItemSpriteExtra* m_goToPageBtn;
ModsStatusNode* m_statusNode;
EventListener<UpdateModListStateFilter> m_updateStateListener;
bool m_showSearch = false;
bool m_showSearch = true;
bool m_bigView = false;
bool init();

View file

@ -3,10 +3,12 @@
#include <Geode/utils/ColorProvider.hpp>
#include <Geode/binding/ButtonSprite.hpp>
#include <Geode/loader/Loader.hpp>
#include <vector>
#include "../GeodeStyle.hpp"
#include "../popups/ModPopup.hpp"
#include "../popups/DevPopup.hpp"
#include "ui/mods/popups/ModErrorPopup.hpp"
#include "ui/mods/sources/ModSource.hpp"
bool ModItem::init(ModSource&& source) {
if (!CCNode::init())
@ -213,29 +215,48 @@ bool ModItem::init(ModSource&& source) {
});
downloadsContainer->updateLayout();
m_viewMenu->addChild(downloadsContainer);
},
[this](ModSuggestion const& suggestion) {
m_recommendedBy = CCNode::create();
m_recommendedBy->setID("recommended-container");
m_recommendedBy->setContentWidth(225);
auto byLabel = CCLabelBMFont::create("Recommended by ", "bigFont.fnt");
byLabel->setID("recommended-label");
byLabel->setColor("mod-list-recommended-by"_cc3b);
m_recommendedBy->addChild(byLabel);
// Check if mod is recommended by any others, only if not installed
if (!Loader::get()->isModInstalled(metadata.id)) {
std::vector<Mod*> recommends {};
for (auto& recommend : Loader::get()->getRecommendations()) {
auto suggestionID = recommend.message.substr(0, recommend.message.find(' '));
if (suggestionID != metadata.id) {
continue;
}
recommends.push_back(std::get<2>(recommend.cause));
}
auto nameLabel = CCLabelBMFont::create(suggestion.forMod->getName().c_str(), "bigFont.fnt");
nameLabel->setID("recommended-name-label");
nameLabel->setColor("mod-list-recommended-by-2"_cc3b);
m_recommendedBy->addChild(nameLabel);
if (recommends.size() > 0) {
m_recommendedBy = CCNode::create();
m_recommendedBy->setID("recommended-container");
m_recommendedBy->setContentWidth(225);
auto byLabel = CCLabelBMFont::create("Recommended by ", "bigFont.fnt");
byLabel->setID("recommended-label");
byLabel->setColor("mod-list-recommended-by"_cc3b);
m_recommendedBy->addChild(byLabel);
m_recommendedBy->setLayout(
std::string recommendStr = "";
if (recommends.size() == 1) {
recommendStr = recommends[0]->getName();
} else {
recommendStr = fmt::format("{} installed mods", recommends.size());
}
auto nameLabel = CCLabelBMFont::create(recommendStr.c_str(), "bigFont.fnt");
nameLabel->setID("recommended-name-label");
nameLabel->setColor("mod-list-recommended-by-2"_cc3b);
m_recommendedBy->addChild(nameLabel);
m_recommendedBy->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, 1.f)
->setAxisAlignment(AxisAlignment::Start)
);
m_infoContainer->addChild(m_recommendedBy);
},
->setDefaultScaleLimits(.1f, 1.f)
->setAxisAlignment(AxisAlignment::Start)
);
m_infoContainer->addChild(m_recommendedBy);
}
}
}
});
auto updateSpr = createGeodeCircleButton(

View file

@ -2,6 +2,7 @@
#include <Geode/binding/ButtonSprite.hpp>
#include <Geode/ui/MDTextArea.hpp>
#include <Geode/utils/web.hpp>
#include <Geode/loader/Loader.hpp>
#include <Geode/ui/GeodeUI.hpp>
#include <Geode/utils/ColorProvider.hpp>
#include "ConfirmUninstallPopup.hpp"
@ -105,28 +106,47 @@ bool ModPopup::setup(ModSource&& src) {
dev->setAnchorPoint({ .0f, .5f });
titleContainer->addChildAtPosition(dev, Anchor::BottomLeft, ccp(devAndTitlePos, titleContainer->getContentHeight() * .25f));
if (auto suggestion = m_source.asSuggestion()) {
title->updateAnchoredPosition(Anchor::TopLeft, ccp(devAndTitlePos, -2));
dev->updateAnchoredPosition(Anchor::Left, ccp(devAndTitlePos, 0));
// Suggestions
if (!Loader::get()->isModInstalled(m_source.getMetadata().getID())) {
std::vector<Mod*> recommends {};
for (auto& problem : Loader::get()->getRecommendations()) {
auto suggestionID = problem.message.substr(0, problem.message.find(' '));
if (suggestionID != m_source.getMetadata().getID()) {
continue;
}
recommends.push_back(std::get<2>(problem.cause));
}
auto recommendedBy = CCNode::create();
recommendedBy->setContentWidth(titleContainer->getContentWidth() - devAndTitlePos);
recommendedBy->setAnchorPoint({ .0f, .5f });
if (recommends.size() > 0) {
title->updateAnchoredPosition(Anchor::TopLeft, ccp(devAndTitlePos, -2));
dev->updateAnchoredPosition(Anchor::Left, ccp(devAndTitlePos, 0));
auto byLabel = CCLabelBMFont::create("Recommended by ", "bigFont.fnt");
byLabel->setColor("mod-list-recommended-by"_cc3b);
recommendedBy->addChild(byLabel);
auto recommendedBy = CCNode::create();
recommendedBy->setContentWidth(titleContainer->getContentWidth() - devAndTitlePos);
recommendedBy->setAnchorPoint({ .0f, .5f });
auto nameLabel = CCLabelBMFont::create(suggestion->forMod->getName().c_str(), "bigFont.fnt");
nameLabel->setColor("mod-list-recommended-by-2"_cc3b);
recommendedBy->addChild(nameLabel);
auto byLabel = CCLabelBMFont::create("Recommended by ", "bigFont.fnt");
byLabel->setColor("mod-list-recommended-by"_cc3b);
recommendedBy->addChild(byLabel);
recommendedBy->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, 1.f)
->setAxisAlignment(AxisAlignment::Start)
);
titleContainer->addChildAtPosition(recommendedBy, Anchor::BottomLeft, ccp(devAndTitlePos, 4));
std::string suggestionStr {};
if (recommends.size() == 1) {
suggestionStr = recommends[0]->getName();
} else {
suggestionStr = fmt::format("{} installed mods", recommends.size());
}
auto nameLabel = CCLabelBMFont::create(suggestionStr.c_str(), "bigFont.fnt");
nameLabel->setColor("mod-list-recommended-by-2"_cc3b);
recommendedBy->addChild(nameLabel);
recommendedBy->setLayout(
RowLayout::create()
->setDefaultScaleLimits(.1f, 1.f)
->setAxisAlignment(AxisAlignment::Start)
);
titleContainer->addChildAtPosition(recommendedBy, Anchor::BottomLeft, ccp(devAndTitlePos, 4));
}
}
leftColumn->addChild(titleContainer);
@ -575,7 +595,7 @@ void ModPopup::updateState() {
m_reenableBtn->setVisible(asMod && modRequestedActionIsToggle(asMod->getRequestedAction()));
m_updateBtn->setVisible(m_source.hasUpdates().has_value() && asMod->getRequestedAction() == ModRequestedAction::None);
m_installBtn->setVisible(m_source.asServer() || m_source.asSuggestion());
m_installBtn->setVisible(m_source.asServer());
m_uninstallBtn->setVisible(asMod && asMod->getRequestedAction() == ModRequestedAction::None);
if (asMod && modRequestedActionIsUninstall(asMod->getRequestedAction())) {
@ -923,9 +943,6 @@ ModPopup* ModPopup::create(ModSource&& src) {
if (src.asServer()) {
style = GeodePopupStyle::Alt;
}
else if (src.asSuggestion()) {
style = GeodePopupStyle::Alt2;
}
if (ret && ret->init(440, 280, std::move(src), style)) {
ret->autorelease();
return ret;

View file

@ -138,30 +138,6 @@ public:
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 {
protected:
SuggestedModsQuery m_query;
void resetQuery() override;
ProviderTask fetchPage(size_t page, size_t pageSize, bool forceUpdate) override;
void setSearchQuery(std::string const& query) override;
SuggestedModListSource();
public:
static SuggestedModListSource* get();
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 {
Download,
Featured,

View file

@ -41,7 +41,6 @@ LoadModSuggestionTask loadModSuggestion(LoadProblem const& problem) {
ModSource::ModSource(Mod* mod) : m_value(mod) {}
ModSource::ModSource(server::ServerModMetadata&& metadata) : m_value(metadata) {}
ModSource::ModSource(ModSuggestion&& suggestion) : m_value(suggestion) {}
std::string ModSource::getID() const {
return std::visit(makeVisitor {
@ -145,9 +144,6 @@ Mod* ModSource::asMod() const {
server::ServerModMetadata const* ModSource::asServer() const {
return std::get_if<server::ServerModMetadata>(&m_value);
}
ModSuggestion const* ModSource::asSuggestion() const {
return std::get_if<ModSuggestion>(&m_value);
}
server::ServerRequest<std::optional<std::string>> ModSource::fetchAbout() const {
if (auto mod = this->asMod()) {

View file

@ -16,7 +16,7 @@ LoadModSuggestionTask loadModSuggestion(LoadProblem const& problem);
class ModSource final {
private:
std::variant<Mod*, server::ServerModMetadata, ModSuggestion> m_value;
std::variant<Mod*, server::ServerModMetadata> m_value;
std::optional<server::ServerModUpdate> m_availableUpdate;
public:
@ -42,7 +42,6 @@ public:
Mod* asMod() const;
server::ServerModMetadata const* asServer() const;
ModSuggestion const* asSuggestion() const;
std::string formatDevelopers() const;
server::ServerRequest<server::ServerModMetadata> fetchServerInfo() const;

View file

@ -99,7 +99,6 @@ InvalidateQueryAfter<server::ModsQuery> ServerModListSource::getQueryMut() {
}
bool ServerModListSource::isDefaultQuery() const {
return !m_query.query.has_value() &&
!m_query.featured.has_value() &&
m_query.tags.empty() &&
!m_query.developer.has_value();
}

View file

@ -1,67 +0,0 @@
#include "ModListSource.hpp"
bool SuggestedModsQuery::preCheck(ModSource const& src) const {
// There are no extra fields in SuggestedModsQuery
return true;
}
bool SuggestedModsQuery::queryCheck(ModSource const& src, double& weighted) const {
if (query) {
if (!modFuzzyMatch(src.asSuggestion()->suggestion, *query, weighted)) {
return false;
}
return modFuzzyMatch(src.asSuggestion()->forMod->getMetadata(), *query, weighted);
}
return true;
}
bool SuggestedModsQuery::isDefault() const {
return LocalModsQueryBase::isDefault();
}
void SuggestedModListSource::resetQuery() {
m_query = SuggestedModsQuery();
}
SuggestedModListSource::ProviderTask SuggestedModListSource::fetchPage(size_t page, size_t pageSize, bool forceUpdate) {
m_query.page = page;
m_query.pageSize = pageSize;
std::vector<LoadModSuggestionTask> tasks;
for (auto problem : Loader::get()->getRecommendations()) {
tasks.push_back(loadModSuggestion(problem));
}
return LoadModSuggestionTask::all(std::move(tasks)).map(
[query = m_query](auto* results) -> ProviderTask::Value {
auto content = ProvidedMods();
for (auto& result : *results) {
if (result && *result) {
content.mods.push_back(ModSource(ModSuggestion(**result)));
}
}
// Filter the results based on the current search
// query and return them
filterModsWithLocalQuery(content, query);
return Ok(std::move(content));
},
[](auto*) -> ProviderTask::Progress { return std::nullopt; }
);
}
SuggestedModListSource::SuggestedModListSource() {}
SuggestedModListSource* SuggestedModListSource::get() {
static auto inst = new SuggestedModListSource();
return inst;
}
void SuggestedModListSource::setSearchQuery(std::string const& query) {
m_query.query = query.size() ? std::optional(query) : std::nullopt;
}
std::unordered_set<std::string> SuggestedModListSource::getModTags() const {
return m_query.tags;
}
void SuggestedModListSource::setModTags(std::unordered_set<std::string> const& tags) {
m_query.tags = tags;
this->clearCache();
}
bool SuggestedModListSource::isDefaultQuery() const {
return m_query.isDefault();
}