From 25ffc4c4b0239ba782a5d10397965a6a61885d82 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 29 Jun 2023 17:58:09 +0300 Subject: [PATCH 01/16] Refactor ImgurUpload Signed-off-by: Trial97 --- launcher/CMakeLists.txt | 1 + launcher/net/NetRequest.cpp | 2 + launcher/net/StaticHeaderProxy.h | 39 ++++++ launcher/screenshots/ImgurAlbumCreation.cpp | 123 ++++++++---------- launcher/screenshots/ImgurAlbumCreation.h | 60 ++++----- launcher/screenshots/ImgurUpload.cpp | 119 +++++++---------- launcher/screenshots/ImgurUpload.h | 47 ++++--- .../ui/pages/instance/ScreenshotsPage.cpp | 70 ++++------ 8 files changed, 224 insertions(+), 237 deletions(-) create mode 100644 launcher/net/StaticHeaderProxy.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 44988db20..e5fb815c3 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/net/NetRequest.cpp b/launcher/net/NetRequest.cpp index 304577121..35072d355 100644 --- a/launcher/net/NetRequest.cpp +++ b/launcher/net/NetRequest.cpp @@ -111,6 +111,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 ab425f1a0..c9d73b8d4 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -36,96 +36,79 @@ #include "ImgurAlbumCreation.h" -#include +#include #include #include -#include +#include +#include #include -#include +#include +#include #include "BuildConfig.h" -#include "Application.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) - { + 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(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; + 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; } - else - { - qDebug() << m_reply->readAll(); - m_reply.reset(); - emitFailed(); - return; + auto object = doc.object(); + if (!object.value("success").toBool()) { + qDebug() << doc.toJson(); + return Task::State::Failed; } -} - -void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - setProgress(bytesReceived, bytesTotal); - emit progress(bytesReceived, bytesTotal); -} + 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 a2b70d8b0..670c35eb3 100644 --- a/launcher/screenshots/ImgurAlbumCreation.h +++ b/launcher/screenshots/ImgurAlbumCreation.h @@ -35,44 +35,40 @@ #pragma once -#include "net/NetAction.h" #include "Screenshot.h" +#include "net/NetRequest.h" -typedef shared_qobject_ptr ImgurAlbumCreationPtr; -class ImgurAlbumCreation : public NetAction -{ -public: - explicit ImgurAlbumCreation(QList screenshots); - static ImgurAlbumCreationPtr make(QList screenshots) - { - return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); - } +class ImgurAlbumCreation : public Net::NetRequest { + public: + 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; + }; -private: + 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 a50f9afae..5213d2d71 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -36,120 +36,95 @@ #include "ImgurUpload.h" #include "BuildConfig.h" -#include "Application.h" +#include "net/StaticHeaderProxy.h" -#include +#include +#include #include +#include #include #include -#include -#include +#include #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); + 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(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); - if (jsonError.error != QJsonParseError::NoError) - { + 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()) - { + 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 e8a6d8d70..e99ba3a4a 100644 --- a/launcher/screenshots/ImgurUpload.h +++ b/launcher/screenshots/ImgurUpload.h @@ -35,31 +35,36 @@ #pragma once -#include "net/NetAction.h" +#include #include "Screenshot.h" +#include "net/NetRequest.h" -class ImgurUpload : public NetAction { -public: - using Ptr = shared_qobject_ptr; +class ImgurUpload : public Net::NetRequest { + public: + 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); -private: - ScreenShot::Ptr m_shot; - bool finished = true; + void init() override; + + private: + virtual QNetworkReply* getReply(QNetworkRequest&) override; + const QFileInfo m_fileInfo; }; diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index 352375941..128d79503 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -403,41 +403,37 @@ void ScreenshotsPage::on_actionUpload_triggered() QList uploaded; auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network())); - if(selection.size() < 2) - { + + 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); - if(dialog.execWithTask(job.get()) != QDialog::Accepted) - { - CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), - tr("Unknown error"), QMessageBox::Warning)->exec(); - } - else - { + if (dialog.execWithTask(job.get()) != QDialog::Accepted) { + CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + } else { auto link = screenshot->m_url; - QClipboard *clipboard = QApplication::clipboard(); + QClipboard* clipboard = QApplication::clipboard(); + qDebug() << "ImgurUpload link" << link; clipboard->setText(link); CustomMessageBox::selectable( - this, - tr("Upload finished"), - tr("The link to the uploaded screenshot has been placed in your clipboard.") - .arg(link), - QMessageBox::Information - )->exec(); + this, tr("Upload finished"), + tr("The link to the uploaded screenshot has been placed in your clipboard.").arg(link), + QMessageBox::Information) + ->exec(); } m_uploadActive = false; return; } - for (auto item : selection) - { + for (auto item : selection) { auto info = m_model->fileInfo(item); auto screenshot = std::make_shared(info); uploaded.push_back(screenshot); @@ -445,32 +441,23 @@ 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(); + if (dialog.execWithTask(&task) != QDialog::Accepted || 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(); + 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; } @@ -478,8 +465,7 @@ void ScreenshotsPage::on_actionUpload_triggered() void ScreenshotsPage::on_actionCopy_Image_triggered() { auto selection = ui->listView->selectionModel()->selectedRows(); - if(selection.size() < 1) - { + if (selection.size() < 1) { return; } From 9d0175b81ab702467cd5c707669c12b6bbcb913e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 17:46:00 +0300 Subject: [PATCH 02/16] Added welcome screen Signed-off-by: Trial97 --- launcher/ui/instanceview/InstanceView.cpp | 79 +++++++++++++++++------ 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 1911dd59a..a1acf5875 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -35,32 +35,32 @@ #include "InstanceView.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "VisualGroup.h" #include "ui/themes/ThemeManager.h" -#include #include #include - -template bool listsIntersect(const QList &l1, const QList t2) +template +bool listsIntersect(const QList& l1, const QList t2) { - for (auto &item : l1) - { - if (t2.contains(item)) - { + for (auto& item : l1) { + if (t2.contains(item)) { return true; } } @@ -536,11 +536,50 @@ void InstanceView::paintEvent(QPaintEvent* event) #endif option.widget = this; + if (model()->rowCount() == 0) { + painter.save(); + const QString line1 = "Welcome!"; + const QString line2 = "Add an instance to get started."; + auto rect = this->viewport()->rect(); + auto font = option.font; + font.setPointSize(64); + 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(); + } + // about icon + auto about = QIcon::fromTheme("about"); + QRect aboutRect(0, 0, fm.height() * .75, fm.height() * .75); + aboutRect.moveCenter(rect.center()); + aboutRect.moveTop(fm.height() * .75); + auto px = about.pixmap(about.actualSize(aboutRect.size())); + if (!px.isNull()) + painter.drawPixmap(aboutRect, px); + + // 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) - { - VisualGroup *category = m_groups.at(i); + for (int i = 0; i < m_groups.size(); ++i) { + VisualGroup* category = m_groups.at(i); int y = category->verticalPosition(); y -= verticalOffset(); QRect backup = option.rect; From 7441974d9d22ad8596a52cf9fd70ae5e2e0e721a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 16 Jul 2023 21:23:22 +0300 Subject: [PATCH 03/16] Removed icon Signed-off-by: Trial97 --- launcher/ui/instanceview/InstanceView.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index a1acf5875..9b0022229 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -542,7 +542,7 @@ void InstanceView::paintEvent(QPaintEvent* event) const QString line2 = "Add an instance to get started."; auto rect = this->viewport()->rect(); auto font = option.font; - font.setPointSize(64); + font.setPointSize(53); painter.setFont(font); auto fm = painter.fontMetrics(); @@ -558,14 +558,6 @@ void InstanceView::paintEvent(QPaintEvent* event) painter.setFont(font); fm = painter.fontMetrics(); } - // about icon - auto about = QIcon::fromTheme("about"); - QRect aboutRect(0, 0, fm.height() * .75, fm.height() * .75); - aboutRect.moveCenter(rect.center()); - aboutRect.moveTop(fm.height() * .75); - auto px = about.pixmap(about.actualSize(aboutRect.size())); - if (!px.isNull()) - painter.drawPixmap(aboutRect, px); // text rect.setTop(rect.top() + fm.height() * 1.5); From f5891940e0d8b52b2250b3e5b80532c71c39c7e8 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 17 Jul 2023 17:22:35 +0300 Subject: [PATCH 04/16] translate strings Signed-off-by: Trial97 --- launcher/ui/instanceview/InstanceView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 9b0022229..025382cb7 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -538,8 +538,8 @@ void InstanceView::paintEvent(QPaintEvent* event) if (model()->rowCount() == 0) { painter.save(); - const QString line1 = "Welcome!"; - const QString line2 = "Add an instance to get started."; + const QString line1 = tr("Welcome!"); + const QString line2 = tr("Add an instance to get started."); auto rect = this->viewport()->rect(); auto font = option.font; font.setPointSize(53); From 72de2d5254babb209b478ed5e9d7c4e1019d7459 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 5 Aug 2023 21:08:16 +0300 Subject: [PATCH 05/16] Added missing header Signed-off-by: Trial97 --- launcher/meta/BaseEntity.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/meta/BaseEntity.cpp b/launcher/meta/BaseEntity.cpp index 38e7f600d..18686acf6 100644 --- a/launcher/meta/BaseEntity.cpp +++ b/launcher/meta/BaseEntity.cpp @@ -15,6 +15,7 @@ #include "BaseEntity.h" +#include "Json.h" #include "net/ApiDownload.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" From f7e8ec1855f26052420694f873ee7e3c167f7545 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 5 Aug 2023 21:17:38 +0300 Subject: [PATCH 06/16] format files Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameAPI.cpp | 6 +++--- .../modplatform/modrinth/ModrinthInstanceCreationTask.cpp | 2 +- launcher/modplatform/technic/SolderPackInstallTask.cpp | 2 +- launcher/ui/pages/modplatform/flame/FlamePage.cpp | 3 ++- launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp | 2 +- launcher/ui/widgets/VariableSizedImageObject.cpp | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 7231b4664..73ed10112 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -8,9 +8,9 @@ #include "Application.h" #include "BuildConfig.h" #include "Json.h" +#include "net/ApiDownload.h" #include "net/ApiUpload.h" #include "net/NetJob.h" -#include "net/ApiDownload.h" #include "net/Upload.h" Task::Ptr FlameAPI::matchFingerprints(const QList& fingerprints, std::shared_ptr response) @@ -75,8 +75,8 @@ auto FlameAPI::getModDescription(int modId) -> QString auto netJob = makeShared(QString("Flame::ModDescription"), APPLICATION->network()); auto response = std::make_shared(); - netJob->addNetAction( - Net::ApiDownload::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response)); + netJob->addNetAction(Net::ApiDownload::makeByteArray( + QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response)); QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &description] { QJsonParseError parse_error{}; diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index e0873ce7e..cdbbd42d0 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -11,8 +11,8 @@ #include "net/ChecksumValidator.h" -#include "net/NetJob.h" #include "net/ApiDownload.h" +#include "net/NetJob.h" #include "settings/INISettingsObject.h" #include "ui/dialogs/CustomMessageBox.h" diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index b24604983..c162d6253 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -42,8 +42,8 @@ #include "SolderPackManifest.h" #include "TechnicPackProcessor.h" -#include "net/ChecksumValidator.h" #include "net/ApiDownload.h" +#include "net/ChecksumValidator.h" Technic::SolderPackInstallTask::SolderPackInstallTask(shared_qobject_ptr network, const QUrl& solderUrl, diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp index a87ff8668..9f0e7085c 100644 --- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp @@ -134,7 +134,8 @@ void FlamePage::onSelectionChanged(QModelIndex curr, QModelIndex prev) auto netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name), APPLICATION->network()); auto response = std::make_shared(); int addonId = current.addonId; - netJob->addNetAction(Net::ApiDownload::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/files").arg(addonId), response)); + netJob->addNetAction( + Net::ApiDownload::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/files").arg(addonId), response)); QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId, curr] { if (addonId != current.addonId) { diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 176728ee5..f600e5a78 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -35,9 +35,9 @@ #include "ListModel.h" #include "Application.h" +#include "net/ApiDownload.h" #include "net/HttpMetaCache.h" #include "net/NetJob.h" -#include "net/ApiDownload.h" #include #include "StringUtils.h" diff --git a/launcher/ui/widgets/VariableSizedImageObject.cpp b/launcher/ui/widgets/VariableSizedImageObject.cpp index 51f2966b1..f655fc38d 100644 --- a/launcher/ui/widgets/VariableSizedImageObject.cpp +++ b/launcher/ui/widgets/VariableSizedImageObject.cpp @@ -25,8 +25,8 @@ #include "Application.h" -#include "net/NetJob.h" #include "net/ApiDownload.h" +#include "net/NetJob.h" enum FormatProperties { ImageData = QTextFormat::UserProperty + 1 }; From fecc1e087aefd276a18d7941d123f1f261a6d0d2 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Aug 2023 13:35:50 +0300 Subject: [PATCH 07/16] Add Trial97 to contribuitors list Signed-off-by: Trial97 --- launcher/ui/dialogs/AboutDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 3c6f6ef16..f5eaff7a1 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -85,6 +85,7 @@ QString getCreditsHtml() stream << QString("

TayouVR %1

\n").arg(getGitHub("TayouVR")); stream << QString("

TheKodeToad %1

\n").arg(getGitHub("TheKodeToad")); stream << QString("

getchoo %1

\n").arg(getGitHub("getchoo")); + stream << QString("

Alexandru Tripon (Trial97) %1

\n").arg(getGitHub("Trial97")); stream << "
\n"; // TODO: possibly retrieve from git history at build time? From 79652799bd88299f1e1bdb1b16449fae56c59913 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 27 Aug 2023 21:30:46 +0300 Subject: [PATCH 08/16] Made text smaller Signed-off-by: Trial97 --- launcher/ui/instanceview/InstanceView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp index 11402e58f..7530fdfba 100644 --- a/launcher/ui/instanceview/InstanceView.cpp +++ b/launcher/ui/instanceview/InstanceView.cpp @@ -482,10 +482,10 @@ void InstanceView::paintEvent([[maybe_unused]] QPaintEvent* event) if (model()->rowCount() == 0) { painter.save(); const QString line1 = tr("Welcome!"); - const QString line2 = tr("Add an instance to get started."); + const QString line2 = tr("Click \"Add Instance\" to get started."); auto rect = this->viewport()->rect(); auto font = option.font; - font.setPointSize(53); + font.setPointSize(37); painter.setFont(font); auto fm = painter.fontMetrics(); From 211865a1e1098245228aea75ee70d7e7b60ebd05 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 28 Aug 2023 13:31:19 +0300 Subject: [PATCH 09/16] handle gracefully the upload abort Signed-off-by: Trial97 --- .../ui/pages/instance/ScreenshotsPage.cpp | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp index da56112c1..25f978cea 100644 --- a/launcher/ui/pages/instance/ScreenshotsPage.cpp +++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp @@ -393,11 +393,18 @@ void ScreenshotsPage::on_actionUpload_triggered() auto screenshot = std::make_shared(info); job->addNetAction(ImgurUpload::make(screenshot)); + 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(); + }); + m_uploadActive = true; - if (dialog.execWithTask(job.get()) != QDialog::Accepted) { - CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"), tr("Unknown error"), QMessageBox::Warning)->exec(); - } else { + if (dialog.execWithTask(job.get()) == QDialog::Accepted) { auto link = screenshot->m_url; QClipboard* clipboard = QApplication::clipboard(); qDebug() << "ImgurUpload link" << link; @@ -426,18 +433,31 @@ void ScreenshotsPage::on_actionUpload_triggered() albumTask->addNetAction(imgurAlbum); task.addTask(job); task.addTask(albumTask); - m_uploadActive = true; - if (dialog.execWithTask(&task) != QDialog::Accepted || 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), + + 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; } From dc74ea73825e7997538bc2aa381b284260a40551 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 6 Oct 2023 19:27:26 +0300 Subject: [PATCH 10/16] fixed wrong account selection Signed-off-by: Trial97 --- launcher/LaunchController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From b1bd0ceadef1eeab7e4f5d10f26ba1865f46525e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 17 Oct 2023 09:29:47 +0300 Subject: [PATCH 11/16] fixed code signing for appImage Signed-off-by: Trial97 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7e542d4e5..8077ea59a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -501,7 +501,7 @@ jobs: export SIGN=1 export SIGN_KEY=${{ secrets.GPG_PRIVATE_KEY_ID }} mkdir -p ~/.gnupg/ - printf "$GPG_PRIVATE_KEY" | base64 --decode > ~/.gnupg/private.key + echo "$GPG_PRIVATE_KEY" > ~/.gnupg/private.key gpg --import ~/.gnupg/private.key else echo ":warning: Skipped code signing for Linux AppImage, as gpg key was not present." >> $GITHUB_STEP_SUMMARY From d348f20dd994c7c60510e33d9ec0496d961f45d1 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Tue, 17 Oct 2023 10:00:17 +0200 Subject: [PATCH 12/16] fix: allow loading themes with missing resources folder Signed-off-by: Sefa Eyeoglu --- launcher/ui/themes/CustomTheme.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 29ecf6254..4859983c6 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -165,11 +165,15 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest QString path = FS::PathCombine("themes", m_id); QString pathResources = FS::PathCombine("themes", m_id, "resources"); - if (!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) { - themeWarningLog() << "couldn't create folder for theme!"; + if (!FS::ensureFolderPathExists(path)) { + themeWarningLog() << "Theme directory for" << m_id << "could not be created. This theme might be invalid"; return; } + if (!FS::ensureFolderPathExists(pathResources)) { + themeWarningLog() << "Resources directory for" << m_id << "could not be created"; + } + auto themeFilePath = FS::PathCombine(path, themeFile); bool jsonDataIncomplete = false; @@ -230,7 +234,11 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest QStringList CustomTheme::searchPaths() { - return { FS::PathCombine("themes", m_id, "resources") }; + QString pathResources = FS::PathCombine("themes", m_id, "resources"); + if (QFileInfo::exists(pathResources)) + return { pathResources }; + + return {}; } QString CustomTheme::id() From 069bc887f1f74b9ea29130d33042bafc82d97f57 Mon Sep 17 00:00:00 2001 From: seth Date: Tue, 17 Oct 2023 19:05:05 -0400 Subject: [PATCH 13/16] fix: don't always build updater on platforms besides mac Signed-off-by: seth --- CMakeLists.txt | 5 +++++ launcher/CMakeLists.txt | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be443fe31..faeb1c44e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -347,6 +347,11 @@ add_subdirectory(program_info) ####################################### Install layout ####################################### set(Launcher_ENABLE_UPDATER NO) +set(Launcher_BUILD_UPDATER NO) + +if (NOT APPLE AND (NOT Launcher_UPDATER_GITHUB_REPO STREQUAL "" AND NOT Launcher_BUILD_ARTIFACT STREQUAL "")) + set(Launcher_BUILD_UPDATER YES) +endif() if(NOT (UNIX AND APPLE)) # Install "portable.txt" if selected component is "portable" diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index d15dc85de..19b837a2f 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1306,7 +1306,7 @@ install(TARGETS ${Launcher_Name} FRAMEWORK DESTINATION ${FRAMEWORK_DEST_DIR} COMPONENT Runtime ) -if(NOT APPLE OR (DEFINED Launcher_BUILD_UPDATER AND Launcher_BUILD_UPDATER)) +if(Launcher_BUILD_UPDATER) # Updater add_library(prism_updater_logic STATIC ${PRISMUPDATER_SOURCES} ${TASKS_SOURCES} ${PRISMUPDATER_UI}) target_include_directories(prism_updater_logic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) From 1f2483c39ee980f317aa8a4bcc5ccebe3a02045f Mon Sep 17 00:00:00 2001 From: Indrale Dnyaneshwar <118615488+Dnyanu76@users.noreply.github.com> Date: Fri, 20 Oct 2023 00:31:47 +0530 Subject: [PATCH 14/16] Remove typo Signed-off-by: Indrale Dnyaneshwar <118615488+Dnyanu76@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 80723eeca174afbbb5af31bf422fe7b2a8e8cad3 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 20 Oct 2023 16:41:32 +0300 Subject: [PATCH 15/16] Fixed FTBApp import icon Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); } From e7e80e704f06c4fd73231228fa04d583d427f635 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 22 Oct 2023 00:18:23 +0000 Subject: [PATCH 16/16] chore(nix): update lockfile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'nixpkgs': 'github:nixos/nixpkgs/01441e14af5e29c9d27ace398e6dd0b293e25a54' (2023-10-11) → 'github:nixos/nixpkgs/44881e03af1c730cbb1d72a4d41274a2c957813a' (2023-10-21) • Updated input 'pre-commit-hooks': 'github:cachix/pre-commit-hooks.nix/42e1b6095ef80a51f79595d9951eb38e91c4e6ca' (2023-10-09) → 'github:cachix/pre-commit-hooks.nix/8cc349bfd082da8782b989cad2158c9ad5bd70fd' (2023-10-19) --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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": {