aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/modplatform/ResourceAPI.h17
-rw-r--r--launcher/modplatform/flame/FlameAPI.cpp15
-rw-r--r--launcher/modplatform/flame/FlameAPI.h17
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.cpp12
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.h4
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp33
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h5
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp2
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h5
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.cpp11
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.h4
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp3
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.h4
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp8
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp3
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h4
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp7
17 files changed, 93 insertions, 61 deletions
diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h
index 78441c34..a2078b94 100644
--- a/launcher/modplatform/ResourceAPI.h
+++ b/launcher/modplatform/ResourceAPI.h
@@ -54,12 +54,23 @@ class ResourceAPI {
enum ModLoaderType { Forge = 1 << 0, Cauldron = 1 << 1, LiteLoader = 1 << 2, Fabric = 1 << 3, Quilt = 1 << 4 };
Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)
+ struct SortingMethod {
+ // The index of the sorting method. Used to allow for arbitrary ordering in the list of methods.
+ // Used by Flame in the API request.
+ unsigned int index;
+ // The real name of the sorting, as used in the respective API specification.
+ // Used by Modrinth in the API request.
+ QString name;
+ // The human-readable name of the sorting, used for display in the UI.
+ QString readable_name;
+ };
+
struct SearchArgs {
ModPlatform::ResourceType type{};
int offset = 0;
std::optional<QString> search;
- std::optional<QString> sorting;
+ std::optional<SortingMethod> sorting;
std::optional<ModLoaderTypes> loaders;
std::optional<std::list<Version> > versions;
};
@@ -95,6 +106,10 @@ class ResourceAPI {
std::function<void(QJsonDocument&, ModPlatform::IndexedPack&)> on_succeed;
};
+ public:
+ /** Gets a list of available sorting methods for this API. */
+ [[nodiscard]] virtual auto getSortingMethods() const -> QList<SortingMethod> = 0;
+
public slots:
[[nodiscard]] virtual NetJob::Ptr searchProjects(SearchArgs&&, SearchCallbacks&&) const
{
diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp
index 89249c41..32729a14 100644
--- a/launcher/modplatform/flame/FlameAPI.cpp
+++ b/launcher/modplatform/flame/FlameAPI.cpp
@@ -212,3 +212,18 @@ NetJob::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response)
return netJob;
}
+
+// https://docs.curseforge.com/?python#tocS_ModsSearchSortField
+static QList<ResourceAPI::SortingMethod> s_sorts = { { 1, "Featured", QObject::tr("Sort by Featured") },
+ { 2, "Popularity", QObject::tr("Sort by Popularity") },
+ { 3, "LastUpdated", QObject::tr("Sort by Last Updated") },
+ { 4, "Name", QObject::tr("Sort by Name") },
+ { 5, "Author", QObject::tr("Sort by Author") },
+ { 6, "TotalDownloads", QObject::tr("Sort by Downloads") },
+ { 7, "Category", QObject::tr("Sort by Category") },
+ { 8, "GameVersion", QObject::tr("Sort by Game Version") } };
+
+QList<ResourceAPI::SortingMethod> FlameAPI::getSortingMethods() const
+{
+ return s_sorts;
+}
diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h
index f3cc0bbf..2b288564 100644
--- a/launcher/modplatform/flame/FlameAPI.h
+++ b/launcher/modplatform/flame/FlameAPI.h
@@ -14,20 +14,9 @@ class FlameAPI : public NetworkResourceAPI {
NetJob::Ptr matchFingerprints(const QList<uint>& fingerprints, QByteArray* response);
NetJob::Ptr getFiles(const QStringList& fileIds, QByteArray* response) const;
- private:
- static int getSortFieldInt(QString const& sortString)
- {
- return sortString == "Featured" ? 1
- : sortString == "Popularity" ? 2
- : sortString == "LastUpdated" ? 3
- : sortString == "Name" ? 4
- : sortString == "Author" ? 5
- : sortString == "TotalDownloads" ? 6
- : sortString == "Category" ? 7
- : sortString == "GameVersion" ? 8
- : 1;
- }
+ [[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
+ private:
static int getClassId(ModPlatform::ResourceType type)
{
switch (type) {
@@ -62,7 +51,7 @@ class FlameAPI : public NetworkResourceAPI {
if (args.search.has_value())
get_arguments.append(QString("searchFilter=%1").arg(args.search.value()));
if (args.sorting.has_value())
- get_arguments.append(QString("sortField=%1").arg(getSortFieldInt(args.sorting.value())));
+ get_arguments.append(QString("sortField=%1").arg(args.sorting.value().index));
get_arguments.append("sortOrder=desc");
if (args.loaders.has_value())
get_arguments.append(QString("modLoaderType=%1").arg(getMappedModLoader(args.loaders.value())));
diff --git a/launcher/modplatform/modrinth/ModrinthAPI.cpp b/launcher/modplatform/modrinth/ModrinthAPI.cpp
index 8e64be09..8d7e3acf 100644
--- a/launcher/modplatform/modrinth/ModrinthAPI.cpp
+++ b/launcher/modplatform/modrinth/ModrinthAPI.cpp
@@ -112,3 +112,15 @@ NetJob::Ptr ModrinthAPI::getProjects(QStringList addonIds, QByteArray* response)
return netJob;
}
+
+// https://docs.modrinth.com/api-spec/#tag/projects/operation/searchProjects
+static QList<ResourceAPI::SortingMethod> s_sorts = { { 1, "relevance", QObject::tr("Sort by Relevance") },
+ { 2, "downloads", QObject::tr("Sort by Downloads") },
+ { 3, "follows", QObject::tr("Sort by Follows") },
+ { 4, "newest", QObject::tr("Sort by Last Updated") },
+ { 5, "updated", QObject::tr("Sort by Newest") } };
+
+QList<ResourceAPI::SortingMethod> ModrinthAPI::getSortingMethods() const
+{
+ return s_sorts;
+}
diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h
index ec38d9ee..949fc46e 100644
--- a/launcher/modplatform/modrinth/ModrinthAPI.h
+++ b/launcher/modplatform/modrinth/ModrinthAPI.h
@@ -49,6 +49,8 @@ class ModrinthAPI : public NetworkResourceAPI {
NetJob::Ptr getProjects(QStringList addonIds, QByteArray* response) const override;
public:
+ [[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
+
inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; };
static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList
@@ -116,7 +118,7 @@ class ModrinthAPI : public NetworkResourceAPI {
if (args.search.has_value())
get_arguments.append(QString("query=%1").arg(args.search.value()));
if (args.sorting.has_value())
- get_arguments.append(QString("index=%1").arg(args.sorting.value()));
+ get_arguments.append(QString("index=%1").arg(args.sorting.value().name));
get_arguments.append(QString("facets=%1").arg(createFacets(args)));
return BuildConfig.MODRINTH_PROD_URL + "/search?" + get_arguments.join('&');
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index c9dee449..5eeac5d5 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -20,12 +20,23 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
Q_ASSERT(profile);
Q_ASSERT(m_filter);
- std::optional<std::list<Version>> versions {};
- if (!m_filter->versions.empty())
- versions = m_filter->versions;
+ std::optional<std::list<Version>> versions{};
+ std::optional<ResourceAPI::SortingMethod> sort{};
+
+ { // Version filter
+ if (!m_filter->versions.empty())
+ versions = m_filter->versions;
+ }
- return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term,
- getSorts()[currentSort], profile->getModLoaders(), versions };
+ { // Sorting method
+ auto sorting_methods = getSortingMethods();
+ auto method = std::find_if(sorting_methods.begin(), sorting_methods.end(),
+ [this](auto const& e) { return m_current_sort_index == e.index; });
+ if (method != sorting_methods.end())
+ sort = *method;
+ }
+
+ return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, profile->getModLoaders(), versions };
}
ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
{
@@ -44,8 +55,8 @@ ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& en
Q_ASSERT(profile);
Q_ASSERT(m_filter);
- std::optional<std::list<Version>> versions {};
- if (!m_filter->versions.empty())
+ std::optional<std::list<Version>> versions{};
+ if (!m_filter->versions.empty())
versions = m_filter->versions;
return { pack, versions, profile->getModLoaders() };
@@ -73,14 +84,14 @@ ResourceAPI::ProjectInfoCallbacks ModModel::createInfoCallbacks(QModelIndex& ent
} };
}
-void ModModel::searchWithTerm(const QString& term, const int sort, const bool filter_changed)
+void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filter_changed)
{
- if (m_search_term == term && m_search_term.isNull() == term.isNull() && currentSort == sort && !filter_changed) {
+ if (m_search_term == term && m_search_term.isNull() == term.isNull() && m_current_sort_index == sort && !filter_changed) {
return;
}
setSearchTerm(term);
- currentSort = sort;
+ m_current_sort_index = sort;
refresh();
}
@@ -142,7 +153,7 @@ void ModModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack&
qWarning() << "Failed to cache mod info!";
return;
}
-
+
emit projectInfoUpdated();
}
}
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index 39d062f9..3aeba3ef 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -21,7 +21,7 @@ class ModModel : public ResourceModel {
ModModel(const BaseInstance&, ResourceAPI* api);
/* Ask the API for more information */
- void searchWithTerm(const QString& term, const int sort, const bool filter_changed);
+ void searchWithTerm(const QString& term, unsigned int sort, bool filter_changed);
virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
@@ -46,11 +46,8 @@ class ModModel : public ResourceModel {
protected:
virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0;
- virtual auto getSorts() const -> const char** = 0;
protected:
- int currentSort = 0;
-
std::shared_ptr<ModFilterWidget::Filter> m_filter = nullptr;
};
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 556bd642..04cbddcb 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -100,7 +100,7 @@ void ModPage::triggerSearch()
updateSelectionButton();
}
- static_cast<ModModel*>(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentIndex(), changed);
+ static_cast<ModModel*>(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt(), changed);
m_fetch_progress.watch(&m_model->activeJob());
}
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
index d0b9234b..facff91d 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.h
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -6,7 +6,9 @@
#include "QObjectPtr.h"
#include "BaseInstance.h"
+
#include "modplatform/ResourceAPI.h"
+
#include "tasks/ConcurrentTask.h"
class NetJob;
@@ -41,6 +43,8 @@ class ResourceModel : public QAbstractListModel {
inline void addActiveJob(Task::Ptr ptr) { m_current_job.addTask(ptr); if (!m_current_job.isRunning()) m_current_job.start(); }
inline Task const& activeJob() { return m_current_job; }
+ [[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); }
+
public slots:
void fetchMore(const QModelIndex& parent) override;
// NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12
@@ -83,6 +87,7 @@ class ResourceModel : public QAbstractListModel {
enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None;
int m_next_search_offset = 0;
QString m_search_term;
+ unsigned int m_current_sort_index = 0;
std::unique_ptr<ResourceAPI> m_api;
diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp
index 6e6868c5..43b77207 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.cpp
+++ b/launcher/ui/pages/modplatform/ResourcePage.cpp
@@ -103,6 +103,17 @@ void ResourcePage::setSearchTerm(QString term)
m_ui->searchEdit->setText(term);
}
+void ResourcePage::addSortings()
+{
+ Q_ASSERT(m_model);
+
+ auto sorts = m_model->getSortingMethods();
+ std::sort(sorts.begin(), sorts.end(), [](auto const& l, auto const& r) { return l.index < r.index; });
+
+ for (auto&& sorting : sorts)
+ m_ui->sortByBox->addItem(sorting.readable_name, QVariant(sorting.index));
+}
+
bool ResourcePage::setCurrentPack(ModPlatform::IndexedPack pack)
{
QVariant v;
diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h
index b95c5a40..547c4056 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.h
+++ b/launcher/ui/pages/modplatform/ResourcePage.h
@@ -52,14 +52,14 @@ class ResourcePage : public QWidget, public BasePage {
[[nodiscard]] bool setCurrentPack(ModPlatform::IndexedPack);
[[nodiscard]] auto getCurrentPack() const -> ModPlatform::IndexedPack;
-
[[nodiscard]] auto getDialog() const -> const ResourceDownloadDialog* { return m_parent_dialog; }
-
[[nodiscard]] auto getModel() const -> ResourceModel* { return m_model; }
protected:
ResourcePage(ResourceDownloadDialog* parent, BaseInstance&);
+ void addSortings();
+
public slots:
virtual void updateUi();
virtual void updateSelectionButton();
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
index d0f109de..a1cd1f26 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
@@ -7,9 +7,6 @@
namespace ResourceDownload {
-// NOLINTNEXTLINE(modernize-avoid-c-arrays)
-const char* FlameModModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" };
-
FlameModModel::FlameModModel(BaseInstance const& base) : ModModel(base, new FlameAPI) {}
void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
index 7b253dce..47fbbe1a 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
@@ -21,10 +21,6 @@ class FlameModModel : public ModModel {
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
-
- // NOLINTNEXTLINE(modernize-avoid-c-arrays)
- static const char* sorts[6];
- inline auto getSorts() const -> const char** override { return sorts; };
};
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
index 67737a76..e34be7fd 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
@@ -48,13 +48,7 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance)
m_model = new FlameModModel(instance);
m_ui->packView->setModel(m_model);
- // index is used to set the sorting with the flame api
- m_ui->sortByBox->addItem(tr("Sort by Featured"));
- m_ui->sortByBox->addItem(tr("Sort by Popularity"));
- m_ui->sortByBox->addItem(tr("Sort by Last Updated"));
- m_ui->sortByBox->addItem(tr("Sort by Name"));
- m_ui->sortByBox->addItem(tr("Sort by Author"));
- m_ui->sortByBox->addItem(tr("Sort by Downloads"));
+ addSortings();
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
// so it's best not to connect them in the parent's contructor...
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
index 895e23fd..06b72fd0 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
@@ -23,9 +23,6 @@
namespace ResourceDownload {
-// NOLINTNEXTLINE(modernize-avoid-c-arrays)
-const char* ModrinthModModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" };
-
ModrinthModModel::ModrinthModModel(BaseInstance const& base) : ModModel(base, new ModrinthAPI) {}
void ModrinthModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
index 798a70e6..2511f5e5 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
@@ -41,10 +41,6 @@ class ModrinthModModel : public ModModel {
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
-
- // NOLINTNEXTLINE(modernize-avoid-c-arrays)
- static const char* sorts[5];
- inline auto getSorts() const -> const char** override { return sorts; };
};
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
index 88621e05..45902d16 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
@@ -50,12 +50,7 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instan
m_model = new ModrinthModModel(instance);
m_ui->packView->setModel(m_model);
- // index is used to set the sorting with the modrinth api
- m_ui->sortByBox->addItem(tr("Sort by Relevance"));
- m_ui->sortByBox->addItem(tr("Sort by Downloads"));
- m_ui->sortByBox->addItem(tr("Sort by Follows"));
- m_ui->sortByBox->addItem(tr("Sort by Last Updated"));
- m_ui->sortByBox->addItem(tr("Sort by Newest"));
+ addSortings();
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
// so it's best not to connect them in the parent's constructor...