refactor: generalize mod models and APIs to resources

Firstly, this abstract away behavior in the mod download models that can
also be applied to other types of resources into a superclass, allowing
other resource types to be implemented without so much code duplication.

For that, this also generalizes the APIs used (currently, ModrinthAPI
and FlameAPI) to be able to make requests to other types of resources.

It also does a general cleanup of both of those. In particular, this
makes use of std::optional instead of invalid values for errors and,
well, optional values :p

This is a squash of some commits that were becoming too interlaced
together to be cleanly separated.

Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
flow
2022-11-25 09:23:46 -03:00
parent b937d33436
commit 6a18079953
68 changed files with 1965 additions and 1520 deletions

View File

@ -16,8 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ModrinthModModel.h"
#include "ModrinthResourceModels.h"
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "modplatform/modrinth/ModrinthPackIndex.h"
namespace Modrinth {
@ -37,7 +40,7 @@ void ListModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance);
Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_associated_page->m_base_instance);
}
auto ListModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
@ -46,3 +49,5 @@ auto ListModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
}
} // namespace Modrinth

View File

@ -18,7 +18,11 @@
#pragma once
#include "ModrinthModPage.h"
#include "ui/pages/modplatform/ModModel.h"
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
#include "modplatform/modrinth/ModrinthAPI.h"
namespace Modrinth {
@ -26,7 +30,7 @@ class ListModel : public ModPlatform::ListModel {
Q_OBJECT
public:
ListModel(ModrinthModPage* parent) : ModPlatform::ListModel(parent){};
ListModel(ModrinthModPage* parent) : ModPlatform::ListModel(parent, new ModrinthAPI){};
~ListModel() override = default;
private:
@ -42,3 +46,4 @@ class ListModel : public ModPlatform::ListModel {
};
} // namespace Modrinth

View File

@ -33,48 +33,52 @@
* limitations under the License.
*/
#include "ModrinthModPage.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "ui_ModPage.h"
#include "ModrinthResourcePages.h"
#include "ui_ResourcePage.h"
#include "ModrinthModModel.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "ModrinthResourceModels.h"
#include "ui/dialogs/ModDownloadDialog.h"
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instance)
: ModPage(dialog, instance, new ModrinthAPI())
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance)
: ModPage(dialog, instance)
{
listModel = new Modrinth::ListModel(this);
ui->packView->setModel(listModel);
m_model = new Modrinth::ListModel(this);
m_ui->packView->setModel(m_model);
// index is used to set the sorting with the modrinth api
ui->sortByBox->addItem(tr("Sort by Relevance"));
ui->sortByBox->addItem(tr("Sort by Downloads"));
ui->sortByBox->addItem(tr("Sort by Follows"));
ui->sortByBox->addItem(tr("Sort by Last Updated"));
ui->sortByBox->addItem(tr("Sort by Newest"));
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"));
// 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...
connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthModPage::onSelectionChanged);
connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthModPage::onVersionSelectionChanged);
connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthModPage::onModSelected);
connect(m_ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthModPage::onSelectionChanged);
connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthModPage::onVersionSelectionChanged);
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthModPage::onResourceSelected);
ui->packDescription->setMetaEntry(metaEntryBase());
m_ui->packDescription->setMetaEntry(metaEntryBase());
}
auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders) const -> bool
auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ResourceAPI::ModLoaderTypes> loaders) const -> bool
{
auto loaderStrings = ModrinthAPI::getModLoaderStrings(loaders);
auto loaderCompatible = !loaders.has_value();
auto loaderCompatible = false;
for (auto remoteLoader : ver.loaders)
{
if (loaderStrings.contains(remoteLoader)) {
loaderCompatible = true;
break;
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;
}
@ -82,3 +86,4 @@ auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString
// other mod providers start loading before being selected, at least with
// my Qt, so we need to implement this in every derived class...
auto ModrinthModPage::shouldDisplay() const -> bool { return true; }

View File

@ -35,32 +35,38 @@
#pragma once
#include "modplatform/ModAPI.h"
#include "Application.h"
#include "modplatform/ResourceAPI.h"
#include "ui/pages/modplatform/ModPage.h"
#include "modplatform/modrinth/ModrinthAPI.h"
static inline QString displayName() { return "Modrinth"; }
static inline QIcon icon() { return APPLICATION->getThemedIcon("modrinth"); }
static inline QString id() { return "modrinth"; }
static inline QString debugName() { return "Modrinth"; }
static inline QString metaEntryBase() { return "ModrinthPacks"; };
class ModrinthModPage : public ModPage {
Q_OBJECT
public:
static ModrinthModPage* create(ModDownloadDialog* dialog, BaseInstance* instance)
static ModrinthModPage* create(ModDownloadDialog* dialog, BaseInstance& instance)
{
return ModPage::create<ModrinthModPage>(dialog, instance);
}
ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instance);
ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance);
~ModrinthModPage() override = default;
inline auto displayName() const -> QString override { return "Modrinth"; }
inline auto icon() const -> QIcon override { return APPLICATION->getThemedIcon("modrinth"); }
inline auto id() const -> QString override { return "modrinth"; }
[[nodiscard]] bool shouldDisplay() const override;
[[nodiscard]] inline auto displayName() const -> QString override { return ::displayName(); } \
[[nodiscard]] inline auto icon() const -> QIcon override { return ::icon(); } \
[[nodiscard]] inline auto id() const -> QString override { return ::id(); } \
[[nodiscard]] inline auto debugName() const -> QString override { return ::debugName(); } \
[[nodiscard]] inline auto metaEntryBase() const -> QString override { return ::metaEntryBase(); }
inline auto helpPage() const -> QString override { return "Mod-platform"; }
inline auto debugName() const -> QString override { return "Modrinth"; }
inline auto metaEntryBase() const -> QString override { return "ModrinthPacks"; };
auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, ModAPI::ModLoaderTypes loaders = ModAPI::Unspecified) const -> bool override;
auto shouldDisplay() const -> bool override;
auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ResourceAPI::ModLoaderTypes> loaders = {}) const -> bool override;
};