diff --git a/README.md b/README.md index 093bc94da..61bf4c20b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ For **Arch**, **Debian**, **Fedora**, **OpenSUSE (Tumbleweed)** and **Gentoo**, [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?label=AUR&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?label=MPR&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git)
[![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?label=COPR&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?label=Gentoo&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) -These packages are also availiable to all the distributions based on the ones mentioned above. +These packages are also available to all the distributions based on the ones mentioned above. ## Community & Support diff --git a/flake.lock b/flake.lock index ad18ff615..d71403358 100644 --- a/flake.lock +++ b/flake.lock @@ -106,11 +106,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1697009197, - "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "lastModified": 1697886341, + "narHash": "sha256-AdE67xPty9M9wn36nPVp6aDntIdigrs7UbyaGv1VAaM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "rev": "44881e03af1c730cbb1d72a4d41274a2c957813a", "type": "github" }, "original": { @@ -153,11 +153,11 @@ ] }, "locked": { - "lastModified": 1696846637, - "narHash": "sha256-0hv4kbXxci2+pxhuXlVgftj/Jq79VSmtAyvfabCCtYk=", + "lastModified": 1697746376, + "narHash": "sha256-gu77VkgdfaHgNCVufeb6WP9oqFLjwK4jHcoPZmBVF3E=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "42e1b6095ef80a51f79595d9951eb38e91c4e6ca", + "rev": "8cc349bfd082da8782b989cad2158c9ad5bd70fd", "type": "github" }, "original": { diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 19b837a2f..9fd77f176 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -139,6 +139,7 @@ set(NET_SOURCES net/HeaderProxy.h net/RawHeaderProxy.h net/ApiHeaderProxy.h + net/StaticHeaderProxy.h net/ApiDownload.h net/ApiDownload.cpp net/ApiUpload.cpp diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 21a146062..9fb385777 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -106,7 +106,7 @@ void LaunchController::decideAccount() // Select the account to use. If the instance has a specific account set, that will be used. Otherwise, the default account will be used auto instanceAccountId = m_instance->settings()->get("InstanceAccountId").toString(); auto instanceAccountIndex = accounts->findAccountByProfileId(instanceAccountId); - if (instanceAccountIndex == -1) { + if (instanceAccountIndex == -1 || instanceAccountId.isEmpty()) { m_accountToUse = accounts->defaultAccount(); } else { m_accountToUse = accounts->at(instanceAccountIndex); diff --git a/launcher/minecraft/AssetsUtils.cpp b/launcher/minecraft/AssetsUtils.cpp index 4ef007075..48e150d16 100644 --- a/launcher/minecraft/AssetsUtils.cpp +++ b/launcher/minecraft/AssetsUtils.cpp @@ -48,6 +48,7 @@ #include "FileSystem.h" #include "net/ApiDownload.h" #include "net/ChecksumValidator.h" +#include "net/Download.h" #include "Application.h" diff --git a/launcher/net/NetRequest.cpp b/launcher/net/NetRequest.cpp index cb675be1b..728c0e077 100644 --- a/launcher/net/NetRequest.cpp +++ b/launcher/net/NetRequest.cpp @@ -112,6 +112,8 @@ void NetRequest::executeTask() m_last_progress_bytes = 0; QNetworkReply* rep = getReply(request); + if (rep == nullptr) // it failed + return; m_reply.reset(rep); connect(rep, &QNetworkReply::downloadProgress, this, &NetRequest::downloadProgress); connect(rep, &QNetworkReply::finished, this, &NetRequest::downloadFinished); diff --git a/launcher/net/StaticHeaderProxy.h b/launcher/net/StaticHeaderProxy.h new file mode 100644 index 000000000..8af7d203d --- /dev/null +++ b/launcher/net/StaticHeaderProxy.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (C) 2023 Rachel Powers <508861+Ryex@users.noreply.github.com> + * + * 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 . + * + */ + +#pragma once + +#include "net/HeaderProxy.h" + +namespace Net { + +class StaticHeaderProxy : public HeaderProxy { + public: + StaticHeaderProxy(QList hdrs = {}) : HeaderProxy(), m_hdrs(hdrs){}; + virtual ~StaticHeaderProxy() = default; + + public: + virtual QList headers(const QNetworkRequest&) const override { return m_hdrs; }; + void setHeaders(QList hdrs) { m_hdrs = hdrs; }; + + private: + QList m_hdrs; +}; + +} // namespace Net diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index d548c89ae..7e42ff40c 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -39,87 +39,76 @@ #include #include #include +#include #include #include #include +#include -#include "Application.h" #include "BuildConfig.h" +#include "net/StaticHeaderProxy.h" -ImgurAlbumCreation::ImgurAlbumCreation(QList screenshots) : NetAction(), m_screenshots(screenshots) +Net::NetRequest::Ptr ImgurAlbumCreation::make(std::shared_ptr output, QList screenshots) { - m_url = BuildConfig.IMGUR_BASE_URL + "album.json"; - m_state = State::Inactive; + auto up = makeShared(); + up->m_url = BuildConfig.IMGUR_BASE_URL + "album.json"; + up->m_sink.reset(new Sink(output)); + up->m_screenshots = screenshots; + return up; } -void ImgurAlbumCreation::executeTask() +QNetworkReply* ImgurAlbumCreation::getReply(QNetworkRequest& request) { - m_state = State::Running; - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); - request.setRawHeader("Accept", "application/json"); - QStringList hashes; for (auto shot : m_screenshots) { hashes.append(shot->m_imgurDeleteHash); } - const QByteArray data = "deletehashes=" + hashes.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; + return m_network->post(request, data); +}; - QNetworkReply* rep = APPLICATION->network()->post(request, data); - - m_reply.reset(rep); - connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); - connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 - connect(rep, &QNetworkReply::errorOccurred, this, &ImgurAlbumCreation::downloadError); -#else - connect(rep, QOverload::of(&QNetworkReply::error), this, &ImgurAlbumCreation::downloadError); -#endif - connect(rep, &QNetworkReply::sslErrors, this, &ImgurAlbumCreation::sslErrors); +void ImgurAlbumCreation::init() +{ + qDebug() << "Setting up imgur upload"; + auto api_headers = new Net::StaticHeaderProxy( + QList{ { "Content-Type", "application/x-www-form-urlencoded" }, + { "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str() }, + { "Accept", "application/json" } }); + addHeaderProxy(api_headers); } -void ImgurAlbumCreation::downloadError([[maybe_unused]] QNetworkReply::NetworkError error) +auto ImgurAlbumCreation::Sink::init(QNetworkRequest& request) -> Task::State { - qDebug() << m_reply->errorString(); - m_state = State::Failed; + m_output.clear(); + return Task::State::Running; +}; + +auto ImgurAlbumCreation::Sink::write(QByteArray& data) -> Task::State +{ + m_output.append(data); + return Task::State::Running; } -void ImgurAlbumCreation::downloadFinished() +auto ImgurAlbumCreation::Sink::abort() -> Task::State { - if (m_state != State::Failed) { - QByteArray data = m_reply->readAll(); - m_reply.reset(); - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) { - qDebug() << jsonError.errorString(); - emitFailed(); - return; - } - auto object = doc.object(); - if (!object.value("success").toBool()) { - qDebug() << doc.toJson(); - emitFailed(); - return; - } - m_deleteHash = object.value("data").toObject().value("deletehash").toString(); - m_id = object.value("data").toObject().value("id").toString(); - m_state = State::Succeeded; - emit succeeded(); - return; - } else { - qDebug() << m_reply->readAll(); - m_reply.reset(); - emitFailed(); - return; + m_output.clear(); + return Task::State::Failed; +} + +auto ImgurAlbumCreation::Sink::finalize(QNetworkReply&) -> Task::State +{ + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(m_output, &jsonError); + if (jsonError.error != QJsonParseError::NoError) { + qDebug() << jsonError.errorString(); + return Task::State::Failed; } -} - -void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - setProgress(bytesReceived, bytesTotal); - emit progress(bytesReceived, bytesTotal); -} + auto object = doc.object(); + if (!object.value("success").toBool()) { + qDebug() << doc.toJson(); + return Task::State::Failed; + } + m_result->deleteHash = object.value("data").toObject().value("deletehash").toString(); + m_result->id = object.value("data").toObject().value("id").toString(); + return Task::State::Succeeded; +} \ No newline at end of file diff --git a/launcher/screenshots/ImgurAlbumCreation.h b/launcher/screenshots/ImgurAlbumCreation.h index bb71bec2b..7c292db73 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -36,34 +36,39 @@ #pragma once #include "Screenshot.h" -#include "net/NetAction.h" +#include "net/NetRequest.h" -typedef shared_qobject_ptr ImgurAlbumCreationPtr; -class ImgurAlbumCreation : public NetAction { +class ImgurAlbumCreation : public Net::NetRequest { public: - explicit ImgurAlbumCreation(QList screenshots); - static ImgurAlbumCreationPtr make(QList screenshots) - { - return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); - } + virtual ~ImgurAlbumCreation() = default; - QString deleteHash() const { return m_deleteHash; } - QString id() const { return m_id; } + struct Result { + QString deleteHash; + QString id; + }; - void init() override{}; + class Sink : public Net::Sink { + public: + Sink(std::shared_ptr res) : m_result(res){}; + virtual ~Sink() = default; - protected slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; - void downloadError(QNetworkReply::NetworkError error) override; - void downloadFinished() override; - void downloadReadyRead() override {} + public: + auto init(QNetworkRequest& request) -> Task::State override; + auto write(QByteArray& data) -> Task::State override; + auto abort() -> Task::State override; + auto finalize(QNetworkReply& reply) -> Task::State override; + auto hasLocalData() -> bool override { return false; } - public slots: - void executeTask() override; + private: + std::shared_ptr m_result; + QByteArray m_output; + }; + + static NetRequest::Ptr make(std::shared_ptr output, QList screenshots); + QNetworkReply* getReply(QNetworkRequest& request) override; + + void init() override; private: QList m_screenshots; - - QString m_deleteHash; - QString m_id; }; diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index 29499a20d..7ed672eb7 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -35,8 +35,8 @@ */ #include "ImgurUpload.h" -#include "Application.h" #include "BuildConfig.h" +#include "net/StaticHeaderProxy.h" #include #include @@ -47,104 +47,84 @@ #include #include -ImgurUpload::ImgurUpload(ScreenShot::Ptr shot) : NetAction(), m_shot(shot) +void ImgurUpload::init() { - m_url = BuildConfig.IMGUR_BASE_URL + "upload.json"; - m_state = State::Inactive; + qDebug() << "Setting up imgur upload"; + auto api_headers = new Net::StaticHeaderProxy( + QList{ { "Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str() }, + { "Accept", "application/json" } }); + addHeaderProxy(api_headers); } -void ImgurUpload::executeTask() +QNetworkReply* ImgurUpload::getReply(QNetworkRequest& request) { - finished = false; - m_state = Task::State::Running; - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); - request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); - request.setRawHeader("Accept", "application/json"); + auto file = new QFile(m_fileInfo.absoluteFilePath()); - QFile f(m_shot->m_file.absoluteFilePath()); - if (!f.open(QFile::ReadOnly)) { + if (!file->open(QFile::ReadOnly)) { emitFailed(); - return; + return nullptr; } QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + file->setParent(multipart); QHttpPart filePart; - filePart.setBody(f.readAll().toBase64()); + filePart.setBodyDevice(file); filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png"); filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\""); multipart->append(filePart); QHttpPart typePart; typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\""); - typePart.setBody("base64"); + typePart.setBody("file"); multipart->append(typePart); QHttpPart namePart; namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\""); - namePart.setBody(m_shot->m_file.baseName().toUtf8()); + namePart.setBody(m_fileInfo.baseName().toUtf8()); multipart->append(namePart); - QNetworkReply* rep = m_network->post(request, multipart); + return m_network->post(request, multipart); +}; - m_reply.reset(rep); - connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); - connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished); -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) // QNetworkReply::errorOccurred added in 5.15 - connect(rep, &QNetworkReply::errorOccurred, this, &ImgurUpload::downloadError); -#else - connect(rep, QOverload::of(&QNetworkReply::error), this, &ImgurUpload::downloadError); -#endif - connect(rep, &QNetworkReply::sslErrors, this, &ImgurUpload::sslErrors); +auto ImgurUpload::Sink::init(QNetworkRequest& request) -> Task::State +{ + m_output.clear(); + return Task::State::Running; +}; + +auto ImgurUpload::Sink::write(QByteArray& data) -> Task::State +{ + m_output.append(data); + return Task::State::Running; } -void ImgurUpload::downloadError([[maybe_unused]] QNetworkReply::NetworkError error) +auto ImgurUpload::Sink::abort() -> Task::State { - qCritical() << "ImgurUpload failed with error" << m_reply->errorString() << "Server reply:\n" << m_reply->readAll(); - if (finished) { - qCritical() << "Double finished ImgurUpload!"; - return; - } - m_state = Task::State::Failed; - finished = true; - m_reply.reset(); - emitFailed(); + m_output.clear(); + return Task::State::Failed; } -void ImgurUpload::downloadFinished() +auto ImgurUpload::Sink::finalize(QNetworkReply&) -> Task::State { - if (finished) { - qCritical() << "Double finished ImgurUpload!"; - return; - } - QByteArray data = m_reply->readAll(); - m_reply.reset(); QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + QJsonDocument doc = QJsonDocument::fromJson(m_output, &jsonError); if (jsonError.error != QJsonParseError::NoError) { qDebug() << "imgur server did not reply with JSON" << jsonError.errorString(); - finished = true; - m_reply.reset(); - emitFailed(); - return; + return Task::State::Failed; } auto object = doc.object(); if (!object.value("success").toBool()) { qDebug() << "Screenshot upload not successful:" << doc.toJson(); - finished = true; - m_reply.reset(); - emitFailed(); - return; + return Task::State::Failed; } m_shot->m_imgurId = object.value("data").toObject().value("id").toString(); m_shot->m_url = object.value("data").toObject().value("link").toString(); m_shot->m_imgurDeleteHash = object.value("data").toObject().value("deletehash").toString(); - m_state = Task::State::Succeeded; - finished = true; - emit succeeded(); - return; + return Task::State::Succeeded; } -void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) +Net::NetRequest::Ptr ImgurUpload::make(ScreenShot::Ptr m_shot) { - setProgress(bytesReceived, bytesTotal); - emit progress(bytesReceived, bytesTotal); + auto up = makeShared(m_shot->m_file); + up->m_url = std::move(BuildConfig.IMGUR_BASE_URL + "upload.json"); + up->m_sink.reset(new Sink(m_shot)); + return up; } diff --git a/launcher/screenshots/ImgurUpload.h b/launcher/screenshots/ImgurUpload.h index 542255b2d..5867ad306 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -35,27 +35,36 @@ #pragma once +#include #include "Screenshot.h" -#include "net/NetAction.h" +#include "net/NetRequest.h" -class ImgurUpload : public NetAction { +class ImgurUpload : public Net::NetRequest { public: - using Ptr = shared_qobject_ptr; + class Sink : public Net::Sink { + public: + Sink(ScreenShot::Ptr shot) : m_shot(shot){}; + virtual ~Sink() = default; - explicit ImgurUpload(ScreenShot::Ptr shot); - static Ptr make(ScreenShot::Ptr shot) { return Ptr(new ImgurUpload(shot)); } - void init() override{}; + public: + auto init(QNetworkRequest& request) -> Task::State override; + auto write(QByteArray& data) -> Task::State override; + auto abort() -> Task::State override; + auto finalize(QNetworkReply& reply) -> Task::State override; + auto hasLocalData() -> bool override { return false; } - protected slots: - void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override; - void downloadError(QNetworkReply::NetworkError error) override; - void downloadFinished() override; - void downloadReadyRead() override {} + private: + ScreenShot::Ptr m_shot; + QByteArray m_output; + }; + ImgurUpload(QFileInfo info) : m_fileInfo(info) {} + virtual ~ImgurUpload() = default; - public slots: - void executeTask() override; + static NetRequest::Ptr make(ScreenShot::Ptr m_shot); + + void init() override; private: - ScreenShot::Ptr m_shot; - bool finished = true; + virtual QNetworkReply* getReply(QNetworkRequest&) override; + const QFileInfo m_fileInfo; }; diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 690dc917b..7530fdfba 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -478,6 +479,38 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event) #endif option.widget = this; + if (model()->rowCount() == 0) { + painter.save(); + const QString line1 = tr("Welcome!"); + const QString line2 = tr("Click \"Add Instance\" to get started."); + auto rect = this->viewport()->rect(); + auto font = option.font; + font.setPointSize(37); + painter.setFont(font); + auto fm = painter.fontMetrics(); + + if (rect.height() <= (fm.height() * 5) || rect.width() <= fm.horizontalAdvance(line2)) { + auto s = rect.height() / (5. * fm.height()); + auto sx = rect.width() * 1. / fm.horizontalAdvance(line2); + if (s >= sx) + s = sx; + auto ps = font.pointSize() * s; + if (ps <= 0) + ps = 1; + font.setPointSize(ps); + painter.setFont(font); + fm = painter.fontMetrics(); + } + + // text + rect.setTop(rect.top() + fm.height() * 1.5); + painter.drawText(rect, Qt::AlignHCenter, line1); + rect.setTop(rect.top() + fm.height()); + painter.drawText(rect, Qt::AlignHCenter, line2); + painter.restore(); + return; + } + int wpWidth = viewport()->width(); option.rect.setWidth(wpWidth); for (int i = 0; i < m_groups.size(); ++i) { diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 29c835fc1..25f978cea 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -383,20 +383,31 @@ void ScreenshotsPage::on_actionUpload_triggered() QList uploaded; auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network())); + + ProgressDialog dialog(this); + dialog.setSkipButton(true, tr("Abort")); + if (selection.size() < 2) { auto item = selection.at(0); auto info = m_model->fileInfo(item); auto screenshot = std::make_shared(info); job->addNetAction(ImgurUpload::make(screenshot)); - m_uploadActive = true; - ProgressDialog dialog(this); + connect(job.get(), &Task::failed, [this](QString reason) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), reason, QMessageBox::Critical)->show(); + }); + connect(job.get(), &Task::aborted, [this] { + CustomMessageBox::selectable(this, tr("Screenshots upload aborted"), tr("The task has been aborted by the user."), + QMessageBox::Information) + ->show(); + }); - if (dialog.execWithTask(job.get()) != QDialog::Accepted) { - CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); - } else { + m_uploadActive = true; + + if (dialog.execWithTask(job.get()) == QDialog::Accepted) { auto link = screenshot->m_url; QClipboard* clipboard = QApplication::clipboard(); + qDebug() << "ImgurUpload link" << link; clipboard->setText(link); CustomMessageBox::selectable( this, tr("Upload finished"), @@ -417,22 +428,36 @@ void ScreenshotsPage::on_actionUpload_triggered() } SequentialTask task; auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation", APPLICATION->network())); - auto imgurAlbum = ImgurAlbumCreation::make(uploaded); + auto imgurResult = std::make_shared(); + auto imgurAlbum = ImgurAlbumCreation::make(imgurResult, uploaded); albumTask->addNetAction(imgurAlbum); task.addTask(job); task.addTask(albumTask); - m_uploadActive = true; - ProgressDialog prog(this); - if (prog.execWithTask(&task) != QDialog::Accepted) { - CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); - } else { - auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id()); - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(link); - CustomMessageBox::selectable(this, tr("Upload finished"), - tr("The link to the uploaded album has been placed in your clipboard.").arg(link), + + connect(&task, &Task::failed, [this](QString reason) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), reason, QMessageBox::Critical)->show(); + }); + connect(&task, &Task::aborted, [this] { + CustomMessageBox::selectable(this, tr("Screenshots upload aborted"), tr("The task has been aborted by the user."), QMessageBox::Information) - ->exec(); + ->show(); + }); + + m_uploadActive = true; + if (dialog.execWithTask(&task) == QDialog::Accepted) { + if (imgurResult->id.isEmpty()) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + } else { + auto link = QString("https://imgur.com/a/%1").arg(imgurResult->id); + qDebug() << "ImgurUpload link" << link; + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(link); + CustomMessageBox::selectable( + this, tr("Upload finished"), + tr("The link to the uploaded album has been placed in your clipboard.").arg(link), + QMessageBox::Information) + ->exec(); + } } m_uploadActive = false; } diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp index 43ff1c0fe..d46f16b4d 100644 --- a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp @@ -90,7 +90,7 @@ void ImportFTBPage::suggestCurrent() } dialog->setSuggestedPack(selected.name, new PackInstallTask(selected)); - QString editedLogoName = QString("ftb_%1_%2,jpg").arg(selected.name, selected.id); + QString editedLogoName = QString("ftb_%1_%2.jpg").arg(selected.name, QString::number(selected.id)); dialog->setSuggestedIconFromFile(FS::PathCombine(selected.path, "folder.jpg"), editedLogoName); }