aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui/pages
diff options
context:
space:
mode:
authorTheKodeToad <freezingma1l@outlook.com>2023-03-02 10:10:46 +0000
committerGitHub <noreply@github.com>2023-03-02 10:10:46 +0000
commit5c913149c84c121523a1ae403848d3e0926de244 (patch)
tree3789176d454bd988b7e572e5f411151efc2cb7e2 /launcher/ui/pages
parentcbe6eff2fa917401b913a96c551429caad852b3b (diff)
parent9265c319a96b3dd5681767c196a397fbbae9164a (diff)
downloadPrismLauncher-5c913149c84c121523a1ae403848d3e0926de244.tar.gz
PrismLauncher-5c913149c84c121523a1ae403848d3e0926de244.tar.bz2
PrismLauncher-5c913149c84c121523a1ae403848d3e0926de244.zip
Merge branch 'PrismLauncher:develop' into modrinth-token
Diffstat (limited to 'launcher/ui/pages')
-rw-r--r--launcher/ui/pages/instance/ResourcePackPage.cpp104
-rw-r--r--launcher/ui/pages/instance/ResourcePackPage.h24
-rw-r--r--launcher/ui/pages/instance/ShaderPackPage.cpp98
-rw-r--r--launcher/ui/pages/instance/ShaderPackPage.h25
-rw-r--r--launcher/ui/pages/instance/TexturePackPage.cpp106
-rw-r--r--launcher/ui/pages/instance/TexturePackPage.h25
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h2
-rw-r--r--launcher/ui/pages/modplatform/ResourcePackModel.cpp46
-rw-r--r--launcher/ui/pages/modplatform/ResourcePackModel.h43
-rw-r--r--launcher/ui/pages/modplatform/ResourcePackPage.cpp46
-rw-r--r--launcher/ui/pages/modplatform/ResourcePackPage.h52
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackModel.cpp46
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackModel.h43
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackPage.cpp54
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackPage.h54
-rw-r--r--launcher/ui/pages/modplatform/TexturePackModel.cpp84
-rw-r--r--launcher/ui/pages/modplatform/TexturePackModel.h27
-rw-r--r--launcher/ui/pages/modplatform/TexturePackPage.h50
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp82
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.h40
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp97
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourcePages.h56
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp66
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h57
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp57
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h72
26 files changed, 1397 insertions, 59 deletions
diff --git a/launcher/ui/pages/instance/ResourcePackPage.cpp b/launcher/ui/pages/instance/ResourcePackPage.cpp
new file mode 100644
index 00000000..24bfb38d
--- /dev/null
+++ b/launcher/ui/pages/instance/ResourcePackPage.cpp
@@ -0,0 +1,104 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
+/*
+ * Prism Launcher - 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 packs"));
+ ui->actionDownloadItem->setToolTip(tr("Download resource packs 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();
+ }
+}
diff --git a/launcher/ui/pages/instance/ResourcePackPage.h b/launcher/ui/pages/instance/ResourcePackPage.h
index db8af0c5..b04aa2e9 100644
--- a/launcher/ui/pages/instance/ResourcePackPage.h
+++ b/launcher/ui/pages/instance/ResourcePackPage.h
@@ -1,6 +1,8 @@
-// SPDX-License-Identifier: GPL-3.0-only
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
/*
- * PolyMC - Minecraft Launcher
+ * Prism Launcher - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* This program is free software: you can redistribute it and/or modify
@@ -44,12 +46,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 +60,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();
};
diff --git a/launcher/ui/pages/instance/ShaderPackPage.cpp b/launcher/ui/pages/instance/ShaderPackPage.cpp
new file mode 100644
index 00000000..2d0c10aa
--- /dev/null
+++ b/launcher/ui/pages/instance/ShaderPackPage.cpp
@@ -0,0 +1,98 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
+/*
+ * Prism Launcher - 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 "ShaderPackPage.h"
+#include "ui_ExternalResourcesPage.h"
+
+#include "ResourceDownloadTask.h"
+
+#include "minecraft/mod/ShaderPackFolderModel.h"
+
+#include "ui/dialogs/CustomMessageBox.h"
+#include "ui/dialogs/ProgressDialog.h"
+#include "ui/dialogs/ResourceDownloadDialog.h"
+
+
+ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget* parent)
+ : ExternalResourcesPage(instance, model, parent)
+{
+ ui->actionDownloadItem->setText(tr("Download shaders"));
+ ui->actionDownloadItem->setToolTip(tr("Download shaders from online platforms"));
+ ui->actionDownloadItem->setEnabled(true);
+ connect(ui->actionDownloadItem, &QAction::triggered, this, &ShaderPackPage::downloadShaders);
+ ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
+
+ ui->actionViewConfigs->setVisible(false);
+}
+
+void ShaderPackPage::downloadShaders()
+{
+ if (!m_controlsEnabled)
+ return;
+ if (m_instance->typeName() != "Minecraft")
+ return; // this is a null instance or a legacy instance
+
+ ResourceDownload::ShaderPackDownloadDialog mdownload(this, std::static_pointer_cast<ShaderPackFolderModel>(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();
+ }
+}
diff --git a/launcher/ui/pages/instance/ShaderPackPage.h b/launcher/ui/pages/instance/ShaderPackPage.h
index 7f7ff8c1..a779fd8c 100644
--- a/launcher/ui/pages/instance/ShaderPackPage.h
+++ b/launcher/ui/pages/instance/ShaderPackPage.h
@@ -1,6 +1,8 @@
-// SPDX-License-Identifier: GPL-3.0-only
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
/*
- * PolyMC - Minecraft Launcher
+ * Prism Launcher - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* This program is free software: you can redistribute it and/or modify
@@ -36,28 +38,21 @@
#pragma once
#include "ExternalResourcesPage.h"
-#include "ui_ExternalResourcesPage.h"
-
-#include "minecraft/mod/ShaderPackFolderModel.h"
class ShaderPackPage : public ExternalResourcesPage
{
Q_OBJECT
public:
- explicit ShaderPackPage(MinecraftInstance *instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget *parent = 0)
- : ExternalResourcesPage(instance, model, parent)
- {
- ui->actionViewConfigs->setVisible(false);
- }
- virtual ~ShaderPackPage() {}
+ explicit ShaderPackPage(MinecraftInstance *instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget *parent = nullptr);
+ ~ShaderPackPage() override = default;
QString displayName() const override { return tr("Shader packs"); }
QIcon icon() const override { return APPLICATION->getThemedIcon("shaderpacks"); }
QString id() const override { return "shaderpacks"; }
QString helpPage() const override { return "Resource-packs"; }
- virtual bool shouldDisplay() const override
- {
- return true;
- }
+ bool shouldDisplay() const override { return true; }
+
+ public slots:
+ void downloadShaders();
};
diff --git a/launcher/ui/pages/instance/TexturePackPage.cpp b/launcher/ui/pages/instance/TexturePackPage.cpp
new file mode 100644
index 00000000..427aba11
--- /dev/null
+++ b/launcher/ui/pages/instance/TexturePackPage.cpp
@@ -0,0 +1,106 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
+/*
+ * Prism Launcher - 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 "TexturePackPage.h"
+
+#include "ResourceDownloadTask.h"
+
+#include "minecraft/mod/TexturePack.h"
+
+#include "ui/dialogs/CustomMessageBox.h"
+#include "ui/dialogs/ProgressDialog.h"
+#include "ui/dialogs/ResourceDownloadDialog.h"
+
+TexturePackPage::TexturePackPage(MinecraftInstance* instance, std::shared_ptr<TexturePackFolderModel> model, QWidget* parent)
+ : ExternalResourcesPage(instance, model, parent)
+{
+ ui->actionDownloadItem->setText(tr("Download packs"));
+ ui->actionDownloadItem->setToolTip(tr("Download texture packs from online platforms"));
+ ui->actionDownloadItem->setEnabled(true);
+ connect(ui->actionDownloadItem, &QAction::triggered, this, &TexturePackPage::downloadTPs);
+ ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
+
+ ui->actionViewConfigs->setVisible(false);
+}
+
+bool TexturePackPage::onSelectionChanged(const QModelIndex& current, const QModelIndex& previous)
+{
+ auto sourceCurrent = m_filterModel->mapToSource(current);
+ int row = sourceCurrent.row();
+ auto& rp = static_cast<TexturePack&>(m_model->at(row));
+ ui->frame->updateWithTexturePack(rp);
+
+ return true;
+}
+
+void TexturePackPage::downloadTPs()
+{
+ if (!m_controlsEnabled)
+ return;
+ if (m_instance->typeName() != "Minecraft")
+ return; // this is a null instance or a legacy instance
+
+ ResourceDownload::TexturePackDownloadDialog mdownload(this, std::static_pointer_cast<TexturePackFolderModel>(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();
+ }
+}
diff --git a/launcher/ui/pages/instance/TexturePackPage.h b/launcher/ui/pages/instance/TexturePackPage.h
index 69b836ca..47a8fa60 100644
--- a/launcher/ui/pages/instance/TexturePackPage.h
+++ b/launcher/ui/pages/instance/TexturePackPage.h
@@ -1,6 +1,8 @@
-// SPDX-License-Identifier: GPL-3.0-only
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only AND Apache-2.0
/*
- * PolyMC - Minecraft Launcher
+ * Prism Launcher - Minecraft Launcher
* Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org>
*
* This program is free software: you can redistribute it and/or modify
@@ -39,18 +41,12 @@
#include "ui_ExternalResourcesPage.h"
#include "minecraft/mod/TexturePackFolderModel.h"
-#include "minecraft/mod/TexturePack.h"
class TexturePackPage : public ExternalResourcesPage
{
Q_OBJECT
public:
- explicit TexturePackPage(MinecraftInstance *instance, std::shared_ptr<TexturePackFolderModel> model, QWidget *parent = 0)
- : ExternalResourcesPage(instance, model, parent)
- {
- ui->actionViewConfigs->setVisible(false);
- }
- virtual ~TexturePackPage() {}
+ explicit TexturePackPage(MinecraftInstance *instance, std::shared_ptr<TexturePackFolderModel> model, QWidget* parent = nullptr);
QString displayName() const override { return tr("Texture packs"); }
QIcon icon() const override { return APPLICATION->getThemedIcon("resourcepacks"); }
@@ -63,13 +59,6 @@ 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<TexturePack&>(m_model->at(row));
- ui->frame->updateWithTexturePack(rp);
-
- return true;
- }
+ bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
+ void downloadTPs();
};
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
index 610b631c..46a02d6e 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.h
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -98,7 +98,7 @@ class ResourceModel : public QAbstractListModel {
/** Functions to load data into a pack.
*
- * Those are needed for the same reason as ddocumentToArray, and NEED to be re-implemented in the same way.
+ * Those are needed for the same reason as documentToArray, and NEED to be re-implemented in the same way.
*/
virtual void loadIndexedPack(ModPlatform::IndexedPack&, QJsonObject&);
diff --git a/launcher/ui/pages/modplatform/ResourcePackModel.cpp b/launcher/ui/pages/modplatform/ResourcePackModel.cpp
new file mode 100644
index 00000000..3df9a787
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ResourcePackModel.cpp
@@ -0,0 +1,46 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#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
diff --git a/launcher/ui/pages/modplatform/ResourcePackModel.h b/launcher/ui/pages/modplatform/ResourcePackModel.h
new file mode 100644
index 00000000..e2b4a195
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ResourcePackModel.h
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#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
diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.cpp b/launcher/ui/pages/modplatform/ResourcePackPage.cpp
new file mode 100644
index 00000000..52fb4802
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ResourcePackPage.cpp
@@ -0,0 +1,46 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "ResourcePackPage.h"
+#include "ui_ResourcePage.h"
+
+#include "ResourcePackModel.h"
+
+#include "ui/dialogs/ResourceDownloadDialog.h"
+
+#include <QRegularExpression>
+
+namespace ResourceDownload {
+
+ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* 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
diff --git a/launcher/ui/pages/modplatform/ResourcePackPage.h b/launcher/ui/pages/modplatform/ResourcePackPage.h
new file mode 100644
index 00000000..c01c89c4
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ResourcePackPage.h
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#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(ResourceDownloadDialog* dialog, BaseInstance& instance);
+
+ protected slots:
+ void triggerSearch() override;
+};
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ShaderPackModel.cpp b/launcher/ui/pages/modplatform/ShaderPackModel.cpp
new file mode 100644
index 00000000..2101b394
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ShaderPackModel.cpp
@@ -0,0 +1,46 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "ShaderPackModel.h"
+
+#include <QMessageBox>
+
+namespace ResourceDownload {
+
+ShaderPackResourceModel::ShaderPackResourceModel(BaseInstance const& base_inst, ResourceAPI* api)
+ : ResourceModel(api), m_base_instance(base_inst){};
+
+/******** Make data requests ********/
+
+ResourceAPI::SearchArgs ShaderPackResourceModel::createSearchArguments()
+{
+ auto sort = getCurrentSortingMethodByIndex();
+ return { ModPlatform::ResourceType::SHADER_PACK, m_next_search_offset, m_search_term, sort };
+}
+
+ResourceAPI::VersionSearchArgs ShaderPackResourceModel::createVersionsArguments(QModelIndex& entry)
+{
+ auto& pack = m_packs[entry.row()];
+ return { pack };
+}
+
+ResourceAPI::ProjectInfoArgs ShaderPackResourceModel::createInfoArguments(QModelIndex& entry)
+{
+ auto& pack = m_packs[entry.row()];
+ return { pack };
+}
+
+void ShaderPackResourceModel::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
diff --git a/launcher/ui/pages/modplatform/ShaderPackModel.h b/launcher/ui/pages/modplatform/ShaderPackModel.h
new file mode 100644
index 00000000..f3c695e9
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ShaderPackModel.h
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#pragma once
+
+#include <QAbstractListModel>
+
+#include "BaseInstance.h"
+
+#include "modplatform/ModIndex.h"
+
+#include "ui/pages/modplatform/ResourceModel.h"
+
+class Version;
+
+namespace ResourceDownload {
+
+class ShaderPackResourceModel : public ResourceModel {
+ Q_OBJECT
+
+ public:
+ ShaderPackResourceModel(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
diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp
new file mode 100644
index 00000000..251c07e7
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "ShaderPackPage.h"
+#include "ui_ResourcePage.h"
+
+#include "ShaderPackModel.h"
+
+#include "ui/dialogs/ResourceDownloadDialog.h"
+
+#include <QRegularExpression>
+
+namespace ResourceDownload {
+
+ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
+ : ResourcePage(dialog, instance)
+{
+ connect(m_ui->searchButton, &QPushButton::clicked, this, &ShaderPackResourcePage::triggerSearch);
+ connect(m_ui->packView, &QListView::doubleClicked, this, &ShaderPackResourcePage::onResourceSelected);
+}
+
+/******** Callbacks to events in the UI (set up in the derived classes) ********/
+
+void ShaderPackResourcePage::triggerSearch()
+{
+ m_ui->packView->clearSelection();
+ m_ui->packDescription->clear();
+ m_ui->versionSelectionBox->clear();
+
+ updateSelectionButton();
+
+ static_cast<ShaderPackResourceModel*>(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt());
+ m_fetch_progress.watch(m_model->activeSearchJob().get());
+}
+
+QMap<QString, QString> ShaderPackResourcePage::urlHandlers() const
+{
+ QMap<QString, QString> map;
+ map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/shaders\\/([^\\/]+)\\/?"), "modrinth");
+ map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/customization\\/([^\\/]+)\\/?"), "curseforge");
+ map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
+ return map;
+}
+
+void ShaderPackResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
+{
+ if (version.loaders.contains(QStringLiteral("canvas")))
+ version.custom_target_folder = QStringLiteral("resourcepacks");
+
+ m_parent_dialog->addResource(pack, version);
+}
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.h b/launcher/ui/pages/modplatform/ShaderPackPage.h
new file mode 100644
index 00000000..972419a8
--- /dev/null
+++ b/launcher/ui/pages/modplatform/ShaderPackPage.h
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#pragma once
+
+#include "ui/pages/modplatform/ResourcePage.h"
+#include "ui/pages/modplatform/ShaderPackModel.h"
+
+namespace Ui {
+class ResourcePage;
+}
+
+namespace ResourceDownload {
+
+class ShaderPackDownloadDialog;
+
+class ShaderPackResourcePage : public ResourcePage {
+ Q_OBJECT
+
+ public:
+ template <typename T>
+ static T* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
+ {
+ auto page = new T(dialog, instance);
+ auto model = static_cast<ShaderPackResourceModel*>(page->getModel());
+
+ connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList);
+ connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
+
+ return page;
+ }
+
+ ~ShaderPackResourcePage() override = default;
+
+ //: The plural version of 'shader pack'
+ [[nodiscard]] inline QString resourcesString() const override { return tr("shader packs"); }
+ //: The singular version of 'shader packs'
+ [[nodiscard]] inline QString resourceString() const override { return tr("shader pack"); }
+
+ [[nodiscard]] bool supportsFiltering() const override { return false; };
+
+ void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&) override;
+
+ [[nodiscard]] QMap<QString, QString> urlHandlers() const override;
+
+ protected:
+ ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
+
+ protected slots:
+ void triggerSearch() override;
+};
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/TexturePackModel.cpp b/launcher/ui/pages/modplatform/TexturePackModel.cpp
new file mode 100644
index 00000000..fa636951
--- /dev/null
+++ b/launcher/ui/pages/modplatform/TexturePackModel.cpp
@@ -0,0 +1,84 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "TexturePackModel.h"
+
+#include "Application.h"
+
+#include "meta/Index.h"
+#include "meta/Version.h"
+
+static std::list<Version> s_availableVersions = {};
+
+namespace ResourceDownload {
+TexturePackResourceModel::TexturePackResourceModel(BaseInstance const& inst, ResourceAPI* api)
+ : ResourcePackResourceModel(inst, api), m_version_list(APPLICATION->metadataIndex()->get("net.minecraft"))
+{
+ if (!m_version_list->isLoaded()) {
+ qDebug() << "Loading version list...";
+ auto task = m_version_list->getLoadTask();
+ if (!task->isRunning())
+ task->start();
+ }
+}
+
+void waitOnVersionListLoad(Meta::VersionList::Ptr version_list)
+{
+ QEventLoop load_version_list_loop;
+
+ QTimer time_limit_for_list_load;
+ time_limit_for_list_load.setTimerType(Qt::TimerType::CoarseTimer);
+ time_limit_for_list_load.setSingleShot(true);
+ time_limit_for_list_load.callOnTimeout(&load_version_list_loop, &QEventLoop::quit);
+ time_limit_for_list_load.start(4000);
+
+ auto task = version_list->getLoadTask();
+ QObject::connect(task.get(), &Task::finished, &load_version_list_loop, &QEventLoop::quit);
+
+ load_version_list_loop.exec();
+ if (time_limit_for_list_load.isActive())
+ time_limit_for_list_load.stop();
+}
+
+ResourceAPI::SearchArgs TexturePackResourceModel::createSearchArguments()
+{
+ if (s_availableVersions.empty())
+ waitOnVersionListLoad(m_version_list);
+
+ auto args = ResourcePackResourceModel::createSearchArguments();
+
+ if (!m_version_list->isLoaded()) {
+ qCritical() << "The version list could not be loaded. Falling back to showing all entries.";
+ return args;
+ }
+
+ if (s_availableVersions.empty()) {
+ for (auto&& version : m_version_list->versions()) {
+ // FIXME: This duplicates the logic in meta for the 'texturepacks' trait. However, we don't have access to that
+ // information from the index file alone. Also, downloading every version's file isn't a very good idea.
+ if (auto ver = version->toComparableVersion(); ver <= maximumTexturePackVersion())
+ s_availableVersions.push_back(ver);
+ }
+ }
+
+ Q_ASSERT(!s_availableVersions.empty());
+
+ args.versions = s_availableVersions;
+
+ return args;
+}
+
+ResourceAPI::VersionSearchArgs TexturePackResourceModel::createVersionsArguments(QModelIndex& entry)
+{
+ auto args = ResourcePackResourceModel::createVersionsArguments(entry);
+ if (!m_version_list->isLoaded()) {
+ qCritical() << "The version list could not be loaded. Falling back to showing all entries.";
+ return args;
+ }
+
+ args.mcVersions = s_availableVersions;
+ return args;
+}
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/TexturePackModel.h b/launcher/ui/pages/modplatform/TexturePackModel.h
new file mode 100644
index 00000000..bb2db5cf
--- /dev/null
+++ b/launcher/ui/pages/modplatform/TexturePackModel.h
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#pragma once
+
+#include "meta/VersionList.h"
+#include "ui/pages/modplatform/ResourcePackModel.h"
+
+namespace ResourceDownload {
+
+class TexturePackResourceModel : public ResourcePackResourceModel {
+ Q_OBJECT
+
+ public:
+ TexturePackResourceModel(BaseInstance const& inst, ResourceAPI* api);
+
+ [[nodiscard]] inline ::Version maximumTexturePackVersion() const { return { "1.6" }; }
+
+ ResourceAPI::SearchArgs createSearchArguments() override;
+ ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override;
+
+ protected:
+ Meta::VersionList::Ptr m_version_list;
+};
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/TexturePackPage.h b/launcher/ui/pages/modplatform/TexturePackPage.h
new file mode 100644
index 00000000..0bdce2f9
--- /dev/null
+++ b/launcher/ui/pages/modplatform/TexturePackPage.h
@@ -0,0 +1,50 @@
+// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
+//
+// SPDX-License-Identifier: GPL-3.0-only
+
+#pragma once
+
+#include "ui_ResourcePage.h"
+#include "ui/dialogs/ResourceDownloadDialog.h"
+#include "ui/pages/modplatform/ResourcePackPage.h"
+#include "ui/pages/modplatform/TexturePackModel.h"
+
+namespace Ui {
+class ResourcePage;
+}
+
+namespace ResourceDownload {
+
+class TexturePackDownloadDialog;
+
+class TexturePackResourcePage : public ResourcePackResourcePage {
+ Q_OBJECT
+
+ public:
+ template <typename T>
+ static T* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ {
+ auto page = new T(dialog, instance);
+ auto model = static_cast<TexturePackResourceModel*>(page->getModel());
+
+ connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList);
+ connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
+
+ return page;
+ }
+
+ //: The plural version of 'texture pack'
+ [[nodiscard]] inline QString resourcesString() const override { return tr("texture packs"); }
+ //: The singular version of 'texture packs'
+ [[nodiscard]] inline QString resourceString() const override { return tr("texture pack"); }
+
+ protected:
+ TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ : ResourcePackResourcePage(dialog, instance)
+ {
+ connect(m_ui->searchButton, &QPushButton::clicked, this, &TexturePackResourcePage::triggerSearch);
+ connect(m_ui->packView, &QListView::doubleClicked, this, &TexturePackResourcePage::onResourceSelected);
+ }
+};
+
+} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
index de1f2122..e3d0bc14 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
@@ -34,4 +34,86 @@ 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");
+}
+
+FlameTexturePackModel::FlameTexturePackModel(const BaseInstance& base) : TexturePackResourceModel(base, new FlameAPI) {}
+
+void FlameTexturePackModel::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 FlameTexturePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
+{
+ FlameMod::loadBody(m, obj);
+}
+
+void FlameTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
+{
+ FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+
+ QVector<ModPlatform::IndexedVersion> filtered_versions(m.versions.size());
+
+ // FIXME: Client-side version filtering. This won't take into account any user-selected filtering.
+ for (auto const& version : m.versions) {
+ auto const& mc_versions = version.mcVersion;
+
+ if (std::any_of(mc_versions.constBegin(), mc_versions.constEnd(),
+ [this](auto const& mc_version){ return Version(mc_version) <= maximumTexturePackVersion(); }))
+ filtered_versions.push_back(version);
+ }
+
+ m.versions = filtered_versions;
+}
+
+ResourceAPI::SearchArgs FlameTexturePackModel::createSearchArguments()
+{
+ auto args = TexturePackResourceModel::createSearchArguments();
+
+ auto profile = static_cast<const MinecraftInstance&>(m_base_instance).getPackProfile();
+ QString instance_minecraft_version = profile->getComponentVersion("net.minecraft");
+
+ // Bypass the texture pack logic, because we can't do multiple versions in the API query
+ args.versions = { instance_minecraft_version };
+
+ return args;
+}
+
+ResourceAPI::VersionSearchArgs FlameTexturePackModel::createVersionsArguments(QModelIndex& entry)
+{
+ auto args = TexturePackResourceModel::createVersionsArguments(entry);
+
+ // Bypass the texture pack logic, because we can't do multiple versions in the API query
+ args.mcVersions = {};
+
+ return args;
+}
+
+auto FlameTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
+{
+ return Json::ensureArray(obj.object(), "data");
+}
+
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
index 625a2a7d..0252ac40 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
@@ -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,43 @@ 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;
+};
+
+class FlameTexturePackModel : public TexturePackResourceModel {
+ Q_OBJECT
+
+ public:
+ FlameTexturePackModel(const BaseInstance&);
+ ~FlameTexturePackModel() 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;
+
+ ResourceAPI::SearchArgs createSearchArguments() override;
+ ResourceAPI::VersionSearchArgs createVersionsArguments(QModelIndex&) override;
+
+ auto documentToArray(QJsonDocument& obj) const -> QJsonArray override;
+};
+
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
index 485431a7..f93e27e6 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
@@ -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,89 @@ 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);
+}
+
+FlameTexturePackPage::FlameTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ : TexturePackResourcePage(dialog, instance)
+{
+ m_model = new FlameTexturePackModel(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, &FlameTexturePackPage::onSelectionChanged);
+ connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlameTexturePackPage::onVersionSelectionChanged);
+ connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameTexturePackPage::onResourceSelected);
+
+ m_ui->packDescription->setMetaEntry(metaEntryBase());
+}
+
+bool FlameTexturePackPage::optedOut(ModPlatform::IndexedVersion& ver) const
+{
+ return isOptedOut(ver);
+}
+
+void FlameTexturePackPage::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;
+ }
+ }
+
+ TexturePackResourcePage::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; }
+auto FlameTexturePackPage::shouldDisplay() const -> bool { return true; }
+
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h
index b21a53ad..103a6bb9 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.h
+++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.h
@@ -43,6 +43,8 @@
#include "modplatform/ResourceAPI.h"
#include "ui/pages/modplatform/ModPage.h"
+#include "ui/pages/modplatform/ResourcePackPage.h"
+#include "ui/pages/modplatform/TexturePackPage.h"
namespace ResourceDownload {
@@ -82,4 +84,58 @@ 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;
+};
+
+class FlameTexturePackPage : public TexturePackResourcePage {
+ Q_OBJECT
+
+ public:
+ static FlameTexturePackPage* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ {
+ return TexturePackResourcePage::create<FlameTexturePackPage>(dialog, instance);
+ }
+
+ FlameTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
+ ~FlameTexturePackPage() 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
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
index 73d55133..f5d1cc28 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
@@ -47,4 +47,70 @@ 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();
+}
+
+ModrinthTexturePackModel::ModrinthTexturePackModel(const BaseInstance& base) : TexturePackResourceModel(base, new ModrinthAPI){}
+
+void ModrinthTexturePackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
+{
+ ::Modrinth::loadIndexedPack(m, obj);
+}
+
+void ModrinthTexturePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
+{
+ ::Modrinth::loadExtraPackData(m, obj);
+}
+
+void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
+{
+ ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+}
+
+auto ModrinthTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
+{
+ return obj.object().value("hits").toArray();
+}
+
+ModrinthShaderPackModel::ModrinthShaderPackModel(const BaseInstance& base) : ShaderPackResourceModel(base, new ModrinthAPI){}
+
+void ModrinthShaderPackModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
+{
+ ::Modrinth::loadIndexedPack(m, obj);
+}
+
+void ModrinthShaderPackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj)
+{
+ ::Modrinth::loadExtraPackData(m, obj);
+}
+
+void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
+{
+ ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
+}
+
+auto ModrinthShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
+{
+ return obj.object().value("hits").toArray();
+}
+
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
index 56cab146..b351b19b 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
@@ -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,58 @@ 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;
+};
+
+class ModrinthTexturePackModel : public TexturePackResourceModel {
+ Q_OBJECT
+
+ public:
+ ModrinthTexturePackModel(const BaseInstance&);
+ ~ModrinthTexturePackModel() 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;
+};
+
+class ModrinthShaderPackModel : public ShaderPackResourceModel {
+ Q_OBJECT
+
+ public:
+ ModrinthShaderPackModel(const BaseInstance&);
+ ~ModrinthShaderPackModel() 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
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
index b82f800e..dd143700 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
@@ -82,9 +82,66 @@ 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());
+}
+
+ModrinthTexturePackPage::ModrinthTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ : TexturePackResourcePage(dialog, instance)
+{
+ m_model = new ModrinthTexturePackModel(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, &ModrinthTexturePackPage::onSelectionChanged);
+ connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthTexturePackPage::onVersionSelectionChanged);
+ connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthTexturePackPage::onResourceSelected);
+
+ m_ui->packDescription->setMetaEntry(metaEntryBase());
+}
+
+ModrinthShaderPackPage::ModrinthShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
+ : ShaderPackResourcePage(dialog, instance)
+{
+ m_model = new ModrinthShaderPackModel(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, &ModrinthShaderPackPage::onSelectionChanged);
+ connect(m_ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthShaderPackPage::onVersionSelectionChanged);
+ connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthShaderPackPage::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; }
+auto ModrinthTexturePackPage::shouldDisplay() const -> bool { return true; }
+auto ModrinthShaderPackPage::shouldDisplay() const -> bool { return true; }
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
index be38eff1..f4eb5ce0 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.h
@@ -42,6 +42,9 @@
#include "modplatform/ResourceAPI.h"
#include "ui/pages/modplatform/ModPage.h"
+#include "ui/pages/modplatform/ResourcePackPage.h"
+#include "ui/pages/modplatform/TexturePackPage.h"
+#include "ui/pages/modplatform/ShaderPackPage.h"
namespace ResourceDownload {
@@ -78,4 +81,73 @@ 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 ""; }
+};
+
+class ModrinthTexturePackPage : public TexturePackResourcePage {
+ Q_OBJECT
+
+ public:
+ static ModrinthTexturePackPage* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
+ {
+ return TexturePackResourcePage::create<ModrinthTexturePackPage>(dialog, instance);
+ }
+
+ ModrinthTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
+ ~ModrinthTexturePackPage() 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 ""; }
+};
+
+class ModrinthShaderPackPage : public ShaderPackResourcePage {
+ Q_OBJECT
+
+ public:
+ static ModrinthShaderPackPage* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
+ {
+ return ShaderPackResourcePage::create<ModrinthShaderPackPage>(dialog, instance);
+ }
+
+ ModrinthShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
+ ~ModrinthShaderPackPage() 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