From 02b4468bcddcdab6c269282564a0968c6394a34f Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 13 Oct 2022 19:52:47 -0300 Subject: feat(ui): add ManagedPackPage ui Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.ui | 173 ++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 launcher/ui/pages/instance/ManagedPackPage.ui diff --git a/launcher/ui/pages/instance/ManagedPackPage.ui b/launcher/ui/pages/instance/ManagedPackPage.ui new file mode 100644 index 00000000..3f019606 --- /dev/null +++ b/launcher/ui/pages/instance/ManagedPackPage.ui @@ -0,0 +1,173 @@ + + + ManagedPackPage + + + + 0 + 0 + 731 + 538 + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + 0 + 0 + + + + Pack information + + + + + + + + Pack name: + + + + + + + placeholder + + + + + + + + + + + Current version: + + + + + + + IBeamCursor + + + placeholder + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + + Provider information: + + + + + + + IBeamCursor + + + placeholder + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + Update to version: + + + + + + + + + + + 0 + 0 + + + + Update pack + + + + + + + + + + 0 + 0 + + + + Changelog + + + + + + + + + + + + + + + -- cgit From e5c42f68c2429a924b22dbcfb0df5a497690b805 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 13 Oct 2022 19:55:21 -0300 Subject: feat: add basic ManagedPackPage classes The idea is to have a base class that defines common behavior, and subclasses for each modpack provider, adding specific behavior. Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.cpp | 129 +++++++++++++++++++++++++ launcher/ui/pages/instance/ManagedPackPage.h | 98 +++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 launcher/ui/pages/instance/ManagedPackPage.cpp create mode 100644 launcher/ui/pages/instance/ManagedPackPage.h diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp new file mode 100644 index 00000000..725f8ce5 --- /dev/null +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -0,0 +1,129 @@ +#include "ManagedPackPage.h" +#include "ui_ManagedPackPage.h" + +#include +#include + +#include "Application.h" + +/** This is just to override the combo box popup behavior so that the combo box doesn't take the whole screen. + * ... thanks Qt. + */ +class NoBigComboBoxStyle : public QProxyStyle { + Q_OBJECT + + public: + NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {} + + // clang-format off + int styleHint(QStyle::StyleHint hint, const QStyleOption* option = nullptr, const QWidget* widget = nullptr, QStyleHintReturn* returnData = nullptr) const override + { + if (hint == QStyle::SH_ComboBox_Popup) + return false; + + return QProxyStyle::styleHint(hint, option, widget, returnData); + } + // clang-format on +}; + +ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent) +{ + if (type == "modrinth") + return new ModrinthManagedPackPage(inst, parent); + if (type == "flame") + return new FlameManagedPackPage(inst, parent); + + return new GenericManagedPackPage(inst, parent); +} + +ManagedPackPage::ManagedPackPage(BaseInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::ManagedPackPage), m_inst(inst) +{ + Q_ASSERT(inst); + + ui->setupUi(this); + + ui->versionsComboBox->setStyle(new NoBigComboBoxStyle(ui->versionsComboBox->style())); +} + +ManagedPackPage::~ManagedPackPage() +{ + delete ui; +} + +void ManagedPackPage::openedImpl() +{ + ui->packName->setText(m_inst->getManagedPackName()); + ui->packVersion->setText(m_inst->getManagedPackVersionName()); + ui->packOrigin->setText(tr("Website: %1 | Pack ID: %2 | Version ID: %3") + .arg(displayName(), m_inst->getManagedPackID(), m_inst->getManagedPackVersionID())); + + parseManagedPack(); +} + +QString ManagedPackPage::displayName() const +{ + auto type = m_inst->getManagedPackType(); + if (type.isEmpty()) + return {}; + return type.replace(0, 1, type[0].toUpper()); +} + +QIcon ManagedPackPage::icon() const +{ + return APPLICATION->getThemedIcon(m_inst->getManagedPackType()); +} + +QString ManagedPackPage::helpPage() const +{ + return {}; +} + +void ManagedPackPage::retranslate() +{ + ui->retranslateUi(this); +} + +bool ManagedPackPage::shouldDisplay() const +{ + return m_inst->isManagedPack(); +} + +ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, QWidget* parent) : ManagedPackPage(inst, parent) +{ + Q_ASSERT(inst->isManagedPack()); + connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); +} + +void ModrinthManagedPackPage::parseManagedPack() +{ +} + +QString ModrinthManagedPackPage::url() const +{ + return {}; +} + +void ModrinthManagedPackPage::suggestVersion() +{ +} + +FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, QWidget* parent) : ManagedPackPage(inst, parent) +{ + Q_ASSERT(inst->isManagedPack()); + connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); +} + +void FlameManagedPackPage::parseManagedPack() +{ +} + +QString FlameManagedPackPage::url() const +{ + return {}; +} + +void FlameManagedPackPage::suggestVersion() +{ +} + +#include "ManagedPackPage.moc" diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h new file mode 100644 index 00000000..be49383c --- /dev/null +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -0,0 +1,98 @@ +#pragma once + +#include "BaseInstance.h" + +#include "modplatform/modrinth/ModrinthAPI.h" +#include "modplatform/modrinth/ModrinthPackManifest.h" + +#include "ui/pages/BasePage.h" + +#include + +namespace Ui { +class ManagedPackPage; +} + +class ManagedPackPage : public QWidget, public BasePage { + Q_OBJECT + + public: + inline static ManagedPackPage* createPage(BaseInstance* inst, QWidget* parent = nullptr) + { + return ManagedPackPage::createPage(inst, inst->getManagedPackType(), parent); + } + + static ManagedPackPage* createPage(BaseInstance* inst, QString type, QWidget* parent = nullptr); + ~ManagedPackPage() override; + + [[nodiscard]] QString displayName() const override; + [[nodiscard]] QIcon icon() const override; + [[nodiscard]] QString helpPage() const override; + [[nodiscard]] QString id() const override { return "managed_pack"; } + [[nodiscard]] bool shouldDisplay() const override; + + void openedImpl() override; + + bool apply() override { return true; } + void retranslate() override; + + /** Gets the necessary information about the managed pack, such as + * available versions*/ + virtual void parseManagedPack() {}; + + /** URL of the managed pack. + * Not the version-specific one. + */ + [[nodiscard]] virtual QString url() const { return {}; }; + + public slots: + /** Gets the current version selection and update the changelog. + */ + virtual void suggestVersion() {}; + + protected: + ManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + + protected: + Ui::ManagedPackPage* ui; + BaseInstance* m_inst; + + bool m_loaded = false; +}; + +/** Simple page for when we aren't a managed pack. */ +class GenericManagedPackPage final : public ManagedPackPage { + Q_OBJECT + + public: + GenericManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr) : ManagedPackPage(inst, parent) {} + ~GenericManagedPackPage() override = default; +}; + +class ModrinthManagedPackPage final : public ManagedPackPage { + Q_OBJECT + + public: + ModrinthManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + ~ModrinthManagedPackPage() override = default; + + void parseManagedPack() override; + [[nodiscard]] QString url() const override; + + public slots: + void suggestVersion() override; +}; + +class FlameManagedPackPage final : public ManagedPackPage { + Q_OBJECT + + public: + FlameManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + ~FlameManagedPackPage() override = default; + + void parseManagedPack() override; + [[nodiscard]] QString url() const override; + + public slots: + void suggestVersion() override; +}; -- cgit From cba2608c1c196c341275b32becc4a7c713e92bbf Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 13 Oct 2022 19:57:23 -0300 Subject: feat: add logic for the modrinth instance modpack page Signed-off-by: flow --- .../modplatform/modrinth/ModrinthPackManifest.cpp | 1 + .../modplatform/modrinth/ModrinthPackManifest.h | 1 + launcher/ui/pages/instance/ManagedPackPage.cpp | 50 ++++++++++++++++++++++ launcher/ui/pages/instance/ManagedPackPage.h | 4 ++ 4 files changed, 56 insertions(+) diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 96f54067..4dca786f 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -128,6 +128,7 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion file.name = Json::requireString(obj, "name"); file.version = Json::requireString(obj, "version_number"); + file.changelog = Json::ensureString(obj, "changelog"); file.id = Json::requireString(obj, "id"); file.project_id = Json::requireString(obj, "project_id"); diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index 035dc62e..2973dfba 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -80,6 +80,7 @@ struct ModpackExtra { struct ModpackVersion { QString name; QString version; + QString changelog; QString id; QString project_id; diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 725f8ce5..ead33136 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -5,6 +5,10 @@ #include #include "Application.h" +#include "BuildConfig.h" +#include "Json.h" + +#include "modplatform/modrinth/ModrinthPackManifest.h" /** This is just to override the combo box popup behavior so that the combo box doesn't take the whole screen. * ... thanks Qt. @@ -96,6 +100,48 @@ ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, QWidget* pa void ModrinthManagedPackPage::parseManagedPack() { + qDebug() << "Parsing Modrinth pack"; + + auto netJob = new NetJob(QString("Modrinth::PackVersions(%1)").arg(m_inst->getManagedPackName()), APPLICATION->network()); + auto response = new QByteArray(); + + QString id = m_inst->getManagedPackID(); + + netJob->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response)); + + QObject::connect(netJob, &NetJob::succeeded, this, [this, response, id] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + try { + Modrinth::loadIndexedVersions(m_pack, doc); + } catch (const JSONValidationError& e) { + qDebug() << *response; + qWarning() << "Error while reading modrinth modpack version: " << e.cause(); + } + + for (auto version : m_pack.versions) { + if (!version.name.contains(version.version)) + ui->versionsComboBox->addItem(QString("%1 — %2").arg(version.name, version.version), QVariant(version.id)); + else + ui->versionsComboBox->addItem(version.name, QVariant(version.id)); + } + + suggestVersion(); + + m_loaded = true; + }); + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { + netJob->deleteLater(); + delete response; + }); + netJob->start(); } QString ModrinthManagedPackPage::url() const @@ -105,6 +151,10 @@ QString ModrinthManagedPackPage::url() const void ModrinthManagedPackPage::suggestVersion() { + auto index = ui->versionsComboBox->currentIndex(); + auto version = m_pack.versions.at(index); + + ui->changelogTextBrowser->setText(version.changelog); } FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, QWidget* parent) : ManagedPackPage(inst, parent) diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h index be49383c..1a756d33 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.h +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -81,6 +81,10 @@ class ModrinthManagedPackPage final : public ManagedPackPage { public slots: void suggestVersion() override; + + private: + Modrinth::Modpack m_pack; + ModrinthAPI m_api; }; class FlameManagedPackPage final : public ManagedPackPage { -- cgit From 1c567232e3a241cb7be767756c88350ec62335a1 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 13 Oct 2022 20:32:40 -0300 Subject: feat: add (current) indicator to the currently installed version in MR Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index ead33136..7c51cf38 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -127,10 +127,19 @@ void ModrinthManagedPackPage::parseManagedPack() } for (auto version : m_pack.versions) { + QString name; + if (!version.name.contains(version.version)) - ui->versionsComboBox->addItem(QString("%1 — %2").arg(version.name, version.version), QVariant(version.id)); + name = QString("%1 — %2").arg(version.name, version.version); else - ui->versionsComboBox->addItem(version.name, QVariant(version.id)); + name = version.name; + + // NOTE: the id from version isn't the same id in the modpack format spec... + // e.g. HexMC's 4.4.0 has versionId 4.0.0 in the modpack index.............. + if (version.version == m_inst->getManagedPackVersionName()) + name.append(tr(" (Current)")); + + ui->versionsComboBox->addItem(name, QVariant(version.id)); } suggestVersion(); -- cgit From 9e17ff884f84601bd6e48721b32c2af51ca8ee7d Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 14 Oct 2022 14:09:41 -0300 Subject: feat: add PageContainer::getPage This allows us to directly access a page from outside. This will be useful for telling the ManagedPackPage who is the window it's on, so that we can close it when updating :^) Signed-off-by: flow --- launcher/ui/pages/BasePageContainer.h | 3 +++ launcher/ui/widgets/PageContainer.cpp | 5 +++++ launcher/ui/widgets/PageContainer.h | 1 + 3 files changed, 9 insertions(+) diff --git a/launcher/ui/pages/BasePageContainer.h b/launcher/ui/pages/BasePageContainer.h index f8c7adeb..b41fe12a 100644 --- a/launcher/ui/pages/BasePageContainer.h +++ b/launcher/ui/pages/BasePageContainer.h @@ -1,10 +1,13 @@ #pragma once +class BasePage; + class BasePageContainer { public: virtual ~BasePageContainer(){}; virtual bool selectPage(QString pageId) = 0; + virtual BasePage* getPage(QString pageId) { return nullptr; }; virtual void refreshContainer() = 0; virtual bool requestClose() = 0; }; diff --git a/launcher/ui/widgets/PageContainer.cpp b/launcher/ui/widgets/PageContainer.cpp index 8d606820..0a06a351 100644 --- a/launcher/ui/widgets/PageContainer.cpp +++ b/launcher/ui/widgets/PageContainer.cpp @@ -130,6 +130,11 @@ bool PageContainer::selectPage(QString pageId) return false; } +BasePage* PageContainer::getPage(QString pageId) +{ + return m_model->findPageEntryById(pageId); +} + void PageContainer::refreshContainer() { m_proxyModel->invalidate(); diff --git a/launcher/ui/widgets/PageContainer.h b/launcher/ui/widgets/PageContainer.h index 80d87a9b..97e294dc 100644 --- a/launcher/ui/widgets/PageContainer.h +++ b/launcher/ui/widgets/PageContainer.h @@ -79,6 +79,7 @@ public: } virtual bool selectPage(QString pageId) override; + BasePage* getPage(QString pageId) override; void refreshContainer() override; virtual void setParentContainer(BasePageContainer * container) -- cgit From 08d008a5aa7379efe76201250b2511b66665d9a7 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 14 Oct 2022 14:22:13 -0300 Subject: refactor: abstract away update confirmation dialog ... so that we can avoid code duplication. Signed-off-by: flow --- launcher/InstanceTask.cpp | 23 ++++++++++++++++++++++ launcher/InstanceTask.h | 2 ++ .../flame/FlameInstanceCreationTask.cpp | 19 +++--------------- .../modrinth/ModrinthInstanceCreationTask.cpp | 19 +++--------------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/launcher/InstanceTask.cpp b/launcher/InstanceTask.cpp index 55a44fd3..06682782 100644 --- a/launcher/InstanceTask.cpp +++ b/launcher/InstanceTask.cpp @@ -18,6 +18,29 @@ InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& ol return InstanceNameChange::ShouldKeep; } +ShouldUpdate askIfShouldUpdate(QWidget *parent, QString original_version_name) +{ + auto info = CustomMessageBox::selectable( + parent, QObject::tr("Similar modpack was found!"), + QObject::tr("One or more of your instances are from this same modpack%1. Do you want to create a " + "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " + "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") + .arg(original_version_name), + QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); + info->setButtonText(QMessageBox::Ok, QObject::tr("Update existing instance")); + info->setButtonText(QMessageBox::Abort, QObject::tr("Create new instance")); + info->setButtonText(QMessageBox::Reset, QObject::tr("Cancel")); + + info->exec(); + + if (info->clickedButton() == info->button(QMessageBox::Ok)) + return ShouldUpdate::Update; + if (info->clickedButton() == info->button(QMessageBox::Abort)) + return ShouldUpdate::SkipUpdating; + return ShouldUpdate::Cancel; + +} + QString InstanceName::name() const { if (!m_modified_name.isEmpty()) diff --git a/launcher/InstanceTask.h b/launcher/InstanceTask.h index e35533fc..178fbc45 100644 --- a/launcher/InstanceTask.h +++ b/launcher/InstanceTask.h @@ -6,6 +6,8 @@ /* Helpers */ enum class InstanceNameChange { ShouldChange, ShouldKeep }; [[nodiscard]] InstanceNameChange askForChangingInstanceName(QWidget* parent, const QString& old_name, const QString& new_name); +enum class ShouldUpdate { Update, SkipUpdating, Cancel }; +[[nodiscard]] ShouldUpdate askIfShouldUpdate(QWidget* parent, QString original_version_name); struct InstanceName { public: diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index f9258f24..d8356c75 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -102,23 +102,10 @@ bool FlameCreationTask::updateInstance() auto version_id = inst->getManagedPackVersionName(); auto version_str = !version_id.isEmpty() ? tr(" (version %1)").arg(version_id) : ""; - auto info = CustomMessageBox::selectable( - m_parent, tr("Similar modpack was found!"), - tr("One or more of your instances are from this same modpack%1. Do you want to create a " - "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " - "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") - .arg(version_str), - QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); - info->setButtonText(QMessageBox::Ok, tr("Update existing instance")); - info->setButtonText(QMessageBox::Abort, tr("Create new instance")); - info->setButtonText(QMessageBox::Reset, tr("Cancel")); - - info->exec(); - - if (info->clickedButton() == info->button(QMessageBox::Abort)) + auto should_update = askIfShouldUpdate(m_parent, version_str); + if (should_update == ShouldUpdate::SkipUpdating) return false; - - if (info->clickedButton() == info->button(QMessageBox::Reset)) { + if (should_update == ShouldUpdate::Cancel) { m_abort = true; return false; } diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index ddeea224..762feef6 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -49,23 +49,10 @@ bool ModrinthCreationTask::updateInstance() auto version_name = inst->getManagedPackVersionName(); auto version_str = !version_name.isEmpty() ? tr(" (version %1)").arg(version_name) : ""; - auto info = CustomMessageBox::selectable( - m_parent, tr("Similar modpack was found!"), - tr("One or more of your instances are from this same modpack%1. Do you want to create a " - "separate instance, or update the existing one?\n\nNOTE: Make sure you made a backup of your important instance data before " - "updating, as worlds can be corrupted and some configuration may be lost (due to pack overrides).") - .arg(version_str), - QMessageBox::Information, QMessageBox::Ok | QMessageBox::Reset | QMessageBox::Abort); - info->setButtonText(QMessageBox::Ok, tr("Create new instance")); - info->setButtonText(QMessageBox::Abort, tr("Update existing instance")); - info->setButtonText(QMessageBox::Reset, tr("Cancel")); - - info->exec(); - - if (info->clickedButton() == info->button(QMessageBox::Ok)) + auto should_update = askIfShouldUpdate(m_parent, version_str); + if (should_update == ShouldUpdate::SkipUpdating) return false; - - if (info->clickedButton() == info->button(QMessageBox::Reset)) { + if (should_update == ShouldUpdate::Cancel) { m_abort = true; return false; } -- cgit From 82699cc297de64fe6e39404dae29ad812766aba0 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 14 Oct 2022 14:23:55 -0300 Subject: feat: allow skipping the update confirmation dialog Signed-off-by: flow --- launcher/InstanceTask.h | 4 ++++ launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 14 ++++++++------ .../modplatform/modrinth/ModrinthInstanceCreationTask.cpp | 14 ++++++++------ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/launcher/InstanceTask.h b/launcher/InstanceTask.h index 178fbc45..e481354c 100644 --- a/launcher/InstanceTask.h +++ b/launcher/InstanceTask.h @@ -44,6 +44,9 @@ class InstanceTask : public Task, public InstanceName { void setGroup(const QString& group) { m_instGroup = group; } QString group() const { return m_instGroup; } + [[nodiscard]] bool shouldConfirmUpdate() const { return m_confirm_update; } + void setConfirmUpdate(bool confirm) { m_confirm_update = confirm; } + bool shouldOverride() const { return m_override_existing; } protected: @@ -56,4 +59,5 @@ class InstanceTask : public Task, public InstanceName { QString m_stagingPath; bool m_override_existing = false; + bool m_confirm_update = true; }; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index d8356c75..d466f029 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -102,12 +102,14 @@ bool FlameCreationTask::updateInstance() auto version_id = inst->getManagedPackVersionName(); auto version_str = !version_id.isEmpty() ? tr(" (version %1)").arg(version_id) : ""; - auto should_update = askIfShouldUpdate(m_parent, version_str); - if (should_update == ShouldUpdate::SkipUpdating) - return false; - if (should_update == ShouldUpdate::Cancel) { - m_abort = true; - return false; + if (shouldConfirmUpdate()) { + auto should_update = askIfShouldUpdate(m_parent, version_str); + if (should_update == ShouldUpdate::SkipUpdating) + return false; + if (should_update == ShouldUpdate::Cancel) { + m_abort = true; + return false; + } } QDir old_inst_dir(inst->instanceRoot()); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 762feef6..5eb28a85 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -49,12 +49,14 @@ bool ModrinthCreationTask::updateInstance() auto version_name = inst->getManagedPackVersionName(); auto version_str = !version_name.isEmpty() ? tr(" (version %1)").arg(version_name) : ""; - auto should_update = askIfShouldUpdate(m_parent, version_str); - if (should_update == ShouldUpdate::SkipUpdating) - return false; - if (should_update == ShouldUpdate::Cancel) { - m_abort = true; - return false; + if (shouldConfirmUpdate()) { + auto should_update = askIfShouldUpdate(m_parent, version_str); + if (should_update == ShouldUpdate::SkipUpdating) + return false; + if (should_update == ShouldUpdate::Cancel) { + m_abort = true; + return false; + } } // Remove repeated files, we don't need to download them! -- cgit From 58d2c15ffa4a966b40ba2f741c90e1d32fdbe106 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 14 Oct 2022 14:36:48 -0300 Subject: feat: add functionality to MR modpack update in the page :D Signed-off-by: flow --- launcher/InstanceImportTask.cpp | 2 + launcher/ui/InstanceWindow.cpp | 6 +++ launcher/ui/pages/instance/ManagedPackPage.cpp | 73 ++++++++++++++++++++++---- launcher/ui/pages/instance/ManagedPackPage.h | 26 +++++++-- 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 5f459649..f5ef250e 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -264,6 +264,7 @@ void InstanceImportTask::processFlame() inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); inst_creation_task->setGroup(m_instGroup); + inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); connect(inst_creation_task, &Task::succeeded, this, [this, inst_creation_task] { setOverride(inst_creation_task->shouldOverride()); @@ -328,6 +329,7 @@ void InstanceImportTask::processModrinth() inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); inst_creation_task->setGroup(m_instGroup); + inst_creation_task->setConfirmUpdate(shouldConfirmUpdate()); connect(inst_creation_task, &Task::succeeded, this, [this, inst_creation_task] { setOverride(inst_creation_task->shouldOverride()); diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 09ce0d67..c62b370f 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -132,6 +132,12 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) { connect(m_instance.get(), &BaseInstance::statusChanged, this, &InstanceWindow::on_instanceStatusChanged); } + + // add ourself as the modpack page's instance window + { + static_cast(m_container->getPage("managed_pack"))->setInstanceWindow(this); + } + show(); } diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 7c51cf38..348dd857 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -6,10 +6,17 @@ #include "Application.h" #include "BuildConfig.h" +#include "InstanceImportTask.h" +#include "InstanceList.h" +#include "InstanceTask.h" #include "Json.h" #include "modplatform/modrinth/ModrinthPackManifest.h" +#include "ui/InstanceWindow.h" +#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ProgressDialog.h" + /** This is just to override the combo box popup behavior so that the combo box doesn't take the whole screen. * ... thanks Qt. */ @@ -33,14 +40,15 @@ class NoBigComboBoxStyle : public QProxyStyle { ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent) { if (type == "modrinth") - return new ModrinthManagedPackPage(inst, parent); + return new ModrinthManagedPackPage(inst, nullptr, parent); if (type == "flame") - return new FlameManagedPackPage(inst, parent); + return new FlameManagedPackPage(inst, nullptr, parent); - return new GenericManagedPackPage(inst, parent); + return new GenericManagedPackPage(inst, nullptr, parent); } -ManagedPackPage::ManagedPackPage(BaseInstance* inst, QWidget* parent) : QWidget(parent), ui(new Ui::ManagedPackPage), m_inst(inst) +ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent) + : QWidget(parent), m_instance_window(instance_window), ui(new Ui::ManagedPackPage), m_inst(inst) { Q_ASSERT(inst); @@ -92,10 +100,37 @@ bool ManagedPackPage::shouldDisplay() const return m_inst->isManagedPack(); } -ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, QWidget* parent) : ManagedPackPage(inst, parent) +bool ManagedPackPage::runUpdateTask(InstanceTask* task) +{ + Q_ASSERT(task); + + unique_qobject_ptr wrapped_task(APPLICATION->instances()->wrapInstanceTask(task)); + + connect(task, &Task::failed, + [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); + connect(task, &Task::succeeded, [this, task]() { + QStringList warnings = task->warnings(); + if (warnings.count()) + CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show(); + }); + connect(task, &Task::aborted, [this] { + CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) + ->show(); + }); + + ProgressDialog loadDialog(this); + loadDialog.setSkipButton(true, tr("Abort")); + loadDialog.execWithTask(task); + + return task->wasSuccessful(); +} + +ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent) + : ManagedPackPage(inst, instance_window, parent) { Q_ASSERT(inst->isManagedPack()); connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); + connect(ui->updateButton, &QPushButton::pressed, this, &ModrinthManagedPackPage::update); } void ModrinthManagedPackPage::parseManagedPack() @@ -166,16 +201,36 @@ void ModrinthManagedPackPage::suggestVersion() ui->changelogTextBrowser->setText(version.changelog); } -FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, QWidget* parent) : ManagedPackPage(inst, parent) +void ModrinthManagedPackPage::update() { - Q_ASSERT(inst->isManagedPack()); - connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); + auto index = ui->versionsComboBox->currentIndex(); + auto version = m_pack.versions.at(index); + + auto extracted = new InstanceImportTask(version.download_url, this); + + InstanceName inst_name(m_inst->getManagedPackName(), version.version); + inst_name.setName(m_inst->name().replace(m_inst->getManagedPackVersionName(), version.version)); + extracted->setName(inst_name); + + extracted->setGroup(APPLICATION->instances()->getInstanceGroup(m_inst->id())); + extracted->setIcon(m_inst->iconKey()); + extracted->setConfirmUpdate(false); + + auto did_succeed = runUpdateTask(extracted); + + if (m_instance_window && did_succeed) + m_instance_window->close(); } -void FlameManagedPackPage::parseManagedPack() +FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent) + : ManagedPackPage(inst, instance_window, parent) { + Q_ASSERT(inst->isManagedPack()); + connect(ui->versionsComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(suggestVersion())); } +void FlameManagedPackPage::parseManagedPack() {} + QString FlameManagedPackPage::url() const { return {}; diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h index 1a756d33..dc6ae118 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.h +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -13,6 +13,9 @@ namespace Ui { class ManagedPackPage; } +class InstanceTask; +class InstanceWindow; + class ManagedPackPage : public QWidget, public BasePage { Q_OBJECT @@ -45,15 +48,28 @@ class ManagedPackPage : public QWidget, public BasePage { */ [[nodiscard]] virtual QString url() const { return {}; }; + void setInstanceWindow(InstanceWindow* window) { m_instance_window = window; } + public slots: /** Gets the current version selection and update the changelog. */ virtual void suggestVersion() {}; + virtual void update() {}; + protected: - ManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr); + + /** Run the InstanceTask, with a progress dialog and all. + * Similar to MainWindow::instanceFromInstanceTask + * + * Returns whether the task was successful. + */ + bool runUpdateTask(InstanceTask*); protected: + InstanceWindow* m_instance_window = nullptr; + Ui::ManagedPackPage* ui; BaseInstance* m_inst; @@ -65,7 +81,7 @@ class GenericManagedPackPage final : public ManagedPackPage { Q_OBJECT public: - GenericManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr) : ManagedPackPage(inst, parent) {} + GenericManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr) : ManagedPackPage(inst, instance_window, parent) {} ~GenericManagedPackPage() override = default; }; @@ -73,7 +89,7 @@ class ModrinthManagedPackPage final : public ManagedPackPage { Q_OBJECT public: - ModrinthManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr); ~ModrinthManagedPackPage() override = default; void parseManagedPack() override; @@ -82,6 +98,8 @@ class ModrinthManagedPackPage final : public ManagedPackPage { public slots: void suggestVersion() override; + void update() override; + private: Modrinth::Modpack m_pack; ModrinthAPI m_api; @@ -91,7 +109,7 @@ class FlameManagedPackPage final : public ManagedPackPage { Q_OBJECT public: - FlameManagedPackPage(BaseInstance* inst, QWidget* parent = nullptr); + FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr); ~FlameManagedPackPage() override = default; void parseManagedPack() override; -- cgit From 0ff8891c6669ffe851afd98edab226a9173a6633 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 14 Oct 2022 14:38:42 -0300 Subject: feat: add ManagedPackPage to the instance pages Signed-off-by: flow --- launcher/CMakeLists.txt | 3 +++ launcher/InstancePageProvider.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 3eb765dc..245b6995 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -680,6 +680,8 @@ SET(LAUNCHER_SOURCES ui/pages/instance/GameOptionsPage.h ui/pages/instance/VersionPage.cpp ui/pages/instance/VersionPage.h + ui/pages/instance/ManagedPackPage.cpp + ui/pages/instance/ManagedPackPage.h ui/pages/instance/TexturePackPage.h ui/pages/instance/ResourcePackPage.h ui/pages/instance/ShaderPackPage.h @@ -919,6 +921,7 @@ qt_wrap_ui(LAUNCHER_UI ui/pages/instance/OtherLogsPage.ui ui/pages/instance/InstanceSettingsPage.ui ui/pages/instance/VersionPage.ui + ui/pages/instance/ManagedPackPage.ui ui/pages/instance/WorldListPage.ui ui/pages/instance/ScreenshotsPage.ui ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index bf29377d..5d8beca9 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -5,6 +5,7 @@ #include "ui/pages/BasePageProvider.h" #include "ui/pages/instance/LogPage.h" #include "ui/pages/instance/VersionPage.h" +#include "ui/pages/instance/ManagedPackPage.h" #include "ui/pages/instance/ModFolderPage.h" #include "ui/pages/instance/ResourcePackPage.h" #include "ui/pages/instance/TexturePackPage.h" @@ -33,6 +34,7 @@ public: values.append(new LogPage(inst)); std::shared_ptr onesix = std::dynamic_pointer_cast(inst); values.append(new VersionPage(onesix.get())); + values.append(ManagedPackPage::createPage(onesix.get())); auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList()); modsPage->setFilter("%1 (*.zip *.jar *.litemod)"); values.append(modsPage); -- cgit From 25cfa26e7b24242dec3b775d9b0c09c84f870a39 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 22 Oct 2022 16:02:10 -0300 Subject: fix: use rich text in changelog for modrinth modpacks Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 348dd857..6d051760 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "Application.h" #include "BuildConfig.h" #include "InstanceImportTask.h" @@ -198,7 +200,8 @@ void ModrinthManagedPackPage::suggestVersion() auto index = ui->versionsComboBox->currentIndex(); auto version = m_pack.versions.at(index); - ui->changelogTextBrowser->setText(version.changelog); + HoeDown md_parser; + ui->changelogTextBrowser->setHtml(md_parser.process(version.changelog.toUtf8())); } void ModrinthManagedPackPage::update() -- cgit From 95392309150079d73f4ee83ea7bdba98ef9caa2f Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 11 Nov 2022 16:58:37 -0300 Subject: fix: do not display managed pack page for providers without an impl. yet Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h index dc6ae118..7ad13533 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.h +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -83,6 +83,9 @@ class GenericManagedPackPage final : public ManagedPackPage { public: GenericManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr) : ManagedPackPage(inst, instance_window, parent) {} ~GenericManagedPackPage() override = default; + + // TODO: We may want to show this page with some useful info at some point. + [[nodiscard]] bool shouldDisplay() const override { return false; }; }; class ModrinthManagedPackPage final : public ManagedPackPage { -- cgit From d4979974b4f65d6662557e0415085c90f1ad5a11 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 11 Nov 2022 17:44:16 -0300 Subject: fix(ManagedPackPage): better UX for when network requests fail / are pending Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.cpp | 34 ++++++++++++++++++++++++++ launcher/ui/pages/instance/ManagedPackPage.h | 14 +++++++++-- launcher/ui/pages/instance/ManagedPackPage.ui | 5 +++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index 6d051760..be0b2f86 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -127,6 +127,30 @@ bool ManagedPackPage::runUpdateTask(InstanceTask* task) return task->wasSuccessful(); } +void ManagedPackPage::suggestVersion() +{ + ui->updateButton->setText(tr("Update pack")); + ui->updateButton->setDisabled(false); +} + +void ManagedPackPage::setFailState() +{ + qDebug() << "Setting fail state!"; + + // We block signals here so that suggestVersion() doesn't get called, causing an assertion fail. + ui->versionsComboBox->blockSignals(true); + ui->versionsComboBox->clear(); + ui->versionsComboBox->addItem(tr("Failed to search for available versions."), {}); + ui->versionsComboBox->blockSignals(false); + + ui->changelogTextBrowser->setText(tr("Failed to request changelog data for this modpack.")); + + ui->updateButton->setText(tr("Cannot update!")); + ui->updateButton->setDisabled(true); + + // TODO: Perhaps start a timer here when m_loaded is false to try and reload. +} + ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent) : ManagedPackPage(inst, instance_window, parent) { @@ -153,6 +177,9 @@ void ModrinthManagedPackPage::parseManagedPack() qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; + + setFailState(); + return; } @@ -161,6 +188,9 @@ void ModrinthManagedPackPage::parseManagedPack() } catch (const JSONValidationError& e) { qDebug() << *response; qWarning() << "Error while reading modrinth modpack version: " << e.cause(); + + setFailState(); + return; } for (auto version : m_pack.versions) { @@ -183,6 +213,8 @@ void ModrinthManagedPackPage::parseManagedPack() m_loaded = true; }); + QObject::connect(netJob, &NetJob::failed, this, &ModrinthManagedPackPage::setFailState); + QObject::connect(netJob, &NetJob::aborted, this, &ModrinthManagedPackPage::setFailState); QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { netJob->deleteLater(); delete response; @@ -202,6 +234,8 @@ void ModrinthManagedPackPage::suggestVersion() HoeDown md_parser; ui->changelogTextBrowser->setHtml(md_parser.process(version.changelog.toUtf8())); + + ManagedPackPage::suggestVersion(); } void ModrinthManagedPackPage::update() diff --git a/launcher/ui/pages/instance/ManagedPackPage.h b/launcher/ui/pages/instance/ManagedPackPage.h index 7ad13533..a81d24f0 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.h +++ b/launcher/ui/pages/instance/ManagedPackPage.h @@ -51,12 +51,22 @@ class ManagedPackPage : public QWidget, public BasePage { void setInstanceWindow(InstanceWindow* window) { m_instance_window = window; } public slots: - /** Gets the current version selection and update the changelog. + /** Gets the current version selection and update the UI, including the update button and the changelog. */ - virtual void suggestVersion() {}; + virtual void suggestVersion(); virtual void update() {}; + protected slots: + /** Does the necessary UI changes for when something failed. + * + * This includes: + * - Setting an appropriate text on the version selector to indicate a fail; + * - Setting an appropriate text on the changelog text browser to indicate a fail; + * - Disable the update button. + */ + void setFailState(); + protected: ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr); diff --git a/launcher/ui/pages/instance/ManagedPackPage.ui b/launcher/ui/pages/instance/ManagedPackPage.ui index 3f019606..14009b13 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.ui +++ b/launcher/ui/pages/instance/ManagedPackPage.ui @@ -133,6 +133,9 @@ + + false + 0 @@ -140,7 +143,7 @@ - Update pack + Fetching versions... -- cgit From 7f5dea28bb2d9cd6ee90c4e5498dce0b57c0cce0 Mon Sep 17 00:00:00 2001 From: flow Date: Fri, 11 Nov 2022 18:29:32 -0300 Subject: feat(ManagedPackPage): add link to the Modrinth's pack page Signed-off-by: flow --- launcher/ui/pages/instance/ManagedPackPage.cpp | 6 +++--- launcher/ui/pages/instance/ManagedPackPage.ui | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp index be0b2f86..126757d5 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.cpp +++ b/launcher/ui/pages/instance/ManagedPackPage.cpp @@ -68,8 +68,8 @@ void ManagedPackPage::openedImpl() { ui->packName->setText(m_inst->getManagedPackName()); ui->packVersion->setText(m_inst->getManagedPackVersionName()); - ui->packOrigin->setText(tr("Website: %1 | Pack ID: %2 | Version ID: %3") - .arg(displayName(), m_inst->getManagedPackID(), m_inst->getManagedPackVersionID())); + ui->packOrigin->setText(tr("Website: %2 | Pack ID: %3 | Version ID: %4") + .arg(url(), displayName(), m_inst->getManagedPackID(), m_inst->getManagedPackVersionID())); parseManagedPack(); } @@ -224,7 +224,7 @@ void ModrinthManagedPackPage::parseManagedPack() QString ModrinthManagedPackPage::url() const { - return {}; + return "https://modrinth.com/mod/" + m_inst->getManagedPackID(); } void ModrinthManagedPackPage::suggestVersion() diff --git a/launcher/ui/pages/instance/ManagedPackPage.ui b/launcher/ui/pages/instance/ManagedPackPage.ui index 14009b13..6d8911e0 100644 --- a/launcher/ui/pages/instance/ManagedPackPage.ui +++ b/launcher/ui/pages/instance/ManagedPackPage.ui @@ -96,6 +96,12 @@ placeholder + + Qt::RichText + + + true + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse -- cgit From 968366c2aecb3337af281a01de56023ce5ffe2f9 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 12 Nov 2022 11:42:07 -0300 Subject: feat+fix: allow forwarding extra info to InstanceImportTask This allows us to pass to the creation instances their actual pack ID and version ID, that in Flame's case, are only available before starting to create an instance. Signed-off-by: flow --- launcher/InstanceImportTask.cpp | 29 ++++++++++++++++------ launcher/InstanceImportTask.h | 6 ++++- .../flame/FlameInstanceCreationTask.cpp | 2 +- .../modplatform/flame/FlameInstanceCreationTask.h | 6 +++-- .../modrinth/ModrinthInstanceCreationTask.cpp | 15 +++-------- .../modrinth/ModrinthInstanceCreationTask.h | 6 ++--- launcher/ui/pages/modplatform/flame/FlamePage.cpp | 17 ++++++++++--- launcher/ui/pages/modplatform/flame/FlamePage.h | 2 +- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 6 ++++- 9 files changed, 56 insertions(+), 33 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index f5ef250e..7c04ec47 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -55,11 +55,9 @@ #include -InstanceImportTask::InstanceImportTask(const QUrl sourceUrl, QWidget* parent) -{ - m_sourceUrl = sourceUrl; - m_parent = parent; -} +InstanceImportTask::InstanceImportTask(const QUrl sourceUrl, QWidget* parent, QMap extra_info) + : m_sourceUrl(sourceUrl), m_extra_info(std::move(extra_info)), m_parent(parent) +{} bool InstanceImportTask::abort() { @@ -259,7 +257,15 @@ void InstanceImportTask::extractAborted() void InstanceImportTask::processFlame() { - auto* inst_creation_task = new FlameCreationTask(m_stagingPath, m_globalSettings, m_parent); + auto pack_id_it = m_extra_info.constFind("pack_id"); + Q_ASSERT(pack_id_it != m_extra_info.constEnd()); + auto pack_id = pack_id_it.value(); + + auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); + Q_ASSERT(pack_version_id_it != m_extra_info.constEnd()); + auto pack_version_id = pack_version_id_it.value(); + + auto* inst_creation_task = new FlameCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id); inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); @@ -324,7 +330,16 @@ void InstanceImportTask::processMultiMC() void InstanceImportTask::processModrinth() { - auto* inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, m_sourceUrl.toString()); + auto pack_id_it = m_extra_info.constFind("pack_id"); + Q_ASSERT(pack_id_it != m_extra_info.constEnd()); + auto pack_id = pack_id_it.value(); + + QString pack_version_id; + auto pack_version_id_it = m_extra_info.constFind("pack_version_id"); + if (pack_version_id_it != m_extra_info.constEnd()) + pack_version_id = pack_version_id_it.value(); + + auto* inst_creation_task = new ModrinthCreationTask(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id); inst_creation_task->setName(*this); inst_creation_task->setIcon(m_instIcon); diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index ef70c819..712ef054 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -56,7 +56,7 @@ class InstanceImportTask : public InstanceTask { Q_OBJECT public: - explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr); + explicit InstanceImportTask(const QUrl sourceUrl, QWidget* parent = nullptr, QMap extra_info = {}); bool abort() override; const QVector &getBlockedFiles() const @@ -101,6 +101,10 @@ private: /* data */ Modrinth, } m_modpackType = ModpackType::Unknown; + // Extra info we might need, that's available before, but can't be derived from + // the source URL / the resource it points to alone. + QMap m_extra_info; + //FIXME: nuke QWidget* m_parent; }; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index d466f029..ad50597e 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -355,7 +355,7 @@ bool FlameCreationTask::createInstance() FS::deletePath(jarmodsPath); } - instance.setManagedPack("flame", {}, m_pack.name, {}, m_pack.version); + instance.setManagedPack("flame", m_managed_id, m_pack.name, m_managed_version_id, m_pack.version); instance.setName(name()); m_mod_id_resolver = new Flame::FileResolvingTask(APPLICATION->network(), m_pack); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h index 5d227ee5..2a513602 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.h +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h @@ -51,8 +51,8 @@ class FlameCreationTask final : public InstanceCreationTask { Q_OBJECT public: - FlameCreationTask(const QString& staging_path, SettingsObjectPtr global_settings, QWidget* parent) - : InstanceCreationTask(), m_parent(parent) + FlameCreationTask(const QString& staging_path, SettingsObjectPtr global_settings, QWidget* parent, QString id, QString version_id) + : InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id)) { setStagingPath(staging_path); setParentSettings(global_settings); @@ -78,5 +78,7 @@ class FlameCreationTask final : public InstanceCreationTask { NetJob* m_process_update_file_info_job = nullptr; NetJob::Ptr m_files_job = nullptr; + QString m_managed_id, m_managed_version_id; + std::optional m_instance; }; diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 5eb28a85..c043a2e3 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -211,7 +211,7 @@ bool ModrinthCreationTask::createInstance() instance.setIconKey("modrinth"); } - instance.setManagedPack("modrinth", getManagedPackID(), m_managed_name, m_managed_version_id, version()); + instance.setManagedPack("modrinth", m_managed_id, m_managed_name, m_managed_version_id, version()); instance.setName(name()); instance.saveNow(); @@ -284,7 +284,8 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector< } if (set_managed_info) { - m_managed_version_id = Json::ensureString(obj, "versionId", {}, "Managed ID"); + if (m_managed_version_id.isEmpty()) + m_managed_version_id = Json::ensureString(obj, "versionId", {}, "Managed ID"); m_managed_name = Json::ensureString(obj, "name", {}, "Managed Name"); } @@ -384,13 +385,3 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector< return true; } - -QString ModrinthCreationTask::getManagedPackID() const -{ - if (!m_source_url.isEmpty()) { - QRegularExpression regex(R"(data\/(.*)\/versions)"); - return regex.match(m_source_url).captured(1); - } - - return {}; -} diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h index e459aadf..551674d2 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h @@ -14,8 +14,8 @@ class ModrinthCreationTask final : public InstanceCreationTask { Q_OBJECT public: - ModrinthCreationTask(QString staging_path, SettingsObjectPtr global_settings, QWidget* parent, QString source_url = {}) - : InstanceCreationTask(), m_parent(parent), m_source_url(std::move(source_url)) + ModrinthCreationTask(QString staging_path, SettingsObjectPtr global_settings, QWidget* parent, QString id, QString version_id = {}) + : InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id)) { setStagingPath(staging_path); setParentSettings(global_settings); @@ -28,14 +28,12 @@ class ModrinthCreationTask final : public InstanceCreationTask { private: bool parseManifest(const QString&, std::vector&, bool set_managed_info = true, bool show_optional_dialog = true); - QString getManagedPackID() const; private: QWidget* m_parent = nullptr; QString minecraftVersion, fabricVersion, quiltVersion, forgeVersion; QString m_managed_id, m_managed_version_id, m_managed_name; - QString m_source_url; std::vector m_files; NetJob::Ptr m_files_job; diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index a65b6585..d288a869 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -197,12 +197,18 @@ void FlamePage::suggestCurrent() return; } - if (selectedVersion.isEmpty() || selectedVersion == "-1") { + if (m_selected_version_index == -1) { dialog->setSuggestedPack(); return; } - dialog->setSuggestedPack(current.name, new InstanceImportTask(selectedVersion,this)); + auto version = current.versions.at(m_selected_version_index); + + QMap extra_info; + extra_info.insert("pack_id", QString::number(current.addonId)); + extra_info.insert("pack_version_id", QString::number(version.fileId)); + + dialog->setSuggestedPack(current.name, new InstanceImportTask(version.downloadUrl, this, extra_info)); QString editedLogoName; editedLogoName = "curseforge_" + current.logoName.section(".", 0, 0); listModel->getLogo(current.logoName, current.logoUrl, @@ -212,10 +218,13 @@ void FlamePage::suggestCurrent() void FlamePage::onVersionSelectionChanged(QString data) { if (data.isNull() || data.isEmpty()) { - selectedVersion = ""; + m_selected_version_index = -1; return; } - selectedVersion = ui->versionSelectionBox->currentData().toString(); + + m_selected_version_index = ui->versionSelectionBox->currentIndex(); + Q_ASSERT(current.versions.at(m_selected_version_index).downloadUrl == ui->versionSelectionBox->currentData().toString()); + suggestCurrent(); } diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.h b/launcher/ui/pages/modplatform/flame/FlamePage.h index