aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui/pages/modplatform/modrinth
diff options
context:
space:
mode:
authorTrial97 <alexandru.tripon97@gmail.com>2023-09-28 22:50:12 +0300
committerTrial97 <alexandru.tripon97@gmail.com>2023-09-28 22:50:12 +0300
commit9acbf98f940204cd141203a6eccbc9a7351e5a78 (patch)
tree6ac8fe4b0e51ee58c67e02783fe97b00de707167 /launcher/ui/pages/modplatform/modrinth
parent254444470f020b086648ac496ebfffb7d3e9ce05 (diff)
parent59e565ef96b85be9a25fa5d4f1723ee87fd5e75e (diff)
downloadPrismLauncher-9acbf98f940204cd141203a6eccbc9a7351e5a78.tar.gz
PrismLauncher-9acbf98f940204cd141203a6eccbc9a7351e5a78.tar.bz2
PrismLauncher-9acbf98f940204cd141203a6eccbc9a7351e5a78.zip
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/acknowledge_release_type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
Diffstat (limited to 'launcher/ui/pages/modplatform/modrinth')
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp75
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthModel.h6
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp32
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.h7
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui10
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp12
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp16
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h2
8 files changed, 107 insertions, 53 deletions
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
index 761e265d..f691a185 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
@@ -38,10 +38,12 @@
#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"
+
#include <QMessageBox>
namespace Modrinth {
@@ -115,7 +117,7 @@ auto ModpackListModel::data(const QModelIndex& index, int role) const -> QVarian
return {};
}
-bool ModpackListModel::setData(const QModelIndex& index, const QVariant& value, int role)
+bool ModpackListModel::setData(const QModelIndex& index, const QVariant& value, [[maybe_unused]] int role)
{
int pos = index.row();
if (pos >= modpacks.size() || pos < 0 || !index.isValid())
@@ -128,7 +130,24 @@ 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.mid(1);
+ if (!projectId.isEmpty()) {
+ ResourceAPI::ProjectInfoCallbacks callbacks;
+
+ callbacks.on_fail = [this](QString reason) { searchRequestFailed(reason); };
+ 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?"
@@ -142,7 +161,7 @@ void ModpackListModel::performPaginatedSearch()
.arg(currentSearchTerm)
.arg(currentSort);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchAllUrl), m_all_response));
+ netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(searchAllUrl), m_all_response));
QObject::connect(netJob.get(), &NetJob::succeeded, this, [this] {
QJsonParseError parse_error_all{};
@@ -165,16 +184,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();
}
@@ -194,8 +214,6 @@ static auto sortFromIndex(int index) -> QString
case 4:
return "updated";
}
-
- return {};
}
void ModpackListModel::searchWithTerm(const QString& term, const int sort)
@@ -218,9 +236,7 @@ void ModpackListModel::searchWithTerm(const QString& term, const int sort)
void ModpackListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback)
{
if (m_logoMap.contains(logo)) {
- callback(APPLICATION->metacache()
- ->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0)))
- ->getFullPath());
+ callback(APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo))->getFullPath());
} else {
requestLogo(logo, logoUrl);
}
@@ -232,10 +248,9 @@ void ModpackListModel::requestLogo(QString logo, QString url)
return;
}
- MetaEntryPtr entry =
- APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0)));
+ MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo));
auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network());
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
+ job->addNetAction(Net::ApiDownload::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] {
@@ -310,9 +325,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."));
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
index 721c69f5..2a9d6226 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h
@@ -73,6 +73,9 @@ class ModpackListModel : public QAbstractListModel {
void refresh();
void searchWithTerm(const QString& term, const int sort);
+ [[nodiscard]] bool hasActiveSearchJob() const { return jobPtr && jobPtr->isRunning(); }
+ [[nodiscard]] Task::Ptr activeSearchJob() { return hasActiveSearchJob() ? jobPtr : nullptr; }
+
void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback);
inline auto canFetchMore(const QModelIndex& parent) const -> bool override
@@ -83,6 +86,7 @@ class ModpackListModel : public QAbstractListModel {
public slots:
void searchRequestFinished(QJsonDocument& doc_all);
void searchRequestFailed(QString reason);
+ void searchRequestForOneSucceeded(QJsonDocument&);
protected slots:
@@ -111,7 +115,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;
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
index b4d73b2f..8e2b9a90 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
@@ -46,11 +46,14 @@
#include "ui/widgets/ProjectItem.h"
+#include "net/ApiDownload.h"
+
#include <QComboBox>
#include <QKeyEvent>
#include <QPushButton>
-ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::ModrinthPage), dialog(dialog)
+ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent)
+ : QWidget(parent), ui(new Ui::ModrinthPage), dialog(dialog), m_fetch_progress(this, false)
{
ui->setupUi(this);
@@ -62,6 +65,17 @@ 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);
+
+ 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());
+
ui->sortByBox->addItem(tr("Sort by Relevance"));
ui->sortByBox->addItem(tr("Sort by Total Downloads"));
ui->sortByBox->addItem(tr("Sort by Follows"));
@@ -100,12 +114,17 @@ 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);
}
-void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev)
+void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelIndex prev)
{
ui->versionSelectionBox->clear();
@@ -127,7 +146,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev)
QString id = current.id;
- netJob->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
+ netJob->addNetAction(Net::ApiDownload::makeByteArray(QString("%1/project/%2").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
QObject::connect(netJob, &NetJob::succeeded, this, [this, response, id, curr] {
if (id != current.id) {
@@ -176,7 +195,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, QModelIndex prev)
QString id = current.id;
netJob->addNetAction(
- Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
+ Net::ApiDownload::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
QObject::connect(netJob, &NetJob::succeeded, this, [this, response, id, curr] {
if (id != current.id) {
@@ -308,11 +327,12 @@ void ModrinthPage::suggestCurrent()
void ModrinthPage::triggerSearch()
{
m_model->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex());
+ m_fetch_progress.watch(m_model->activeSearchJob().get());
}
-void ModrinthPage::onVersionSelectionChanged(QString data)
+void ModrinthPage::onVersionSelectionChanged(QString version)
{
- if (data.isNull() || data.isEmpty()) {
+ if (version.isNull() || version.isEmpty()) {
selectedVersion = "";
return;
}
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
index b7054c88..4240dcaf 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h
@@ -41,7 +41,9 @@
#include "ui/pages/BasePage.h"
#include "modplatform/modrinth/ModrinthPackManifest.h"
+#include "ui/widgets/ProgressWidget.h"
+#include <QTimer>
#include <QWidget>
namespace Ui {
@@ -88,4 +90,9 @@ class ModrinthPage : public QWidget, public BasePage {
Modrinth::Modpack current;
QString selectedVersion;
+
+ 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/modrinth/ModrinthPage.ui b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
index 6d8b2b67..78a25fea 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui
@@ -10,8 +10,8 @@
<height>600</height>
</rect>
</property>
- <layout class="QVBoxLayout">
- <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
@@ -29,7 +29,7 @@
</property>
</widget>
</item>
- <item>
+ <item row="1" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QLineEdit" name="searchEdit">
@@ -47,7 +47,7 @@
</item>
</layout>
</item>
- <item>
+ <item row="3" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QListView" name="packView">
@@ -77,7 +77,7 @@
</item>
</layout>
</item>
- <item>
+ <item row="4" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QComboBox" name="sortByBox"/>
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
index 00a0108a..85601829 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
@@ -39,13 +39,13 @@ void ModrinthModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObjec
void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+ ::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
}
auto ModrinthModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion
{
- return ::Modrinth::loadDependencyVersions(m, arr);
-};
+ return ::Modrinth::loadDependencyVersions(m, arr, &m_base_instance);
+}
auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
{
@@ -66,7 +66,7 @@ void ModrinthResourcePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, Q
void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+ ::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
}
auto ModrinthResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
@@ -88,7 +88,7 @@ void ModrinthTexturePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJ
void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+ ::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
}
auto ModrinthTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
@@ -110,7 +110,7 @@ void ModrinthShaderPackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJs
void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+ ::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
}
auto ModrinthShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
index 616c1a81..a4197b22 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
@@ -65,21 +65,9 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instan
auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver,
QString mineVer,
- std::optional<ResourceAPI::ModLoaderTypes> loaders) const -> bool
+ std::optional<ModPlatform::ModLoaderTypes> loaders) const -> bool
{
- auto loaderCompatible = !loaders.has_value();
-
- if (!loaderCompatible) {
- auto loaderStrings = ModrinthAPI::getModLoaderStrings(loaders.value());
- for (auto remoteLoader : ver.loaders) {
- if (loaderStrings.contains(remoteLoader)) {
- loaderCompatible = true;
- break;
- }
- }
- }
-
- return ver.mcVersion.contains(mineVer) && loaderCompatible;
+ return ver.mcVersion.contains(mineVer) && (!loaders.has_value() || !ver.loaders || loaders.value() & ver.loaders);
}
ModrinthResourcePackPage::ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
index 86ba1ccb..311bcfe3 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
@@ -93,7 +93,7 @@ class ModrinthModPage : public ModPage {
[[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; }
- auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ResourceAPI::ModLoaderTypes> loaders = {}) const
+ auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ModPlatform::ModLoaderTypes> loaders = {}) const
-> bool override;
};