diff options
22 files changed, 341 insertions, 559 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cabab7c..7cd0cf86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,14 +59,11 @@ set(Launcher_VERSION_HOTFIX 0) set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.") # Build platform. -set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used by the notification system and to display in the about dialog.") +set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.") # Channel list URL set(Launcher_UPDATER_BASE "" CACHE STRING "Base URL for the updater.") -# Notification URL -set(Launcher_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") - # The metadata server set(Launcher_META_URL "https://meta.polymc.org/v1/" CACHE STRING "URL to fetch Launcher's meta files from.") @@ -170,13 +167,13 @@ if(UNIX AND APPLE) # Mac bundle settings set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}") - set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: Minecraft launcher and management utility.") + set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.polymc.${Launcher_Name}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}.${Launcher_VERSION_BUILD}") set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns) - set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2021 ${Launcher_Copyright}") + set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}") # directories to look for dependencies set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) @@ -48,7 +48,7 @@ If you want to contribute to PolyMC you might find it useful to join our Discord ## Building -If you want to build PolyMC yourself, check [BUILD.md](BUILD.md) for build instructions. +If you want to build PolyMC yourself, check [Build Instructions](https://polymc.org/wiki/development/build-instructions/) for build instructions. ## Code formatting @@ -66,9 +66,15 @@ In general, in order of importance: The translation effort for PolyMC is hosted on [Weblate](https://hosted.weblate.org/projects/polymc/polymc/) and information about translating PolyMC is available at https://github.com/PolyMC/Translations -## Download infomation -To modify download infomation or change packaging infomation send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md) +## Download information +To modify download information or change packaging information send a pull request or issue to the website [Here](https://github.com/PolyMC/polymc.github.io/blob/master/src/download.md) ## Forking/Redistributing/Custom builds policy Do whatever you want, we don't care. Just follow the license. If you have any questions about this feel free to ask in an issue. + +All launcher code is available under the GPL-3 license. + +[Source for the website](https://github.com/PolyMC/polymc.github.io) is hosted under the AGPL-3 License. + +The logo and related assets are under the CC BY-NC-SA 4.0 license. diff --git a/buildconfig/BuildConfig.cpp.in b/buildconfig/BuildConfig.cpp.in index d1bd4d05..6524fb5d 100644 --- a/buildconfig/BuildConfig.cpp.in +++ b/buildconfig/BuildConfig.cpp.in @@ -25,8 +25,6 @@ Config::Config() BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@"; UPDATER_BASE = "@Launcher_UPDATER_BASE@"; - NOTIFICATION_URL = "@Launcher_NOTIFICATION_URL@"; - FULL_VERSION_STR = "@Launcher_VERSION_MAJOR@.@Launcher_VERSION_MINOR@.@Launcher_VERSION_BUILD@"; GIT_COMMIT = "@Launcher_GIT_COMMIT@"; GIT_REFSPEC = "@Launcher_GIT_REFSPEC@"; diff --git a/buildconfig/BuildConfig.h b/buildconfig/BuildConfig.h index cf74b39e..79210505 100644 --- a/buildconfig/BuildConfig.h +++ b/buildconfig/BuildConfig.h @@ -46,13 +46,6 @@ public: /// User-Agent to use for uncached requests. QString USER_AGENT_UNCACHED; - - /// URL for notifications - QString NOTIFICATION_URL; - - /// Used for matching notifications - QString FULL_VERSION_STR; - /// The git commit hash of this build QString GIT_COMMIT; diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c699d840..e0d7ba0a 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -575,9 +575,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("IconTheme", QString("pe_colored")); m_settings->registerSetting("ApplicationTheme", QString("system")); - // Notifications - m_settings->registerSetting("ShownNotifications", QString()); - // Remembered state m_settings->registerSetting("LastUsedGroupForNewInstance", QString()); @@ -1497,7 +1494,7 @@ QString Application::getJarsPath() return FS::PathCombine(m_rootPath, m_jarsPath); } -QString Application::getMSAClientID() +QString Application::getMSAClientID() { QString clientIDOverride = m_settings->get("MSAClientIDOverride").toString(); if (!clientIDOverride.isEmpty()) { diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 86c05651..751b354b 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -174,13 +174,6 @@ add_unit_test(DownloadTask DATA updater/testdata ) -# Rarely used notifications -set(NOTIFICATIONS_SOURCES - # Notifications - short warning messages - notifications/NotificationChecker.h - notifications/NotificationChecker.cpp -) - # Backend for the news bar... there's usually no news. set(NEWS_SOURCES # News System @@ -561,7 +554,6 @@ set(LOGIC_SOURCES ${NET_SOURCES} ${LAUNCH_SOURCES} ${UPDATE_SOURCES} - ${NOTIFICATIONS_SOURCES} ${NEWS_SOURCES} ${MINECRAFT_SOURCES} ${SCREENSHOTS_SOURCES} @@ -791,12 +783,12 @@ SET(LAUNCHER_SOURCES ui/dialogs/NewComponentDialog.h ui/dialogs/NewInstanceDialog.cpp ui/dialogs/NewInstanceDialog.h - ui/dialogs/NotificationDialog.cpp - ui/dialogs/NotificationDialog.h ui/pagedialog/PageDialog.cpp ui/pagedialog/PageDialog.h ui/dialogs/ProgressDialog.cpp ui/dialogs/ProgressDialog.h + ui/dialogs/ReviewMessageBox.cpp + ui/dialogs/ReviewMessageBox.h ui/dialogs/UpdateDialog.cpp ui/dialogs/UpdateDialog.h ui/dialogs/VersionSelectDialog.cpp @@ -893,7 +885,6 @@ qt5_wrap_ui(LAUNCHER_UI ui/dialogs/ProfileSetupDialog.ui ui/dialogs/ProgressDialog.ui ui/dialogs/NewInstanceDialog.ui - ui/dialogs/NotificationDialog.ui ui/dialogs/UpdateDialog.ui ui/dialogs/NewComponentDialog.ui ui/dialogs/ProfileSelectDialog.ui @@ -905,6 +896,7 @@ qt5_wrap_ui(LAUNCHER_UI ui/dialogs/AboutDialog.ui ui/dialogs/LoginDialog.ui ui/dialogs/EditAccountDialog.ui + ui/dialogs/ReviewMessageBox.ui ) qt5_add_resources(LAUNCHER_RESOURCES diff --git a/launcher/notifications/NotificationChecker.cpp b/launcher/notifications/NotificationChecker.cpp deleted file mode 100644 index 10b91691..00000000 --- a/launcher/notifications/NotificationChecker.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "NotificationChecker.h" - -#include <QJsonDocument> -#include <QJsonObject> -#include <QJsonArray> -#include <QDebug> - -#include "net/Download.h" - -#include "Application.h" - -NotificationChecker::NotificationChecker(QObject *parent) - : QObject(parent) -{ -} - -void NotificationChecker::setNotificationsUrl(const QUrl ¬ificationsUrl) -{ - m_notificationsUrl = notificationsUrl; -} - -void NotificationChecker::setApplicationChannel(QString channel) -{ - m_appVersionChannel = channel; -} - -void NotificationChecker::setApplicationFullVersion(QString version) -{ - m_appFullVersion = version; -} - -void NotificationChecker::setApplicationPlatform(QString platform) -{ - m_appPlatform = platform; -} - -QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const -{ - return m_entries; -} - -void NotificationChecker::checkForNotifications() -{ - if (!m_notificationsUrl.isValid()) - { - qCritical() << "Failed to check for notifications. No notifications URL set." - << "If you'd like to use PolyMC's notification system, please pass the " - "URL to CMake at compile time."; - return; - } - if (m_checkJob) - { - return; - } - m_checkJob = new NetJob("Checking for notifications", APPLICATION->network()); - auto entry = APPLICATION->metacache()->resolveEntry("root", "notifications.json"); - entry->setStale(true); - m_checkJob->addNetAction(m_download = Net::Download::makeCached(m_notificationsUrl, entry)); - connect(m_download.get(), &Net::Download::succeeded, this, &NotificationChecker::downloadSucceeded); - m_checkJob->start(); -} - -void NotificationChecker::downloadSucceeded(int) -{ - m_entries.clear(); - - QFile file(m_download->getTargetFilepath()); - if (file.open(QFile::ReadOnly)) - { - QJsonArray root = QJsonDocument::fromJson(file.readAll()).array(); - for (auto it = root.begin(); it != root.end(); ++it) - { - QJsonObject obj = (*it).toObject(); - NotificationEntry entry; - entry.id = obj.value("id").toDouble(); - entry.message = obj.value("message").toString(); - entry.channel = obj.value("channel").toString(); - entry.platform = obj.value("platform").toString(); - entry.from = obj.value("from").toString(); - entry.to = obj.value("to").toString(); - const QString type = obj.value("type").toString("critical"); - if (type == "critical") - { - entry.type = NotificationEntry::Critical; - } - else if (type == "warning") - { - entry.type = NotificationEntry::Warning; - } - else if (type == "information") - { - entry.type = NotificationEntry::Information; - } - if(entryApplies(entry)) - m_entries.append(entry); - } - } - - m_checkJob.reset(); - - emit notificationCheckFinished(); -} - -bool versionLessThan(const QString &v1, const QString &v2) -{ - QStringList l1 = v1.split('.'); - QStringList l2 = v2.split('.'); - while (!l1.isEmpty() && !l2.isEmpty()) - { - int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt(); - int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt(); - if (one != two) - { - return one < two; - } - } - return false; -} - -bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const -{ - bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel; - bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform; - bool fromApplies = - entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from); - bool toApplies = - entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion); - return channelApplies && platformApplies && fromApplies && toApplies; -} diff --git a/launcher/notifications/NotificationChecker.h b/launcher/notifications/NotificationChecker.h deleted file mode 100644 index 0f305f33..00000000 --- a/launcher/notifications/NotificationChecker.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include <QObject> - -#include "net/NetJob.h" -#include "net/Download.h" - -class NotificationChecker : public QObject -{ - Q_OBJECT - -public: - explicit NotificationChecker(QObject *parent = 0); - - void setNotificationsUrl(const QUrl ¬ificationsUrl); - void setApplicationPlatform(QString platform); - void setApplicationChannel(QString channel); - void setApplicationFullVersion(QString version); - - struct NotificationEntry - { - int id; - QString message; - enum - { - Critical, - Warning, - Information - } type; - QString channel; - QString platform; - QString from; - QString to; - }; - - QList<NotificationEntry> notificationEntries() const; - -public -slots: - void checkForNotifications(); - -private -slots: - void downloadSucceeded(int); - -signals: - void notificationCheckFinished(); - -private: - bool entryApplies(const NotificationEntry &entry) const; - -private: - QList<NotificationEntry> m_entries; - QUrl m_notificationsUrl; - NetJob::Ptr m_checkJob; - Net::Download::Ptr m_download; - - QString m_appVersionChannel; - QString m_appPlatform; - QString m_appFullVersion; -}; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 2cb3c7fd..7b758e05 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -59,7 +59,6 @@ #include <net/NetJob.h> #include <net/Download.h> #include <news/NewsChecker.h> -#include <notifications/NotificationChecker.h> #include <tools/BaseProfiler.h> #include <updater/DownloadTask.h> #include <updater/UpdateChecker.h> @@ -82,7 +81,6 @@ #include "ui/dialogs/CopyInstanceDialog.h" #include "ui/dialogs/UpdateDialog.h" #include "ui/dialogs/EditAccountDialog.h" -#include "ui/dialogs/NotificationDialog.h" #include "ui/dialogs/ExportInstanceDialog.h" #include "UpdateController.h" @@ -846,17 +844,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow } } - { - auto checker = new NotificationChecker(); - checker->setNotificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL)); - checker->setApplicationChannel(BuildConfig.VERSION_CHANNEL); - checker->setApplicationPlatform(BuildConfig.BUILD_PLATFORM); - checker->setApplicationFullVersion(BuildConfig.FULL_VERSION_STR); - m_notificationChecker.reset(checker); - connect(m_notificationChecker.get(), &NotificationChecker::notificationCheckFinished, this, &MainWindow::notificationsChanged); - checker->checkForNotifications(); - } - setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString()); // removing this looks stupid @@ -1268,24 +1255,6 @@ QString intListToString(const QList<int> &list) } return slist.join(','); } -void MainWindow::notificationsChanged() -{ - QList<NotificationChecker::NotificationEntry> entries = m_notificationChecker->notificationEntries(); - QList<int> shownNotifications = stringToIntList(APPLICATION->settings()->get("ShownNotifications").toString()); - for (auto it = entries.begin(); it != entries.end(); ++it) - { - NotificationChecker::NotificationEntry entry = *it; - if (!shownNotifications.contains(entry.id)) - { - NotificationDialog dialog(entry, this); - if (dialog.exec() == NotificationDialog::DontShowAgain) - { - shownNotifications.append(entry.id); - } - } - } - APPLICATION->settings()->set("ShownNotifications", intListToString(shownNotifications)); -} void MainWindow::downloadUpdates(GoUpdate::Status status) { diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index bdbe81aa..f2852d78 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -28,7 +28,6 @@ class LaunchController; class NewsChecker; -class NotificationChecker; class QToolButton; class InstanceProxyModel; class LabeledToolButton; @@ -168,8 +167,6 @@ private slots: void updateNotAvailable(); - void notificationsChanged(); - void defaultAccountChanged(); void changeActiveAccount(); @@ -215,7 +212,6 @@ private: KonamiCode * secretEventFilter = nullptr; unique_qobject_ptr<NewsChecker> m_newsChecker; - unique_qobject_ptr<NotificationChecker> m_notificationChecker; InstancePtr m_selectedInstance; QString m_currentInstIcon; diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 23ca8731..a53f93e8 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -5,7 +5,7 @@ #include <InstanceList.h> #include "ProgressDialog.h" -#include "CustomMessageBox.h" +#include "ReviewMessageBox.h" #include <QLayout> #include <QPushButton> @@ -75,27 +75,16 @@ void ModDownloadDialog::confirm() auto keys = modTask.keys(); keys.sort(Qt::CaseInsensitive); - auto info = QString(tr("You're about to download the following mods:")); - info.append("\n\n"); - for(auto task : keys){ - info.append(task); - info.append("\n --> "); - info.append(tr("File name: ")); - info.append(modTask.find(task).value()->getFilename()); - info.append('\n'); - } - - auto confirm_dialog = CustomMessageBox::selectable( + auto confirm_dialog = ReviewMessageBox::create( this, - tr("Confirm mods to download"), - info, - QMessageBox::NoIcon, - QMessageBox::Cancel | QMessageBox::Ok, - QMessageBox::Ok + tr("Confirm mods to download") ); - auto AcceptButton = confirm_dialog->button(QMessageBox::Ok); - connect(AcceptButton, &QPushButton::clicked, this, &ModDownloadDialog::accept); + for(auto task : keys){ + confirm_dialog->appendMod(task, modTask.find(task).value()->getFilename()); + } + + connect(confirm_dialog, &QDialog::accepted, this, &ModDownloadDialog::accept); confirm_dialog->open(); } diff --git a/launcher/ui/dialogs/NotificationDialog.cpp b/launcher/ui/dialogs/NotificationDialog.cpp deleted file mode 100644 index f2a35ae2..00000000 --- a/launcher/ui/dialogs/NotificationDialog.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "NotificationDialog.h" -#include "ui_NotificationDialog.h" - -#include <QTimerEvent> -#include <QStyle> - -NotificationDialog::NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent) : - QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint), - ui(new Ui::NotificationDialog) -{ - ui->setupUi(this); - - QStyle::StandardPixmap icon; - switch (entry.type) - { - case NotificationChecker::NotificationEntry::Critical: - icon = QStyle::SP_MessageBoxCritical; - break; - case NotificationChecker::NotificationEntry::Warning: - icon = QStyle::SP_MessageBoxWarning; - break; - default: - case NotificationChecker::NotificationEntry::Information: - icon = QStyle::SP_MessageBoxInformation; - break; - } - ui->iconLabel->setPixmap(style()->standardPixmap(icon, 0, this)); - ui->messageLabel->setText(entry.message); - - m_dontShowAgainText = tr("Don't show again"); - m_closeText = tr("Close"); - - ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime)); - ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime)); - - startTimer(1000); -} - -NotificationDialog::~NotificationDialog() -{ - delete ui; -} - -void NotificationDialog::timerEvent(QTimerEvent *event) -{ - if (m_dontShowAgainTime > 0) - { - m_dontShowAgainTime--; - if (m_dontShowAgainTime == 0) - { - ui->dontShowAgainBtn->setText(m_dontShowAgainText); - ui->dontShowAgainBtn->setEnabled(true); - } - else - { - ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime)); - } - } - if (m_closeTime > 0) - { - m_closeTime--; - if (m_closeTime == 0) - { - ui->closeBtn->setText(m_closeText); - ui->closeBtn->setEnabled(true); - } - else - { - ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime)); - } - } - - if (m_closeTime == 0 && m_dontShowAgainTime == 0) - { - killTimer(event->timerId()); - } -} - -void NotificationDialog::on_dontShowAgainBtn_clicked() -{ - done(DontShowAgain); -} -void NotificationDialog::on_closeBtn_clicked() -{ - done(Normal); -} diff --git a/launcher/ui/dialogs/NotificationDialog.h b/launcher/ui/dialogs/NotificationDialog.h deleted file mode 100644 index e1cbb9fa..00000000 --- a/launcher/ui/dialogs/NotificationDialog.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef NOTIFICATIONDIALOG_H -#define NOTIFICATIONDIALOG_H - -#include <QDialog> - -#include "notifications/NotificationChecker.h" - -namespace Ui { -class NotificationDialog; -} - -class NotificationDialog : public QDialog -{ - Q_OBJECT - -public: - explicit NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent = 0); - ~NotificationDialog(); - - enum ExitCode - { - Normal, - DontShowAgain - }; - -protected: - void timerEvent(QTimerEvent *event); - -private: - Ui::NotificationDialog *ui; - - int m_dontShowAgainTime = 10; - int m_closeTime = 5; - - QString m_dontShowAgainText; - QString m_closeText; - -private -slots: - void on_dontShowAgainBtn_clicked(); - void on_closeBtn_clicked(); -}; - -#endif // NOTIFICATIONDIALOG_H diff --git a/launcher/ui/dialogs/NotificationDialog.ui b/launcher/ui/dialogs/NotificationDialog.ui deleted file mode 100644 index 3e6c22bc..00000000 --- a/launcher/ui/dialogs/NotificationDialog.ui +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>NotificationDialog</class> - <widget class="QDialog" name="NotificationDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>320</width> - <height>240</height> - </rect> - </property> - <property name="windowTitle"> - <string>Notification</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1"> - <item> - <widget class="QLabel" name="iconLabel"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="messageLabel"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextBrowserInteraction</set> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="dontShowAgainBtn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Don't show again</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="closeBtn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp new file mode 100644 index 00000000..2bfd02e0 --- /dev/null +++ b/launcher/ui/dialogs/ReviewMessageBox.cpp @@ -0,0 +1,31 @@ +#include "ReviewMessageBox.h" +#include "ui_ReviewMessageBox.h" + +ReviewMessageBox::ReviewMessageBox(QWidget* parent, QString const& title, QString const& icon) + : QDialog(parent), ui(new Ui::ReviewMessageBox) +{ + ui->setupUi(this); +} + +ReviewMessageBox::~ReviewMessageBox() +{ + delete ui; +} + +auto ReviewMessageBox::create(QWidget* parent, QString&& title, QString&& icon) -> ReviewMessageBox* +{ + return new ReviewMessageBox(parent, title, icon); +} + +void ReviewMessageBox::appendMod(const QString& name, const QString& filename) +{ + auto itemTop = new QTreeWidgetItem(ui->modTreeWidget); + itemTop->setText(0, name); + + auto filenameItem = new QTreeWidgetItem(itemTop); + filenameItem->setText(0, tr("Filename: %1").arg(filename)); + + itemTop->insertChildren(0, { filenameItem }); + + ui->modTreeWidget->addTopLevelItem(itemTop); +} diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h new file mode 100644 index 00000000..48742cd9 --- /dev/null +++ b/launcher/ui/dialogs/ReviewMessageBox.h @@ -0,0 +1,23 @@ +#pragma once + +#include <QDialog> + +namespace Ui { +class ReviewMessageBox; +} + +class ReviewMessageBox final : public QDialog { + Q_OBJECT + + public: + static auto create(QWidget* parent, QString&& title, QString&& icon = "") -> ReviewMessageBox*; + + void appendMod(const QString& name, const QString& filename); + + ~ReviewMessageBox(); + + private: + ReviewMessageBox(QWidget* parent, const QString& title, const QString& icon); + + Ui::ReviewMessageBox* ui; +}; diff --git a/launcher/ui/dialogs/ReviewMessageBox.ui b/launcher/ui/dialogs/ReviewMessageBox.ui new file mode 100644 index 00000000..d04f3b3f --- /dev/null +++ b/launcher/ui/dialogs/ReviewMessageBox.ui @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ReviewMessageBox</class> + <widget class="QDialog" name="ReviewMessageBox"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Confirm mod selection</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>You're about to download the following mods:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QTreeWidget" name="modTreeWidget"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectItems</enum> + </property> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string/> + </property> + </column> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ReviewMessageBox</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>200</x> + <y>265</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>149</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ReviewMessageBox</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>200</x> + <y>265</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>149</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index cec496dc..ee68cd08 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -234,11 +234,6 @@ void LauncherPage::applySettings() { auto s = APPLICATION->settings(); - if (ui->resetNotificationsBtn->isChecked()) - { - s->set("ShownNotifications", QString()); - } - // Updates s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); s->set("UpdateChannel", m_currentUpdateChannel); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index 59096a28..c110dd09 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -185,25 +185,6 @@ </attribute> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Launcher notifications</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QPushButton" name="resetNotificationsBtn"> - <property name="text"> - <string>Reset hidden notifications</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> <widget class="QGroupBox" name="sortingModeBox"> <property name="enabled"> <bool>true</bool> @@ -499,7 +480,6 @@ <tabstop>modsDirBrowseBtn</tabstop> <tabstop>iconsDirTextBox</tabstop> <tabstop>iconsDirBrowseBtn</tabstop> - <tabstop>resetNotificationsBtn</tabstop> <tabstop>sortLastLaunchedBtn</tabstop> <tabstop>sortByNameBtn</tabstop> <tabstop>themeComboBox</tabstop> diff --git a/program_info/polymc-header-black.svg b/program_info/polymc-header-black.svg index 34cda4ab..e9e7c3e2 100644 --- a/program_info/polymc-header-black.svg +++ b/program_info/polymc-header-black.svg @@ -1,31 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg width="1424" height="512" version="1.1" viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home"> <defs> - <linearGradient id="linearGradient84726" x1="4.4979" x2="12.435" y1="3.8011" y2="9.5681" gradientUnits="userSpaceOnUse"> + <linearGradient id="a" x1="4.498" x2="12.435" y1="3.801" y2="9.568" gradientUnits="userSpaceOnUse"> <stop stop-color="#88b858" offset="0"/> <stop stop-color="#72b147" offset=".5"/> <stop stop-color="#5a9a30" offset="1"/> </linearGradient> </defs> - <g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)"> - <g> - <path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#765338"/> - <path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/> - <path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/> - <path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#72b147"/> - <path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#5a9a30"/> - <path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#88b858"/> - <path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/> + <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/> + <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/> + <path d="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/> + <path d="m79 95.709-2.53 1.84-2.532-1.84c0-1.84 2.531-1.84 2.531-1.84s2.531 0 2.531 1.84z" fill="#72b147"/> + <path d="M76.47 93.872s0-40.121 55.165-40.121l-1.564 4.819-6.384 8.324-6.384.962-6.383 8.324-6.384.961-6.384 8.325-6.384.961-6.384 8.324-6.383.962z" fill="#5a9a30"/> + <path d="m73.938 95.709-6.383-.961-6.384-8.325-6.384-.961-6.384-8.324-6.384-.962-6.383-8.324-6.384-.962-6.384-8.324-1.564-4.819c55.165 0 55.165 40.121 55.165 40.121z" fill="#88b858"/> + <path d="m.53 6.685 7.937 5.766 7.937-5.766L8.467.918z" fill="url(#a)" transform="matrix(6.95 0 0 6.9572 17.626 7.241)"/> + <path d="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/> + <g fill="#000" stroke-width=".265" aria-label="PolyMC"> + <g stroke-width=".01" aria-label="PolyMC"> + <path d="M168.153 47.323q5.434 0 9.287 1.858 3.852 1.788 5.916 5.228 2.133 3.44 2.133 8.324 0 2.958-.895 5.847-.894 2.82-2.889 5.16-1.926 2.27-5.09 3.646t-7.705 1.375h-7.361v18.3h-6.673V47.322zm.688 25.041q2.958 0 4.884-.963 1.927-.963 3.027-2.408 1.1-1.513 1.582-3.164.482-1.651.482-2.958 0-1.514-.482-3.096-.481-1.651-1.65-2.958-1.101-1.376-2.959-2.202-1.788-.894-4.471-.894h-7.705v18.643zM187.49 82.6q0-4.265 1.994-7.705 2.064-3.44 5.641-5.434 3.577-1.995 8.118-1.995 4.678 0 8.186 1.995 3.509 1.995 5.435 5.434 1.926 3.44 1.926 7.705t-1.926 7.773q-1.926 3.44-5.503 5.435-3.509 1.995-8.187 1.995-4.54 0-8.118-1.857-3.508-1.927-5.572-5.298-1.995-3.44-1.995-8.048zm6.397.07q0 2.751 1.238 5.021 1.238 2.202 3.302 3.509 2.133 1.307 4.678 1.307 2.683 0 4.747-1.307 2.133-1.307 3.302-3.509 1.17-2.27 1.17-5.022 0-2.752-1.17-4.953-1.17-2.27-3.302-3.577-2.064-1.376-4.747-1.376-2.614 0-4.747 1.376-2.063 1.376-3.302 3.646-1.17 2.201-1.17 4.884zM223.251 43.858h6.398v53.246h-6.398zM238.914 110.808l18.78-42.17h5.917l-18.368 42.17zm7.017-13.484-13.69-28.687h7.223l11.489 25.453zM266.775 97.085V51.2h.063l23.855 33.774-3.043-.67L311.384 51.2h.122v45.885h-7.06v-29.88l.487 3.59-16.065 22.7h-.122l-16.31-22.7 1.218-3.286v29.576zM352.299 93.62q-.974.67-2.921 1.643-1.887.973-4.564 1.704-2.617.67-5.843.608-5.172-.062-9.31-1.825-4.138-1.826-6.999-4.869-2.86-3.104-4.442-7.06-1.522-4.016-1.522-8.52 0-5.05 1.583-9.25t4.503-7.241q2.921-3.104 6.938-4.808 4.016-1.704 8.763-1.704 4.199 0 7.485 1.156 3.347 1.096 5.598 2.496l-2.799 6.633q-1.704-1.156-4.26-2.313-2.556-1.156-5.781-1.156-2.921 0-5.599 1.217-2.678 1.156-4.686 3.347-2.008 2.13-3.225 4.99-1.156 2.86-1.156 6.208 0 3.468 1.034 6.39 1.096 2.92 3.043 5.05 2.008 2.07 4.747 3.287 2.799 1.156 6.268 1.156 3.408 0 5.964-1.035 2.616-1.095 4.199-2.434z"/> </g> - <path d="m0.75424 7.3773-0.22507-0.69269 7.9375 5.7669 7.9375-5.7669-0.22507 0.69269-7.7124 5.6034z" fill-opacity="0"/> - </g> - <g id="polymc-header-text" fill="black" transform="matrix(6.9306 0 0 6.9306 -702.9 -659.02)" stroke-width=".26458" aria-label="PolyMC"> - <path d="m120.51 108.48v2.7957h-1.3074v-7.5241h2.8784q1.2609 0 1.9999 0.65629 0.74414 0.65629 0.74414 1.7363 0 1.1059-0.72864 1.7208-0.72346 0.61495-2.0309 0.61495zm0-1.049h1.571q0.69763 0 1.0645-0.32556 0.3669-0.33073 0.3669-0.95084 0-0.60978-0.37207-0.97152-0.37207-0.3669-1.0232-0.37723h-1.6071z"/> - <path d="m125.55 108.43q0-0.82165 0.32556-1.4779 0.32556-0.66145 0.91467-1.0128 0.58911-0.35657 1.3539-0.35657 1.1317 0 1.8345 0.72864 0.70797 0.72863 0.76481 1.9327l5e-3 0.29455q0 0.82682-0.32039 1.478-0.31523 0.65112-0.9095 1.0077-0.58911 0.35657-1.3643 0.35657-1.1834 0-1.8965-0.78548-0.70796-0.79065-0.70796-2.1032zm1.2557 0.10852q0 0.863 0.35657 1.3539 0.35656 0.48576 0.99218 0.48576t0.98702-0.49609q0.35657-0.49609 0.35657-1.4521 0-0.84749-0.36691-1.3436-0.36173-0.49609-0.98701-0.49609-0.61495 0-0.97668 0.49092-0.36174 0.48576-0.36174 1.4573z"/> - <path d="m133.14 111.27h-1.2557v-7.9375h1.2557z"/> - <path d="m136.46 109.47 1.1369-3.793h1.3384l-2.2221 6.4389q-0.5116 1.4108-1.7363 1.4108-0.27388 0-0.60461-0.093v-0.97151l0.23771 0.0155q0.47542 0 0.71314-0.1757 0.24287-0.17053 0.3824-0.57877l0.18087-0.48059-1.9637-5.5655h1.3539z"/> - <path d="m141.48 103.75 2.1704 5.7671 2.1652-5.7671h1.6898v7.5241h-1.3022v-2.4805l0.12919-3.3176-2.2221 5.7981h-0.93534l-2.2169-5.7929 0.12919 3.3124v2.4805h-1.3022v-7.5241z"/> - <path d="m154.79 108.82q-0.11369 1.2041-0.88883 1.881-0.77515 0.67179-2.0619 0.67179-0.89916 0-1.5865-0.42375-0.68212-0.42891-1.0542-1.2144t-0.38758-1.8242v-0.7028q0-1.0645 0.37724-1.8758 0.37724-0.81131 1.08-1.2506 0.70797-0.43925 1.633-0.43925 1.2454 0 2.005 0.67696 0.75965 0.67696 0.88367 1.912h-1.3022q-0.093-0.81132-0.47543-1.1679-0.37723-0.36174-1.111-0.36174-0.85265 0-1.3126 0.62529-0.45475 0.62011-0.46509 1.8242v0.66662q0 1.2196 0.43408 1.8604 0.43925 0.64078 1.2816 0.64078 0.76998 0 1.1576-0.34623t0.49093-1.1524z"/> </g> </svg> diff --git a/program_info/polymc-header.Source.svg b/program_info/polymc-header.Source.svg new file mode 100644 index 00000000..c960f33b --- /dev/null +++ b/program_info/polymc-header.Source.svg @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="1424" + height="512" + version="1.1" + viewBox="0 0 376.77 135.47" + id="svg866" + sodipodi:docname="PolyMC-Header.Source.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview868" + pagecolor="#343434" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="0.61938202" + inkscape:cx="534.40363" + inkscape:cy="299.49206" + inkscape:window-width="2560" + inkscape:window-height="1382" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg866" /> + <defs + id="defs831"> + <linearGradient + id="linearGradient84726" + x1="4.4979" + x2="12.435" + y1="3.8011" + y2="9.5681" + gradientUnits="userSpaceOnUse"> + <stop + stop-color="#88b858" + offset="0" + id="stop824" /> + <stop + stop-color="#72b147" + offset=".5" + id="stop826" /> + <stop + stop-color="#5a9a30" + offset="1" + id="stop828" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient84726" + id="linearGradient1147" + gradientUnits="userSpaceOnUse" + x1="4.4979" + y1="3.8011" + x2="12.435" + y2="9.5681" /> + </defs> + <g + id="g1157"> + <g + transform="matrix(6.95,0,0,6.9572,17.626477,7.241195)" + id="g1322"> + <g + id="g1318"> + <path + d="m 3.561,16.016 c 0,0 0,-3.5642 4.9056,-3.5642 4.9069,0 4.9056,3.5642 4.9056,3.5642 z" + fill="#765338" + id="path1304" /> + <path + d="M 8.4667,12.452 3.5611,16.0162 0.5292,6.6851 Z" + fill="#b7835a" + id="path1306" /> + <path + d="m 8.4667,12.452 7.9375,-5.7669 -3.0319,9.3311 z" + fill="#5b422d" + id="path1308" /> + <path + d="M 8.8308,12.716 8.46663,12.98058 8.10246,12.716 c 0,-0.26458 0.36417,-0.26458 0.36417,-0.26458 0,0 0.36417,0 0.36417,0.26458 z" + fill="#72b147" + id="path1310" /> + <path + d="m 8.4667,12.452 c 0,0 -2e-7,-5.7669 7.9375,-5.7669 l -0.22507,0.69269 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 -0.91853,1.1965 -0.91853,0.13819 z" + fill="#5a9a30" + id="path1312" /> + <path + d="M 8.1025,12.716 7.18397,12.57781 6.26544,11.38131 5.34691,11.24312 4.42838,10.04662 3.50985,9.90843 2.59132,8.71193 1.67279,8.57374 0.75426,7.37724 0.52919,6.68455 c 7.9375,1e-7 7.9375,5.7669 7.9375,5.7669 z" + fill="#88b858" + id="path1314" /> + <path + d="m 0.52917,6.6846 7.9375,5.7669 7.9375,-5.7669 -7.9375,-5.7669 z" + fill="url(#linearGradient84726)" + id="path1316" + style="fill:url(#linearGradient1147)" /> + </g> + <path + d="m 0.75424,7.3773 -0.22507,-0.69269 7.9375,5.7669 7.9375,-5.7669 -0.22507,0.69269 -7.7124,5.6034 z" + fill-opacity="0" + id="path1320" /> + </g> + <g + id="polymc-header-text-3" + fill="white" + transform="matrix(6.9306,0,0,6.9306,-695.39957,-649.40511)" + stroke-width="0.26458" + aria-label="PolyMC" + style="fill:#ffffff;fill-opacity:1"> + <text + xml:space="preserve" + style="font-size:9.92603px;line-height:1.25;font-family:sans-serif;letter-spacing:-0.610833px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke-width:0.0101009" + x="121.65298" + y="107.71044" + id="text4534"><tspan + sodipodi:role="line" + id="tspan4532" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.92603px;font-family:'Josefin Sans';-inkscape-font-specification:'Josefin Sans';fill:#ffffff;fill-opacity:1;stroke-width:0.0101009" + x="121.65298" + y="107.71044">Poly<tspan + style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:8.78072px;font-family:'Josefin Sans';-inkscape-font-specification:'Josefin Sans Semi-Bold'" + id="tspan137828" + rotate="0 0">MC</tspan></tspan></text> + </g> + </g> + <g + id="polymc-header-text-4" + fill="white" + transform="matrix(6.9306,0,0,6.9306,-697.30938,-585.54339)" + stroke-width="0.26458" + aria-label="PolyMC" + style="fill:#ffffff;fill-opacity:1" /> +</svg> diff --git a/program_info/polymc-header.svg b/program_info/polymc-header.svg index a896787f..837004e1 100644 --- a/program_info/polymc-header.svg +++ b/program_info/polymc-header.svg @@ -1,31 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> -<svg width="1424" height="512" version="1.1" viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +<svg viewBox="0 0 376.77 135.47" xmlns="http://www.w3.org/2000/svg" class="home"> <defs> - <linearGradient id="linearGradient84726" x1="4.4979" x2="12.435" y1="3.8011" y2="9.5681" gradientUnits="userSpaceOnUse"> + <linearGradient id="a" x1="4.498" x2="12.435" y1="3.801" y2="9.568" gradientUnits="userSpaceOnUse"> <stop stop-color="#88b858" offset="0"/> <stop stop-color="#72b147" offset=".5"/> <stop stop-color="#5a9a30" offset="1"/> </linearGradient> </defs> - <g transform="matrix(6.95 0 0 6.9572 3.7759 1.0225)"> - <g> - <path d="m3.561 16.016s0-3.5642 4.9056-3.5642c4.9069 0 4.9056 3.5642 4.9056 3.5642z" fill="#765338"/> - <path d="m8.4667 12.452-4.9056 3.5642-3.0319-9.3311z" fill="#b7835a"/> - <path d="m8.4667 12.452 7.9375-5.7669-3.0319 9.3311z" fill="#5b422d"/> - <path d="m8.8308 12.716-0.36417 0.26458-0.36417-0.26458c0-0.26458 0.36417-0.26458 0.36417-0.26458s0.36417 0 0.36417 0.26458z" fill="#72b147"/> - <path d="m8.4667 12.452s-2e-7 -5.7669 7.9375-5.7669l-0.22507 0.69269-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819-0.91853 1.1965-0.91853 0.13819z" fill="#5a9a30"/> - <path d="m8.1025 12.716-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.91853-0.13819-0.91853-1.1965-0.22507-0.69269c7.9375 1e-7 7.9375 5.7669 7.9375 5.7669z" fill="#88b858"/> - <path d="m0.52917 6.6846 7.9375 5.7669 7.9375-5.7669-7.9375-5.7669z" fill="url(#linearGradient84726)"/> + <path d="M42.375 118.668s0-24.797 34.094-24.797c34.103 0 34.094 24.797 34.094 24.797z" fill="#765338"/> + <path d="M76.47 93.872 42.376 118.67 21.304 53.751z" fill="#b7835a"/> + <path d="m76.47 93.872 55.165-40.121-21.072 64.918z" fill="#5b422d"/> + <path d="m79 95.709-2.53 1.84-2.532-1.84c0-1.84 2.531-1.84 2.531-1.84s2.531 0 2.531 1.84z" fill="#72b147"/> + <path d="M76.47 93.872s0-40.121 55.165-40.121l-1.564 4.819-6.384 8.324-6.384.962-6.383 8.324-6.384.961-6.384 8.325-6.384.961-6.384 8.324-6.383.962z" fill="#5a9a30"/> + <path d="m73.938 95.709-6.383-.961-6.384-8.325-6.384-.961-6.384-8.324-6.384-.962-6.383-8.324-6.384-.962-6.384-8.324-1.564-4.819c55.165 0 55.165 40.121 55.165 40.121z" fill="#88b858"/> + <path d="m.53 6.685 7.937 5.766 7.937-5.766L8.467.918z" fill="url(#a)" transform="matrix(6.95 0 0 6.9572 17.626 7.241)"/> + <path d="m22.868 58.567-1.564-4.82L76.469 93.87l55.166-40.122-1.564 4.82L76.47 97.55z" fill="none"/> + <g fill="#fff" stroke-width=".265" aria-label="PolyMC"> + <g stroke-width=".01" aria-label="PolyMC"> + <path d="M168.153 47.323q5.434 0 9.287 1.858 3.852 1.788 5.916 5.228 2.133 3.44 2.133 8.324 0 2.958-.895 5.847-.894 2.82-2.889 5.16-1.926 2.27-5.09 3.646t-7.705 1.375h-7.361v18.3h-6.673V47.322zm.688 25.041q2.958 0 4.884-.963 1.927-.963 3.027-2.408 1.1-1.513 1.582-3.164.482-1.651.482-2.958 0-1.514-.482-3.096-.481-1.651-1.65-2.958-1.101-1.376-2.959-2.202-1.788-.894-4.471-.894h-7.705v18.643zM187.49 82.6q0-4.265 1.994-7.705 2.064-3.44 5.641-5.434 3.577-1.995 8.118-1.995 4.678 0 8.186 1.995 3.509 1.995 5.435 5.434 1.926 3.44 1.926 7.705t-1.926 7.773q-1.926 3.44-5.503 5.435-3.509 1.995-8.187 1.995-4.54 0-8.118-1.857-3.508-1.927-5.572-5.298-1.995-3.44-1.995-8.048zm6.397.07q0 2.751 1.238 5.021 1.238 2.202 3.302 3.509 2.133 1.307 4.678 1.307 2.683 0 4.747-1.307 2.133-1.307 3.302-3.509 1.17-2.27 1.17-5.022 0-2.752-1.17-4.953-1.17-2.27-3.302-3.577-2.064-1.376-4.747-1.376-2.614 0-4.747 1.376-2.063 1.376-3.302 3.646-1.17 2.201-1.17 4.884zM223.251 43.858h6.398v53.246h-6.398zM238.914 110.808l18.78-42.17h5.917l-18.368 42.17zm7.017-13.484-13.69-28.687h7.223l11.489 25.453zM266.775 97.085V51.2h.063l23.855 33.774-3.043-.67L311.384 51.2h.122v45.885h-7.06v-29.88l.487 3.59-16.065 22.7h-.122l-16.31-22.7 1.218-3.286v29.576zM352.299 93.62q-.974.67-2.921 1.643-1.887.973-4.564 1.704-2.617.67-5.843.608-5.172-.062-9.31-1.825-4.138-1.826-6.999-4.869-2.86-3.104-4.442-7.06-1.522-4.016-1.522-8.52 0-5.05 1.583-9.25t4.503-7.241q2.921-3.104 6.938-4.808 4.016-1.704 8.763-1.704 4.199 0 7.485 1.156 3.347 1.096 5.598 2.496l-2.799 6.633q-1.704-1.156-4.26-2.313-2.556-1.156-5.781-1.156-2.921 0-5.599 1.217-2.678 1.156-4.686 3.347-2.008 2.13-3.225 4.99-1.156 2.86-1.156 6.208 0 3.468 1.034 6.39 1.096 2.92 3.043 5.05 2.008 2.07 4.747 3.287 2.799 1.156 6.268 1.156 3.408 0 5.964-1.035 2.616-1.095 4.199-2.434z"/> </g> - <path d="m0.75424 7.3773-0.22507-0.69269 7.9375 5.7669 7.9375-5.7669-0.22507 0.69269-7.7124 5.6034z" fill-opacity="0"/> - </g> - <g id="polymc-header-text" fill="white" transform="matrix(6.9306 0 0 6.9306 -702.9 -659.02)" stroke-width=".26458" aria-label="PolyMC"> - <path d="m120.51 108.48v2.7957h-1.3074v-7.5241h2.8784q1.2609 0 1.9999 0.65629 0.74414 0.65629 0.74414 1.7363 0 1.1059-0.72864 1.7208-0.72346 0.61495-2.0309 0.61495zm0-1.049h1.571q0.69763 0 1.0645-0.32556 0.3669-0.33073 0.3669-0.95084 0-0.60978-0.37207-0.97152-0.37207-0.3669-1.0232-0.37723h-1.6071z"/> - <path d="m125.55 108.43q0-0.82165 0.32556-1.4779 0.32556-0.66145 0.91467-1.0128 0.58911-0.35657 1.3539-0.35657 1.1317 0 1.8345 0.72864 0.70797 0.72863 0.76481 1.9327l5e-3 0.29455q0 0.82682-0.32039 1.478-0.31523 0.65112-0.9095 1.0077-0.58911 0.35657-1.3643 0.35657-1.1834 0-1.8965-0.78548-0.70796-0.79065-0.70796-2.1032zm1.2557 0.10852q0 0.863 0.35657 1.3539 0.35656 0.48576 0.99218 0.48576t0.98702-0.49609q0.35657-0.49609 0.35657-1.4521 0-0.84749-0.36691-1.3436-0.36173-0.49609-0.98701-0.49609-0.61495 0-0.97668 0.49092-0.36174 0.48576-0.36174 1.4573z"/> - <path d="m133.14 111.27h-1.2557v-7.9375h1.2557z"/> - <path d="m136.46 109.47 1.1369-3.793h1.3384l-2.2221 6.4389q-0.5116 1.4108-1.7363 1.4108-0.27388 0-0.60461-0.093v-0.97151l0.23771 0.0155q0.47542 0 0.71314-0.1757 0.24287-0.17053 0.3824-0.57877l0.18087-0.48059-1.9637-5.5655h1.3539z"/> - <path d="m141.48 103.75 2.1704 5.7671 2.1652-5.7671h1.6898v7.5241h-1.3022v-2.4805l0.12919-3.3176-2.2221 5.7981h-0.93534l-2.2169-5.7929 0.12919 3.3124v2.4805h-1.3022v-7.5241z"/> - <path d="m154.79 108.82q-0.11369 1.2041-0.88883 1.881-0.77515 0.67179-2.0619 0.67179-0.89916 0-1.5865-0.42375-0.68212-0.42891-1.0542-1.2144t-0.38758-1.8242v-0.7028q0-1.0645 0.37724-1.8758 0.37724-0.81131 1.08-1.2506 0.70797-0.43925 1.633-0.43925 1.2454 0 2.005 0.67696 0.75965 0.67696 0.88367 1.912h-1.3022q-0.093-0.81132-0.47543-1.1679-0.37723-0.36174-1.111-0.36174-0.85265 0-1.3126 0.62529-0.45475 0.62011-0.46509 1.8242v0.66662q0 1.2196 0.43408 1.8604 0.43925 0.64078 1.2816 0.64078 0.76998 0 1.1576-0.34623t0.49093-1.1524z"/> </g> </svg> |