show updates button state is now properly updated :3

This commit is contained in:
HJfod 2024-03-30 19:51:18 +02:00
parent 17f6aa09bb
commit 6d3f72209f
7 changed files with 101 additions and 35 deletions

View file

@ -205,7 +205,7 @@ void ModsLayer::gotoTab(ModListSource* src) {
// Update the state of the current list
m_lists.at(m_currentSource)->updateSize(m_bigView);
m_lists.at(m_currentSource)->activateSearch(m_showSearch);
m_lists.at(m_currentSource)->updatePageNumber();
m_lists.at(m_currentSource)->updateState();
}
void ModsLayer::keyBackClicked() {

View file

@ -47,7 +47,6 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
// search query
if (m_source->isInstalledMods()) {
m_source->search(m_searchInput->getString());
this->gotoPage(0);
return;
}
// Otherwise buffer inputs by a bit
@ -60,7 +59,6 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
if (m_searchInputThreads == 0) {
Loader::get()->queueInMainThread([this] {
m_source->search(m_searchInput->getString());
this->gotoPage(0);
});
}
}).detach();
@ -124,17 +122,18 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
CCSprite::createWithSpriteFrameName("GJ_filterIcon_001.png"),
"Hide Updates", "GE_button_05.png"_spr
);
auto viewUpdatesBtn = CCMenuItemToggler::create(
showUpdatesSpr, hideUpdatesSpr, this, nullptr
m_toggleUpdatesOnlyBtn = CCMenuItemToggler::create(
showUpdatesSpr, hideUpdatesSpr, this, menu_selector(ModList::onToggleUpdates)
);
updateAllMenu->addChild(viewUpdatesBtn);
m_toggleUpdatesOnlyBtn->m_notClickable = true;
updateAllMenu->addChild(m_toggleUpdatesOnlyBtn);
auto updateAllSpr = createGeodeButton(
CCSprite::createWithSpriteFrameName("update.png"_spr),
"Update All", "GE_button_01.png"_spr
);
auto updateAllBtn = CCMenuItemSpriteExtra::create(
updateAllSpr, this, nullptr
updateAllSpr, this, menu_selector(ModList::onUpdateAll)
);
updateAllMenu->addChild(updateAllBtn);
@ -240,6 +239,9 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
m_listener.bind(this, &ModList::onPromise);
m_invalidateCacheListener.bind(this, &ModList::onInvalidateCache);
m_invalidateCacheListener.setFilter(InvalidateCacheFilter(m_source));
this->gotoPage(0);
this->updateTopContainer();
@ -272,7 +274,7 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
m_list->m_contentLayer->setPositionY(listTopScrollPos);
// Update page UI
this->updatePageNumber();
this->updateState();
}
else if (auto progress = event->getProgress()) {
// todo: percentage in a loading bar
@ -287,7 +289,7 @@ void ModList::onPromise(typename ModListSource::PageLoadEvent* event) {
}
else if (auto rejected = event->getReject()) {
this->showStatus(ModListErrorStatus(), rejected->message, rejected->details);
this->updatePageNumber();
this->updateState();
}
if (event->isFinally()) {
@ -335,6 +337,10 @@ void ModList::onCheckUpdates(PromiseEvent<std::vector<std::string>, server::Serv
}
}
void ModList::onInvalidateCache(InvalidateCacheEvent* event) {
this->gotoPage(0);
}
void ModList::activateSearch(bool activate) {
m_searchMenu->setVisible(activate);
this->updateTopContainer();
@ -393,7 +399,15 @@ void ModList::updateSize(bool big) {
) * oldPosition);
}
void ModList::updatePageNumber() {
void ModList::updateState() {
// Update the "Show Updates" button on the updates available banner
if (m_toggleUpdatesOnlyBtn) {
auto src = typeinfo_cast<InstalledModListSource*>(m_source);
if (src) {
m_toggleUpdatesOnlyBtn->toggle(src->getQuery().onlyUpdates);
}
}
auto pageCount = m_source->getPageCount();
// Hide if page count hasn't been loaded
@ -420,7 +434,7 @@ void ModList::gotoPage(size_t page, bool update) {
// Do initial eager update on page UI (to prevent user spamming arrows
// to access invalid pages)
this->updatePageNumber();
this->updateState();
}
void ModList::showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details) {
@ -453,15 +467,21 @@ void ModList::showStatus(ModListStatus status, std::string const& message, std::
}
void ModList::onFilters(CCObject*) {
TagsPopup::create(m_source, [this]() {
this->gotoPage(0);
})->show();
TagsPopup::create(m_source)->show();
}
void ModList::onClearFilters(CCObject*) {
m_searchInput->setString("", true);
}
void ModList::onToggleUpdates(CCObject*) {
if (auto src = typeinfo_cast<InstalledModListSource*>(m_source)) {
src->getQueryMut()->onlyUpdates = !src->getQuery().onlyUpdates;
}
}
void ModList::onUpdateAll(CCObject*) {}
size_t ModList::getPage() const {
return m_page;
}

View file

@ -33,9 +33,10 @@ protected:
CCNode* m_topContainer;
CCNode* m_searchMenu;
CCNode* m_updateAllMenu = nullptr;
CCMenuItemToggler* m_toggleUpdatesOnlyBtn = nullptr;
TextArea* m_updateCountLabel = nullptr;
TextInput* m_searchInput;
EventListener<UpdateModListStateFilter> m_updateStateListener;
EventListener<InvalidateCacheFilter> m_invalidateCacheListener;
EventListener<PromiseEventFilter<std::vector<std::string>, server::ServerError>> m_checkUpdatesListener;
bool m_bigSize = false;
std::atomic<size_t> m_searchInputThreads = 0;
@ -44,12 +45,15 @@ protected:
void updateTopContainer();
void onCheckUpdates(PromiseEvent<std::vector<std::string>, server::ServerError>* event);
void onInvalidateCache(InvalidateCacheEvent* event);
void onPromise(ModListSource::PageLoadEvent* event);
void onPage(CCObject*);
void onShowStatusDetails(CCObject*);
void onFilters(CCObject*);
void onClearFilters(CCObject*);
void onToggleUpdates(CCObject*);
void onUpdateAll(CCObject*);
public:
static ModList* create(ModListSource* src, CCSize const& size);
@ -60,7 +64,7 @@ public:
void gotoPage(size_t page, bool update = false);
void showStatus(ModListStatus status, std::string const& message, std::optional<std::string> const& details = std::nullopt);
void updatePageNumber();
void updateState();
void updateSize(bool big);
void activateSearch(bool activate);
};

View file

@ -1,9 +1,8 @@
#include "TagsPopup.hpp"
bool TagsPopup::setup(ModListSource* src, MiniFunction<void()> onClose) {
bool TagsPopup::setup(ModListSource* src) {
m_noElasticity = true;
m_source = src;
m_onClose = onClose;
this->setTitle("Select Tags");
@ -13,13 +12,13 @@ bool TagsPopup::setup(ModListSource* src, MiniFunction<void()> onClose) {
}
void TagsPopup::onClose(CCObject* sender) {
if (m_onClose) m_onClose();
InvalidateCacheEvent(m_source).post();
Popup::onClose(sender);
}
TagsPopup* TagsPopup::create(ModListSource* src, MiniFunction<void()> onClose) {
TagsPopup* TagsPopup::create(ModListSource* src) {
auto ret = new TagsPopup();
if (ret && ret->init(260, 200, src, onClose)) {
if (ret && ret->init(260, 200, src)) {
ret->autorelease();
return ret;
}

View file

@ -6,15 +6,14 @@
using namespace geode::prelude;
class TagsPopup : public GeodePopup<ModListSource*, MiniFunction<void()>> {
class TagsPopup : public GeodePopup<ModListSource*> {
protected:
ModListSource* m_source;
MiniFunction<void()> m_onClose;
bool setup(ModListSource* src, MiniFunction<void()> onClose) override;
bool setup(ModListSource* src) override;
void onClose(CCObject*) override;
public:
static TagsPopup* create(ModListSource* src, MiniFunction<void()> onClose);
static TagsPopup* create(ModListSource* src);
};

View file

@ -82,6 +82,17 @@ static void filterModsWithQuery(InstalledModListSource::ProvidedMods& mods, Inst
mods.totalModCount = filtered.size();
}
InvalidateCacheEvent::InvalidateCacheEvent(ModListSource* src) : source(src) {}
ListenerResult InvalidateCacheFilter::handle(MiniFunction<Callback> fn, InvalidateCacheEvent* event) {
if (event->source == m_source) {
fn(event);
}
return ListenerResult::Propagate;
}
InvalidateCacheFilter::InvalidateCacheFilter(ModListSource* src) : m_source(src) {}
typename ModListSource::PagePromise ModListSource::loadPage(size_t page, bool update) {
if (!update && m_cachedPages.contains(page)) {
return PagePromise([this, page](auto resolve, auto) {
@ -127,6 +138,7 @@ void ModListSource::reset() {
void ModListSource::clearCache() {
m_cachedPages.clear();
m_cachedItemCount = std::nullopt;
InvalidateCacheEvent(this).post();
}
void ModListSource::search(std::string const& query) {
this->setSearchQuery(query);
@ -211,9 +223,8 @@ InstalledModsQuery const& InstalledModListSource::getQuery() const {
return m_query;
}
InstalledModsQuery& InstalledModListSource::getQueryMut() {
this->clearCache();
return m_query;
InvalidateQueryAfter<InstalledModsQuery> InstalledModListSource::getQueryMut() {
return InvalidateQueryAfter(m_query, this);
}
bool InstalledModListSource::isInstalledMods() const {
@ -313,9 +324,8 @@ void ServerModListSource::setSearchQuery(std::string const& query) {
server::ModsQuery const& ServerModListSource::getQuery() const {
return m_query;
}
server::ModsQuery& ServerModListSource::getQueryMut() {
this->clearCache();
return m_query;
InvalidateQueryAfter<server::ModsQuery> ServerModListSource::getQueryMut() {
return InvalidateQueryAfter(m_query, this);
}
bool ServerModListSource::isInstalledMods() const {

View file

@ -7,6 +7,26 @@
using namespace geode::prelude;
class ModListSource;
struct InvalidateCacheEvent : public Event {
ModListSource* source;
InvalidateCacheEvent(ModListSource* src);
};
class InvalidateCacheFilter : public EventFilter<InvalidateCacheEvent> {
protected:
ModListSource* m_source;
public:
using Callback = void(InvalidateCacheEvent*);
ListenerResult handle(MiniFunction<Callback> fn, InvalidateCacheEvent* event);
InvalidateCacheFilter() = default;
InvalidateCacheFilter(ModListSource* src);
};
struct InstalledModsQuery final {
std::optional<std::string> query;
bool onlyUpdates = false;
@ -69,6 +89,22 @@ public:
virtual bool wantsRestart() const = 0;
};
template <class T>
class InvalidateQueryAfter final {
private:
ModListSource* m_source;
T& m_ref;
public:
InvalidateQueryAfter(T& ref, ModListSource* source) : m_ref(ref), m_source(source) {}
~InvalidateQueryAfter() {
m_source->clearCache();
}
T* operator->() const {
return &m_ref;
}
};
class InstalledModListSource : public ModListSource {
protected:
bool m_onlyUpdates;
@ -85,8 +121,7 @@ public:
void setSearchQuery(std::string const& query) override;
InstalledModsQuery const& getQuery() const;
// Get mutable access to the current query; this clears the cache
InstalledModsQuery& getQueryMut();
InvalidateQueryAfter<InstalledModsQuery> getQueryMut();
bool isInstalledMods() const override;
bool wantsRestart() const override;
@ -115,8 +150,7 @@ public:
void setSearchQuery(std::string const& query) override;
server::ModsQuery const& getQuery() const;
// Get mutable access to the current query; this clears the cache
server::ModsQuery& getQueryMut();
InvalidateQueryAfter<server::ModsQuery> getQueryMut();
bool isInstalledMods() const override;
bool wantsRestart() const override;