From 5c3111e56477a91b9134f437df4c75c521519bb0 Mon Sep 17 00:00:00 2001 From: HJfod <60038575+HJfod@users.noreply.github.com> Date: Mon, 22 Apr 2024 21:19:07 +0300 Subject: [PATCH] fix description & changelog not working on server mods --- loader/src/ui/GeodeUI.cpp | 3 ++ loader/src/ui/mods/popups/ModPopup.cpp | 64 ++++++++++++++++++++++-- loader/src/ui/mods/sources/ModSource.cpp | 58 ++++++++++++--------- loader/src/ui/mods/sources/ModSource.hpp | 4 +- 4 files changed, 98 insertions(+), 31 deletions(-) diff --git a/loader/src/ui/GeodeUI.cpp b/loader/src/ui/GeodeUI.cpp index 1448d2b8..ada7fbc8 100644 --- a/loader/src/ui/GeodeUI.cpp +++ b/loader/src/ui/GeodeUI.cpp @@ -147,6 +147,9 @@ protected: this->setSprite(CCSprite::createWithTexture(texture)); } } + else if (event->isCancelled()) { + this->setSprite(nullptr); + } } public: diff --git a/loader/src/ui/mods/popups/ModPopup.cpp b/loader/src/ui/mods/popups/ModPopup.cpp index 226c0fd8..a6e81b75 100644 --- a/loader/src/ui/mods/popups/ModPopup.cpp +++ b/loader/src/ui/mods/popups/ModPopup.cpp @@ -5,6 +5,60 @@ #include <Geode/utils/ColorProvider.hpp> #include "ConfirmUninstallPopup.hpp" +class FetchTextArea : public CCNode { +public: + using Request = server::ServerRequest<std::optional<std::string>>; + +protected: + EventListener<Request> m_listener; + MDTextArea* m_textarea; + CCNode* m_loading; + std::string m_noneText; + + bool init(Request const& req, std::string const& noneText, CCSize const& size) { + if (!CCNode::init()) + return false; + + this->setAnchorPoint({ .5f, .5f }); + this->setContentSize(size); + + m_noneText = noneText; + + m_textarea = MDTextArea::create("", size); + this->addChildAtPosition(m_textarea, Anchor::Center); + + m_loading = createLoadingCircle(30); + this->addChildAtPosition(m_loading, Anchor::Center); + + m_listener.bind(this, &FetchTextArea::onRequest); + m_listener.setFilter(req); + + return true; + } + + void onRequest(Request::Event* event) { + if (event->getValue() && event->getValue()->isOk() && event->getValue()->unwrap()) { + m_loading->removeFromParent(); + m_textarea->setString(event->getValue()->unwrap()->c_str()); + } + else if (!event->getProgress()) { + m_loading->removeFromParent(); + m_textarea->setString(m_noneText.c_str()); + } + } + +public: + static FetchTextArea* create(Request const& req, std::string const& noneText, CCSize const& size) { + auto ret = new FetchTextArea(); + if (ret && ret->init(req, noneText, size)) { + ret->autorelease(); + return ret; + } + CC_SAFE_DELETE(ret); + return nullptr; + } +}; + bool ModPopup::setup(ModSource&& src) { m_source = std::move(src); m_noElasticity = true; @@ -665,16 +719,18 @@ void ModPopup::loadTab(ModPopup::Tab tab) { const float mdScale = .85f; switch (tab) { case Tab::Details: { - m_currentTabPage = MDTextArea::create( - m_source.getAbout().value_or("No description provided"), + m_currentTabPage = FetchTextArea::create( + m_source.fetchAbout(), + "No description provided", size / mdScale ); m_currentTabPage->setScale(mdScale); } break; case Tab::Changelog: { - m_currentTabPage = MDTextArea::create( - m_source.getChangelog().value_or("No changelog provided"), + m_currentTabPage = FetchTextArea::create( + m_source.fetchChangelog(), + "No changelog provided", size / mdScale ); m_currentTabPage->setScale(mdScale); diff --git a/loader/src/ui/mods/sources/ModSource.cpp b/loader/src/ui/mods/sources/ModSource.cpp index b7301780..66275454 100644 --- a/loader/src/ui/mods/sources/ModSource.cpp +++ b/loader/src/ui/mods/sources/ModSource.cpp @@ -26,28 +26,6 @@ ModMetadata ModSource::getMetadata() const { } }, m_value); } -std::optional<std::string> ModSource::getAbout() const { - return std::visit(makeVisitor { - [](Mod* mod) { - return mod->getMetadata().getDetails(); - }, - [](server::ServerModMetadata const& metadata) { - // Versions should be guaranteed to have at least one item - return metadata.about; - } - }, m_value); -} -std::optional<std::string> ModSource::getChangelog() const { - return std::visit(makeVisitor { - [](Mod* mod) { - return mod->getMetadata().getChangelog(); - }, - [](server::ServerModMetadata const& metadata) { - // Versions should be guaranteed to have at least one item - return metadata.changelog; - } - }, m_value); -} CCNode* ModSource::createModLogo() const { return std::visit(makeVisitor { [](Mod* mod) { @@ -95,16 +73,46 @@ server::ServerModMetadata const* ModSource::asServer() const { return std::get_if<server::ServerModMetadata>(&m_value); } -server::ServerRequest<server::ServerModMetadata> ModSource::fetchServerInfo() const { +server::ServerRequest<std::optional<std::string>> ModSource::fetchAbout() const { return std::visit(makeVisitor { [](Mod* mod) { - return server::getMod(mod->getID()); + return server::ServerRequest<std::optional<std::string>>::immediate(Ok(mod->getMetadata().getDetails())); }, [](server::ServerModMetadata const& metadata) { - return server::ServerRequest<server::ServerModMetadata>::immediate(Ok(metadata)); + return server::getMod(metadata.id).map( + [](auto* result) -> Result<std::optional<std::string>, server::ServerError> { + if (result->isOk()) { + return Ok(result->unwrap().about); + } + return Err(result->unwrapErr()); + } + ); } }, m_value); } +server::ServerRequest<std::optional<std::string>> ModSource::fetchChangelog() const { + return std::visit(makeVisitor { + [](Mod* mod) { + return server::ServerRequest<std::optional<std::string>>::immediate(Ok(mod->getMetadata().getChangelog())); + }, + [](server::ServerModMetadata const& metadata) { + return server::getMod(metadata.id).map( + [](auto* result) -> Result<std::optional<std::string>, server::ServerError> { + if (result->isOk()) { + return Ok(result->unwrap().changelog); + } + return Err(result->unwrapErr()); + } + ); + } + }, m_value); +} +server::ServerRequest<server::ServerModMetadata> ModSource::fetchServerInfo() const { + // Request the info even if this is already a server mod because this might + // not have the full details (for example changelog) and the server cache + // should deal with performance issues + return server::getMod(this->getID()); +} server::ServerRequest<std::unordered_set<std::string>> ModSource::fetchValidTags() const { return std::visit(makeVisitor { [](Mod* mod) { diff --git a/loader/src/ui/mods/sources/ModSource.hpp b/loader/src/ui/mods/sources/ModSource.hpp index 6d4af8d3..51ebd99d 100644 --- a/loader/src/ui/mods/sources/ModSource.hpp +++ b/loader/src/ui/mods/sources/ModSource.hpp @@ -17,8 +17,6 @@ public: std::string getID() const; ModMetadata getMetadata() const; - std::optional<std::string> getAbout() const; - std::optional<std::string> getChangelog() const; CCNode* createModLogo() const; bool wantsRestart() const; // note: be sure to call checkUpdates first... @@ -36,6 +34,8 @@ public: server::ServerModMetadata const* asServer() const; server::ServerRequest<server::ServerModMetadata> fetchServerInfo() const; + server::ServerRequest<std::optional<std::string>> fetchAbout() const; + server::ServerRequest<std::optional<std::string>> fetchChangelog() const; server::ServerRequest<std::unordered_set<std::string>> fetchValidTags() const; server::ServerRequest<std::optional<server::ServerModUpdate>> checkUpdates(); };