feat:refactored modpack ux

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2023-08-18 20:03:02 +03:00
parent e88418ab7f
commit 44ff247f5f
32 changed files with 679 additions and 163 deletions

View File

@ -38,8 +38,8 @@
#include "BuildConfig.h"
#include "Json.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "net/NetJob.h"
#include "ui/widgets/ProjectItem.h"
#include "net/ApiDownload.h"
@ -130,7 +130,28 @@ bool ModpackListModel::setData(const QModelIndex& index, const QVariant& value,
void ModpackListModel::performPaginatedSearch()
{
// TODO: Move to standalone API
if (hasActiveSearchJob())
return;
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 ModrinthAPI api;
if (auto job = api.getProjectInfo({ projectId }, std::move(callbacks)); job) {
jobPtr = job;
jobPtr->start();
}
return;
}
} // TODO: Move to standalone API
auto netJob = makeShared<NetJob>("Modrinth::SearchModpack", APPLICATION->network());
auto searchAllUrl = QString(BuildConfig.MODRINTH_PROD_URL +
"/search?"
@ -167,16 +188,17 @@ void ModpackListModel::performPaginatedSearch()
void ModpackListModel::refresh()
{
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();
}
@ -307,9 +329,29 @@ void ModpackListModel::searchRequestFinished(QJsonDocument& doc_all)
endInsertRows();
}
void ModpackListModel::searchRequestForOneSucceeded(QJsonDocument& doc)
{
jobPtr.reset();
auto packObj = doc.object();
Modrinth::Modpack pack;
try {
Modrinth::loadIndexedPack(pack, packObj);
pack.id = Json::ensureString(packObj, "id", pack.id);
} catch (const JSONValidationError& e) {
qWarning() << "Error while loading mod from " << m_parent->debugName() << ": " << e.cause();
return;
}
beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + 1);
modpacks.append({ pack });
endInsertRows();
}
void ModpackListModel::searchRequestFailed(QString reason)
{
auto failed_action = jobPtr->getFailedActions().at(0);
auto failed_action = dynamic_cast<NetJob*>(jobPtr.get())->getFailedActions().at(0);
if (!failed_action->m_reply) {
// Network error
QMessageBox::critical(nullptr, tr("Error"), tr("A network error occurred. Could not load modpacks."));

View File

@ -73,6 +73,8 @@ class ModpackListModel : public QAbstractListModel {
void refresh();
void searchWithTerm(const QString& term, const int sort);
[[nodiscard]] bool hasActiveSearchJob() const { return jobPtr && jobPtr->isRunning(); }
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
inline auto canFetchMore(const QModelIndex& parent) const -> bool override
@ -83,6 +85,7 @@ class ModpackListModel : public QAbstractListModel {
public slots:
void searchRequestFinished(QJsonDocument& doc_all);
void searchRequestFailed(QString reason);
void searchRequestForOneSucceeded(QJsonDocument&);
protected slots:
@ -111,7 +114,7 @@ class ModpackListModel : public QAbstractListModel {
int nextSearchOffset = 0;
enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None;
NetJob::Ptr jobPtr;
Task::Ptr jobPtr;
std::shared_ptr<QByteArray> m_all_response = std::make_shared<QByteArray>();
QByteArray m_specific_response;

View File

@ -64,6 +64,11 @@ ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget
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, &ModrinthPage::triggerSearch);
ui->sortByBox->addItem(tr("Sort by Relevance"));
ui->sortByBox->addItem(tr("Sort by Total Downloads"));
ui->sortByBox->addItem(tr("Sort by Follows"));
@ -102,6 +107,11 @@ bool ModrinthPage::eventFilter(QObject* watched, QEvent* event)
this->triggerSearch();
keyEvent->accept();
return true;
} else {
if (m_search_timer.isActive())
m_search_timer.stop();
m_search_timer.start(350);
}
}
return QObject::eventFilter(watched, event);

View File

@ -42,6 +42,7 @@
#include "modplatform/modrinth/ModrinthPackManifest.h"
#include <QTimer>
#include <QWidget>
namespace Ui {
@ -88,4 +89,7 @@ class ModrinthPage : public QWidget, public BasePage {
Modrinth::Modpack current;
QString selectedVersion;
// Used to do instant searching with a delay to cache quick changes
QTimer m_search_timer;
};