From 44ff247f5f71ebeb95423ca37bf82d9913073522 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Aug 2023 20:03:02 +0300 Subject: feat:refactored modpack ux Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/flame/FlameModel.cpp | 55 +++++++++++++++++++--- launcher/ui/pages/modplatform/flame/FlameModel.h | 5 +- launcher/ui/pages/modplatform/flame/FlamePage.cpp | 10 ++++ launcher/ui/pages/modplatform/flame/FlamePage.h | 5 +- 4 files changed, 66 insertions(+), 9 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame') diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index ff21d010..e488f078 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -1,6 +1,8 @@ #include "FlameModel.h" #include #include "Application.h" +#include "modplatform/ResourceAPI.h" +#include "modplatform/flame/FlameAPI.h" #include "ui/widgets/ProjectItem.h" #include "net/ApiDownload.h" @@ -161,6 +163,25 @@ void ListModel::fetchMore(const QModelIndex& parent) void ListModel::performPaginatedSearch() { + if (currentSearchTerm.startsWith("#")) { + auto projectId = currentSearchTerm.removeFirst(); + if (!projectId.isEmpty()) { + ResourceAPI::ProjectInfoCallbacks callbacks; + + // Use defaults if no callbacks are set + if (!callbacks.on_fail) + callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); }; + + if (!callbacks.on_succeed) + callbacks.on_succeed = [this](auto& doc, auto pack) { searchRequestForOneSucceeded(doc); }; + static const FlameAPI api; + if (auto job = api.getProjectInfo({ projectId }, std::move(callbacks)); job) { + jobPtr = job; + jobPtr->start(); + } + return; + } + } auto netJob = makeShared("Flame::Search", APPLICATION->network()); auto searchUrl = QString( "https://api.curseforge.com/v1/mods/search?" @@ -189,23 +210,24 @@ void ListModel::searchWithTerm(const QString& term, int sort) } currentSearchTerm = term; currentSort = sort; - if (jobPtr) { + if (hasActiveSearchJob()) { jobPtr->abort(); searchState = ResetRequested; return; - } else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; } + beginResetModel(); + modpacks.clear(); + endResetModel(); + searchState = None; + nextSearchOffset = 0; performPaginatedSearch(); } void Flame::ListModel::searchRequestFinished() { - jobPtr.reset(); + if (hasActiveSearchJob()) + return; QJsonParseError parse_error; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); @@ -246,6 +268,25 @@ void Flame::ListModel::searchRequestFinished() endInsertRows(); } +void Flame::ListModel::searchRequestForOneSucceeded(QJsonDocument& doc) +{ + jobPtr.reset(); + + auto packObj = Json::ensureObject(doc.object(), "data"); + + Flame::IndexedPack pack; + try { + Flame::loadIndexedPack(pack, packObj); + } catch (const JSONValidationError& e) { + qWarning() << "Error while loading pack from CurseForge: " << e.cause(); + return; + } + + beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + 1); + modpacks.append({ pack }); + endInsertRows(); +} + void Flame::ListModel::searchRequestFailed(QString reason) { jobPtr.reset(); diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.h b/launcher/ui/pages/modplatform/flame/FlameModel.h index b3bc96b8..cd73fce3 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModel.h @@ -40,6 +40,8 @@ class ListModel : public QAbstractListModel { void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); void searchWithTerm(const QString& term, const int sort); + [[nodiscard]] bool hasActiveSearchJob() const { return jobPtr && jobPtr->isRunning(); } + private slots: void performPaginatedSearch(); @@ -48,6 +50,7 @@ class ListModel : public QAbstractListModel { void searchRequestFinished(); void searchRequestFailed(QString reason); + void searchRequestForOneSucceeded(QJsonDocument&); private: void requestLogo(QString file, QString url); @@ -63,7 +66,7 @@ class ListModel : public QAbstractListModel { int currentSort = 0; int nextSearchOffset = 0; enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None; - NetJob::Ptr jobPtr; + Task::Ptr jobPtr; std::shared_ptr response = std::make_shared(); }; diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 183e16f9..79fcc821 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -61,6 +61,11 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(paren ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); + m_search_timer.setTimerType(Qt::TimerType::CoarseTimer); + m_search_timer.setSingleShot(true); + + connect(&m_search_timer, &QTimer::timeout, this, &FlamePage::triggerSearch); + // index is used to set the sorting with the curseforge api ui->sortByBox->addItem(tr("Sort by Featured")); ui->sortByBox->addItem(tr("Sort by Popularity")); @@ -90,6 +95,11 @@ bool FlamePage::eventFilter(QObject* watched, QEvent* event) triggerSearch(); keyEvent->accept(); return true; + } else { + if (m_search_timer.isActive()) + m_search_timer.stop(); + + m_search_timer.start(350); } } return QWidget::eventFilter(watched, event); diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index ff5c7975..a45c9e40 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.h +++ b/launcher/ui/pages/modplatform/flame/FlamePage.h @@ -39,7 +39,7 @@ #include #include -#include "tasks/Task.h" +#include #include "ui/pages/BasePage.h" namespace Ui { @@ -86,4 +86,7 @@ class FlamePage : public QWidget, public BasePage { Flame::IndexedPack current; int m_selected_version_index = -1; + + // Used to do instant searching with a delay to cache quick changes + QTimer m_search_timer; }; -- cgit From 4c52b18bdd3112b5e92de61860fd8eff8ecdde9b Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Aug 2023 20:19:51 +0300 Subject: replaced removeFirst with mid Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/flame/FlameModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui/pages/modplatform/flame') diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index e488f078..e4388c24 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -164,7 +164,7 @@ void ListModel::fetchMore(const QModelIndex& parent) void ListModel::performPaginatedSearch() { if (currentSearchTerm.startsWith("#")) { - auto projectId = currentSearchTerm.removeFirst(); + auto projectId = currentSearchTerm.mid(1); if (!projectId.isEmpty()) { ResourceAPI::ProjectInfoCallbacks callbacks; -- cgit From 05094b7382aafc0a9dcda17c13d5294dbaa89c36 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Aug 2023 22:24:30 +0300 Subject: more fixes Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/flame/FlameModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'launcher/ui/pages/modplatform/flame') diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index e4388c24..17875a60 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -173,7 +173,7 @@ void ListModel::performPaginatedSearch() callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); }; if (!callbacks.on_succeed) - callbacks.on_succeed = [this](auto& doc, auto pack) { searchRequestForOneSucceeded(doc); }; + callbacks.on_succeed = [this](auto& doc, auto& pack) { searchRequestForOneSucceeded(doc); }; static const FlameAPI api; if (auto job = api.getProjectInfo({ projectId }, std::move(callbacks)); job) { jobPtr = job; -- cgit From 4036cecfc02142c403a45e18474ad7aab6fc8834 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 27 Aug 2023 15:04:42 +0300 Subject: Added progress widget to some modpack providers Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/flame/FlameModel.h | 1 + launcher/ui/pages/modplatform/flame/FlamePage.cpp | 10 +++++++++- launcher/ui/pages/modplatform/flame/FlamePage.h | 3 +++ launcher/ui/pages/modplatform/flame/FlamePage.ui | 4 ++-- 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame') diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.h b/launcher/ui/pages/modplatform/flame/FlameModel.h index cd73fce3..fd8496df 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModel.h @@ -41,6 +41,7 @@ class ListModel : public QAbstractListModel { void searchWithTerm(const QString& term, const int sort); [[nodiscard]] bool hasActiveSearchJob() const { return jobPtr && jobPtr->isRunning(); } + [[nodiscard]] Task::Ptr activeSearchJob() { return hasActiveSearchJob() ? jobPtr : nullptr; } private slots: void performPaginatedSearch(); diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index 79fcc821..50656f42 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -50,7 +50,8 @@ static FlameAPI api; -FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) +FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) + : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog), m_fetch_progress(this, false) { ui->setupUi(this); connect(ui->searchButton, &QPushButton::clicked, this, &FlamePage::triggerSearch); @@ -66,6 +67,12 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(paren connect(&m_search_timer, &QTimer::timeout, this, &FlamePage::triggerSearch); + m_fetch_progress.hideIfInactive(true); + m_fetch_progress.setFixedHeight(24); + m_fetch_progress.progressFormat(""); + + ui->gridLayout->addWidget(&m_fetch_progress, 2, 0, 1, ui->gridLayout->columnCount()); + // index is used to set the sorting with the curseforge api ui->sortByBox->addItem(tr("Sort by Featured")); ui->sortByBox->addItem(tr("Sort by Popularity")); @@ -124,6 +131,7 @@ void FlamePage::openedImpl() void FlamePage::triggerSearch() { listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex()); + m_fetch_progress.watch(listModel->activeSearchJob().get()); } void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelIndex prev) diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index a45c9e40..d35858fb 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.h +++ b/launcher/ui/pages/modplatform/flame/FlamePage.h @@ -41,6 +41,7 @@ #include #include #include "ui/pages/BasePage.h" +#include "ui/widgets/ProgressWidget.h" namespace Ui { class FlamePage; @@ -87,6 +88,8 @@ class FlamePage : public QWidget, public BasePage { int m_selected_version_index = -1; + ProgressWidget m_fetch_progress; + // Used to do instant searching with a delay to cache quick changes QTimer m_search_timer; }; diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui index 71d19513..f9e1fe67 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.ui +++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui @@ -47,7 +47,7 @@ - + @@ -77,7 +77,7 @@ - + -- cgit From 8c607ae7348206c29a8a8ce5e2db421138bd89ff Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 27 Aug 2023 20:02:12 +0300 Subject: removed extra if Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/flame/FlameModel.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame') diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 17875a60..8875a945 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -168,12 +168,8 @@ void ListModel::performPaginatedSearch() if (!projectId.isEmpty()) { ResourceAPI::ProjectInfoCallbacks callbacks; - // Use defaults if no callbacks are set - if (!callbacks.on_fail) - callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); }; - - if (!callbacks.on_succeed) - callbacks.on_succeed = [this](auto& doc, auto& pack) { searchRequestForOneSucceeded(doc); }; + callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); }; + callbacks.on_succeed = [this](auto& doc, auto& pack) { searchRequestForOneSucceeded(doc); }; static const FlameAPI api; if (auto job = api.getProjectInfo({ projectId }, std::move(callbacks)); job) { jobPtr = job; -- cgit