feat(RD): add resource pack downloader
Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
e89a10945c
commit
c3ea303a37
@ -610,6 +610,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
||||
m_settings->registerSetting("UpdateDialogGeometry", "");
|
||||
|
||||
m_settings->registerSetting("ModDownloadGeometry", "");
|
||||
m_settings->registerSetting("RPDownloadGeometry", "");
|
||||
|
||||
// HACK: This code feels so stupid is there a less stupid way of doing this?
|
||||
{
|
||||
|
@ -721,6 +721,7 @@ SET(LAUNCHER_SOURCES
|
||||
ui/pages/instance/ManagedPackPage.h
|
||||
ui/pages/instance/TexturePackPage.h
|
||||
ui/pages/instance/ResourcePackPage.h
|
||||
ui/pages/instance/ResourcePackPage.cpp
|
||||
ui/pages/instance/ShaderPackPage.h
|
||||
ui/pages/instance/ModFolderPage.cpp
|
||||
ui/pages/instance/ModFolderPage.h
|
||||
@ -773,6 +774,9 @@ SET(LAUNCHER_SOURCES
|
||||
ui/pages/modplatform/ModModel.cpp
|
||||
ui/pages/modplatform/ModModel.h
|
||||
|
||||
ui/pages/modplatform/ResourcePackPage.cpp
|
||||
ui/pages/modplatform/ResourcePackModel.cpp
|
||||
|
||||
ui/pages/modplatform/atlauncher/AtlFilterModel.cpp
|
||||
ui/pages/modplatform/atlauncher/AtlFilterModel.h
|
||||
ui/pages/modplatform/atlauncher/AtlListModel.cpp
|
||||
|
@ -27,6 +27,8 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
default:
|
||||
case ModPlatform::ResourceType::MOD:
|
||||
return 6;
|
||||
case ModPlatform::ResourceType::RESOURCE_PACK:
|
||||
return 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,8 @@ class ModrinthAPI : public NetworkResourceAPI {
|
||||
switch (type) {
|
||||
case ModPlatform::ResourceType::MOD:
|
||||
return "mod";
|
||||
case ModPlatform::ResourceType::RESOURCE_PACK:
|
||||
return "resourcepack";
|
||||
default:
|
||||
qWarning() << "Invalid resource type for Modrinth API!";
|
||||
break;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "minecraft/mod/ResourcePackFolderModel.h"
|
||||
|
||||
#include "ui/dialogs/ReviewMessageBox.h"
|
||||
|
||||
@ -229,4 +230,30 @@ QList<BasePage*> ModDownloadDialog::getPages()
|
||||
return pages;
|
||||
}
|
||||
|
||||
|
||||
ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<ResourcePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance)
|
||||
: ResourceDownloadDialog(parent, resource_packs), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty())
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toByteArray()));
|
||||
}
|
||||
|
||||
QList<BasePage*> ResourcePackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
pages.append(ModrinthResourcePackPage::create(this, *m_instance));
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame)
|
||||
pages.append(FlameResourcePackPage::create(this, *m_instance));
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -35,6 +35,7 @@ class QVBoxLayout;
|
||||
class QDialogButtonBox;
|
||||
class ResourceDownloadTask;
|
||||
class ResourceFolderModel;
|
||||
class ResourcePackFolderModel;
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
@ -108,4 +109,23 @@ class ModDownloadDialog final : public ResourceDownloadDialog {
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
class ResourcePackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ResourcePackDownloadDialog(QWidget* parent,
|
||||
const std::shared_ptr<ResourcePackFolderModel>& resource_packs,
|
||||
BaseInstance* instance);
|
||||
~ResourcePackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the resource pack download dialog title ("Download " + resourcesString())
|
||||
[[nodiscard]] QString resourcesString() const override { return tr("resource packs"); }
|
||||
[[nodiscard]] QString geometrySaveKey() const override { return "RPDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
102
launcher/ui/pages/instance/ResourcePackPage.cpp
Normal file
102
launcher/ui/pages/instance/ResourcePackPage.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* PolyMC - Minecraft Launcher
|
||||
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file incorporates work covered by the following copyright and
|
||||
* permission notice:
|
||||
*
|
||||
* Copyright 2013-2021 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ResourcePackPage.h"
|
||||
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
ResourcePackPage::ResourcePackPage(MinecraftInstance* instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget* parent)
|
||||
: ExternalResourcesPage(instance, model, parent)
|
||||
{
|
||||
ui->actionDownloadItem->setText(tr("Download RPs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download RPs from online platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ResourcePackPage::downloadRPs);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
|
||||
ui->actionViewConfigs->setVisible(false);
|
||||
}
|
||||
|
||||
bool ResourcePackPage::onSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
auto& rp = static_cast<ResourcePack&>(m_model->at(row));
|
||||
ui->frame->updateWithResourcePack(rp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourcePackPage::downloadRPs()
|
||||
{
|
||||
if (!m_controlsEnabled)
|
||||
return;
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
ResourceDownload::ResourcePackDownloadDialog mdownload(this, std::static_pointer_cast<ResourcePackFolderModel>(m_model), m_instance);
|
||||
if (mdownload.exec()) {
|
||||
auto tasks = new ConcurrentTask(this);
|
||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::aborted, [this, tasks]() {
|
||||
CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::succeeded, [this, tasks]() {
|
||||
QStringList warnings = tasks->warnings();
|
||||
if (warnings.count())
|
||||
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
||||
|
||||
tasks->deleteLater();
|
||||
});
|
||||
|
||||
for (auto& task : mdownload.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
|
||||
m_model->update();
|
||||
}
|
||||
}
|
@ -44,12 +44,7 @@ class ResourcePackPage : public ExternalResourcesPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResourcePackPage(MinecraftInstance *instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget *parent = 0)
|
||||
: ExternalResourcesPage(instance, model, parent)
|
||||
{
|
||||
ui->actionViewConfigs->setVisible(false);
|
||||
}
|
||||
virtual ~ResourcePackPage() {}
|
||||
explicit ResourcePackPage(MinecraftInstance *instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget *parent = 0);
|
||||
|
||||
QString displayName() const override { return tr("Resource packs"); }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); }
|
||||
@ -63,14 +58,7 @@ public:
|
||||
}
|
||||
|
||||
public slots:
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override
|
||||
{
|
||||
auto sourceCurrent = m_filterModel->mapToSource(current);
|
||||
int row = sourceCurrent.row();
|
||||
auto& rp = static_cast<ResourcePack&>(m_model->at(row));
|
||||
ui->frame->updateWithResourcePack(rp);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
void downloadRPs();
|
||||
};
|
||||
|
||||
|
42
launcher/ui/pages/modplatform/ResourcePackModel.cpp
Normal file
42
launcher/ui/pages/modplatform/ResourcePackModel.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "ResourcePackModel.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourcePackResourceModel::ResourcePackResourceModel(BaseInstance const& base_inst, ResourceAPI* api)
|
||||
: ResourceModel(api), m_base_instance(base_inst){};
|
||||
|
||||
/******** Make data requests ********/
|
||||
|
||||
ResourceAPI::SearchArgs ResourcePackResourceModel::createSearchArguments()
|
||||
{
|
||||
auto sort = getCurrentSortingMethodByIndex();
|
||||
return { ModPlatform::ResourceType::RESOURCE_PACK, m_next_search_offset, m_search_term, sort };
|
||||
}
|
||||
|
||||
ResourceAPI::VersionSearchArgs ResourcePackResourceModel::createVersionsArguments(QModelIndex& entry)
|
||||
{
|
||||
auto& pack = m_packs[entry.row()];
|
||||
return { pack };
|
||||
}
|
||||
|
||||
ResourceAPI::ProjectInfoArgs ResourcePackResourceModel::createInfoArguments(QModelIndex& entry)
|
||||
{
|
||||
auto& pack = m_packs[entry.row()];
|
||||
return { pack };
|
||||
}
|
||||
|
||||
void ResourcePackResourceModel::searchWithTerm(const QString& term, unsigned int sort)
|
||||
{
|
||||
if (m_search_term == term && m_search_term.isNull() == term.isNull() && m_current_sort_index == sort) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSearchTerm(term);
|
||||
m_current_sort_index = sort;
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
39
launcher/ui/pages/modplatform/ResourcePackModel.h
Normal file
39
launcher/ui/pages/modplatform/ResourcePackModel.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "BaseInstance.h"
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "ui/pages/modplatform/ResourceModel.h"
|
||||
|
||||
class Version;
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ResourcePackResourceModel : public ResourceModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ResourcePackResourceModel(BaseInstance const&, ResourceAPI*);
|
||||
|
||||
/* Ask the API for more information */
|
||||
void searchWithTerm(const QString& term, unsigned int sort);
|
||||
|
||||
void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&) override = 0;
|
||||
void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) override = 0;
|
||||
void loadIndexedPackVersions(ModPlatform::IndexedPack&, QJsonArray&) override = 0;
|
||||
|
||||
public slots:
|
||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||
ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override;
|
||||
ResourceAPI::ProjectInfoArgs createInfoArguments(QModelIndex&) override;
|
||||
|
||||
protected:
|
||||
const BaseInstance& m_base_instance;
|
||||
|
||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override = 0;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
42
launcher/ui/pages/modplatform/ResourcePackPage.cpp
Normal file
42
launcher/ui/pages/modplatform/ResourcePackPage.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "ResourcePackPage.h"
|
||||
#include "ui_ResourcePage.h"
|
||||
|
||||
#include "ResourcePackModel.h"
|
||||
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourcePackResourcePage::ResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ResourcePage(dialog, instance)
|
||||
{
|
||||
connect(m_ui->searchButton, &QPushButton::clicked, this, &ResourcePackResourcePage::triggerSearch);
|
||||
connect(m_ui->packView, &QListView::doubleClicked, this, &ResourcePackResourcePage::onResourceSelected);
|
||||
}
|
||||
|
||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||
|
||||
void ResourcePackResourcePage::triggerSearch()
|
||||
{
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
||||
updateSelectionButton();
|
||||
|
||||
static_cast<ResourcePackResourceModel*>(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt());
|
||||
m_fetch_progress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
QMap<QString, QString> ResourcePackResourcePage::urlHandlers() const
|
||||
{
|
||||
QMap<QString, QString> map;
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"), "curseforge");
|
||||
map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return map;
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
48
launcher/ui/pages/modplatform/ResourcePackPage.h
Normal file
48
launcher/ui/pages/modplatform/ResourcePackPage.h
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
#include "ui/pages/modplatform/ResourcePackModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ResourcePackDownloadDialog;
|
||||
|
||||
class ResourcePackResourcePage : public ResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto model = static_cast<ResourcePackResourceModel*>(page->getModel());
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
~ResourcePackResourcePage() override = default;
|
||||
|
||||
//: The plural version of 'resource pack'
|
||||
[[nodiscard]] inline QString resourcesString() const override { return tr("resource packs"); }
|
||||
//: The singular version of 'resource packs'
|
||||
[[nodiscard]] inline QString resourceString() const override { return tr("resource pack"); }
|
||||
|
||||
[[nodiscard]] bool supportsFiltering() const override { return false; };
|
||||
|
||||
[[nodiscard]] QMap<QString, QString> urlHandlers() const override;
|
||||
|
||||
protected:
|
||||
ResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
@ -34,4 +34,28 @@ auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||
return Json::ensureArray(obj.object(), "data");
|
||||
}
|
||||
|
||||
FlameResourcePackModel::FlameResourcePackModel(const BaseInstance& base) : ResourcePackResourceModel(base, new FlameAPI) {}
|
||||
|
||||
void FlameResourcePackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||
{
|
||||
FlameMod::loadIndexedPack(m, obj);
|
||||
}
|
||||
|
||||
// We already deal with the URLs when initializing the pack, due to the API response's structure
|
||||
void FlameResourcePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||
{
|
||||
FlameMod::loadBody(m, obj);
|
||||
}
|
||||
|
||||
void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
||||
{
|
||||
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
|
||||
}
|
||||
|
||||
auto FlameResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||
{
|
||||
return Json::ensureArray(obj.object(), "data");
|
||||
}
|
||||
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ModModel.h"
|
||||
#include "ui/pages/modplatform/ResourcePackModel.h"
|
||||
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
@ -27,4 +28,22 @@ class FlameModModel : public ModModel {
|
||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||
};
|
||||
|
||||
class FlameResourcePackModel : public ResourcePackResourceModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FlameResourcePackModel(const BaseInstance&);
|
||||
~FlameResourcePackModel() override = default;
|
||||
|
||||
private:
|
||||
[[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; }
|
||||
[[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); }
|
||||
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
||||
|
||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -44,6 +44,11 @@
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
static bool isOptedOut(ModPlatform::IndexedVersion const& ver)
|
||||
{
|
||||
return ver.downloadUrl.isEmpty();
|
||||
}
|
||||
|
||||
FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ModPage(dialog, instance)
|
||||
{
|
||||
@ -70,14 +75,9 @@ auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString min
|
||||
|
||||
bool FlameModPage::optedOut(ModPlatform::IndexedVersion& ver) const
|
||||
{
|
||||
return ver.downloadUrl.isEmpty();
|
||||
return isOptedOut(ver);
|
||||
}
|
||||
|
||||
// I don't know why, but doing this on the parent class makes it so that
|
||||
// other mod providers start loading before being selected, at least with
|
||||
// my Qt, so we need to implement this in every derived class...
|
||||
auto FlameModPage::shouldDisplay() const -> bool { return true; }
|
||||
|
||||
void FlameModPage::openUrl(const QUrl& url)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
@ -94,4 +94,49 @@ void FlameModPage::openUrl(const QUrl& url)
|
||||
ModPage::openUrl(url);
|
||||
}
|
||||
|
||||
FlameResourcePackPage::FlameResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ResourcePackResourcePage(dialog, instance)
|
||||
{
|
||||
m_model = new FlameResourcePackModel(instance);
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
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...
|
||||
connect(m_ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameResourcePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlameResourcePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameResourcePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
bool FlameResourcePackPage::optedOut(ModPlatform::IndexedVersion& ver) const
|
||||
{
|
||||
return isOptedOut(ver);
|
||||
}
|
||||
|
||||
void FlameResourcePackPage::openUrl(const QUrl& url)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
ResourcePackResourcePage::openUrl({QUrl::fromPercentEncoding(query.toUtf8())}); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ResourcePackResourcePage::openUrl(url);
|
||||
}
|
||||
|
||||
// I don't know why, but doing this on the parent class makes it so that
|
||||
// other mod providers start loading before being selected, at least with
|
||||
// my Qt, so we need to implement this in every derived class...
|
||||
auto FlameModPage::shouldDisplay() const -> bool { return true; }
|
||||
auto FlameResourcePackPage::shouldDisplay() const -> bool { return true; }
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
||||
#include "ui/pages/modplatform/ModPage.h"
|
||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
@ -82,4 +83,31 @@ class FlameModPage : public ModPage {
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
class FlameResourcePackPage : public ResourcePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameResourcePackPage* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ResourcePackResourcePage::create<FlameResourcePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameResourcePackPage() override = default;
|
||||
|
||||
[[nodiscard]] bool shouldDisplay() const override;
|
||||
|
||||
[[nodiscard]] inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
[[nodiscard]] inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
[[nodiscard]] inline auto id() const -> QString override { return Flame::id(); }
|
||||
[[nodiscard]] inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
[[nodiscard]] inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
[[nodiscard]] inline auto helpPage() const -> QString override { return ""; }
|
||||
|
||||
bool optedOut(ModPlatform::IndexedVersion& ver) const override;
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -47,4 +47,26 @@ auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||
return obj.object().value("hits").toArray();
|
||||
}
|
||||
|
||||
ModrinthResourcePackModel::ModrinthResourcePackModel(const BaseInstance& base) : ResourcePackResourceModel(base, new ModrinthAPI){}
|
||||
|
||||
void ModrinthResourcePackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||
{
|
||||
::Modrinth::loadIndexedPack(m, obj);
|
||||
}
|
||||
|
||||
void ModrinthResourcePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
|
||||
{
|
||||
::Modrinth::loadExtraPackData(m, obj);
|
||||
}
|
||||
|
||||
void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
|
||||
{
|
||||
::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
|
||||
}
|
||||
|
||||
auto ModrinthResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
|
||||
{
|
||||
return obj.object().value("hits").toArray();
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -21,12 +21,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ModModel.h"
|
||||
#include "ui/pages/modplatform/ResourcePackModel.h"
|
||||
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ModrinthModPage;
|
||||
|
||||
class ModrinthModModel : public ModModel {
|
||||
Q_OBJECT
|
||||
|
||||
@ -45,4 +44,22 @@ class ModrinthModModel : public ModModel {
|
||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||
};
|
||||
|
||||
class ModrinthResourcePackModel : public ResourcePackResourceModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModrinthResourcePackModel(const BaseInstance&);
|
||||
~ModrinthResourcePackModel() override = default;
|
||||
|
||||
private:
|
||||
[[nodiscard]] QString debugName() const override { return Modrinth::debugName() + " (Model)"; }
|
||||
[[nodiscard]] QString metaEntryBase() const override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
|
||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
|
||||
|
||||
auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -82,9 +82,28 @@ auto ModrinthModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString
|
||||
return ver.mcVersion.contains(mineVer) && loaderCompatible;
|
||||
}
|
||||
|
||||
ModrinthResourcePackPage::ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ResourcePackResourcePage(dialog, instance)
|
||||
{
|
||||
m_model = new ModrinthResourcePackModel(instance);
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
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...
|
||||
connect(m_ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthResourcePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthResourcePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthResourcePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
// I don't know why, but doing this on the parent class makes it so that
|
||||
// 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; }
|
||||
auto ModrinthResourcePackPage::shouldDisplay() const -> bool { return true; }
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
||||
#include "ui/pages/modplatform/ModPage.h"
|
||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
@ -78,4 +79,27 @@ class ModrinthModPage : public ModPage {
|
||||
auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ResourceAPI::ModLoaderTypes> loaders = {}) const -> bool override;
|
||||
};
|
||||
|
||||
class ModrinthResourcePackPage : public ResourcePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthResourcePackPage* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ResourcePackResourcePage::create<ModrinthResourcePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthResourcePackPage() override = default;
|
||||
|
||||
[[nodiscard]] bool shouldDisplay() const override;
|
||||
|
||||
[[nodiscard]] inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
[[nodiscard]] inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
[[nodiscard]] inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
[[nodiscard]] inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
[[nodiscard]] inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
[[nodiscard]] inline auto helpPage() const -> QString override { return ""; }
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
Loading…
Reference in New Issue
Block a user