From e204dfdb173da51a486728b1efa7004f186b3f53 Mon Sep 17 00:00:00 2001 From: fourtf Date: Thu, 21 Jun 2018 22:02:35 +0200 Subject: [PATCH] added updating mechanic --- src/singletons/pathmanager.cpp | 2 +- src/singletons/settingsmanager.hpp | 3 + src/singletons/updatemanager.cpp | 66 +++++++++++++++++++++- src/singletons/updatemanager.hpp | 13 ++++- src/widgets/lastruncrashdialog.cpp | 12 +++- src/widgets/logindialog.cpp | 9 ++- src/widgets/settingspages/accountspage.cpp | 2 +- src/widgets/settingspages/commandpage.cpp | 3 +- src/widgets/window.cpp | 16 ++++++ src/widgets/window.hpp | 1 + 10 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/singletons/pathmanager.cpp b/src/singletons/pathmanager.cpp index a473f47a..cb150786 100644 --- a/src/singletons/pathmanager.cpp +++ b/src/singletons/pathmanager.cpp @@ -71,7 +71,7 @@ void PathManager::initAppDataDirectory() this->rootAppDataDirectory = [&]() -> QString { // portable - if (this->portable) { + if (this->isPortable()) { return QCoreApplication::applicationDirPath(); } diff --git a/src/singletons/settingsmanager.hpp b/src/singletons/settingsmanager.hpp index 6120f001..110eebc7 100644 --- a/src/singletons/settingsmanager.hpp +++ b/src/singletons/settingsmanager.hpp @@ -125,6 +125,9 @@ public: QStringSetting preferredQuality = {"/external/streamlink/quality", "Choose"}; QStringSetting streamlinkOpts = {"/external/streamlink/options", ""}; + /// Misc + IntSetting startUpNotification = {"/misc/startUpNotification", 0}; + void updateWordTypeMask(); void saveSnapshot(); diff --git a/src/singletons/updatemanager.cpp b/src/singletons/updatemanager.cpp index ad270db7..9517fb4b 100644 --- a/src/singletons/updatemanager.cpp +++ b/src/singletons/updatemanager.cpp @@ -1,8 +1,12 @@ #include "updatemanager.hpp" +#include "util/combine_path.hpp" #include "util/networkrequest.hpp" #include "version.hpp" +#include +#include + namespace chatterino { namespace singletons { @@ -32,32 +36,90 @@ const QString &UpdateManager::getOnlineVersion() const void UpdateManager::installUpdates() { + if (this->status_ != UpdateAvailable) { + assert(false); + return; + } + +#ifdef Q_OS_WIN + QMessageBox *box = new QMessageBox(QMessageBox::Information, "Chatterino Update", + "Chatterino is downloading the update " + "in the background and will run the " + "updater once it is finished."); + box->setAttribute(Qt::WA_DeleteOnClose); + box->show(); + + util::NetworkRequest req(this->updateUrl_); + req.setTimeout(600000); + req.onError([this](int) -> bool { + this->setStatus_(DownloadFailed); + return true; + }); + req.get([this](QByteArray &object) { + auto filename = util::combinePath(getApp()->paths->miscDirectory, "update.zip"); + + QFile file(filename); + if (file.write(object) == -1) { + this->setStatus_(WriteFileFailed); + return false; + } + + QProcess::startDetached("./updater.1/ChatterinoUpdater.exe", {filename, "restart"}); + + QApplication::exit(0); + return false; + }); + this->setStatus_(Downloading); + req.execute(); +#endif } void UpdateManager::checkForUpdates() { +#ifdef Q_OS_WIN QString url = "https://notitia.chatterino.com/version/chatterino/" CHATTERINO_OS "/stable"; util::NetworkRequest req(url); req.setTimeout(30000); req.getJSON([this](QJsonObject &object) { QJsonValue version_val = object.value("version"); - if (!version_val.isString()) { - this->setStatus_(Error); + QJsonValue update_val = object.value("update"); + + if (!version_val.isString() || !update_val.isString()) { + this->setStatus_(SearchFailed); qDebug() << "error updating"; + + QMessageBox *box = + new QMessageBox(QMessageBox::Information, "Chatterino Update", + "Error while searching for updates.\n\nEither the service is down " + "temporarily or everything is broken."); + box->setAttribute(Qt::WA_DeleteOnClose); + box->show(); return; } this->onlineVersion_ = version_val.toString(); + this->updateUrl_ = update_val.toString(); if (this->currentVersion_ != this->onlineVersion_) { this->setStatus_(UpdateAvailable); + + QMessageBox *box = new QMessageBox(QMessageBox::Information, "Chatterino Update", + "An update for chatterino is available.\n\nDo you " + "want to download and install it?", + QMessageBox::Yes | QMessageBox::No); + box->setAttribute(Qt::WA_DeleteOnClose); + box->show(); + if (box->exec() == QMessageBox::Yes) { + this->installUpdates(); + } } else { this->setStatus_(NoUpdateAvailable); } }); this->setStatus_(Searching); req.execute(); +#endif } UpdateManager::UpdateStatus UpdateManager::getStatus() const diff --git a/src/singletons/updatemanager.hpp b/src/singletons/updatemanager.hpp index 365bc21f..f188422e 100644 --- a/src/singletons/updatemanager.hpp +++ b/src/singletons/updatemanager.hpp @@ -11,7 +11,16 @@ class UpdateManager UpdateManager(); public: - enum UpdateStatus { None, Searching, UpdateAvailable, NoUpdateAvailable, Error }; + enum UpdateStatus { + None, + Searching, + UpdateAvailable, + NoUpdateAvailable, + SearchFailed, + Downloading, + DownloadFailed, + WriteFileFailed, + }; // fourtf: don't add this class to the application class static UpdateManager &getInstance(); @@ -29,6 +38,8 @@ private: QString onlineVersion_; UpdateStatus status_ = None; + QString updateUrl_; + void setStatus_(UpdateStatus status); }; diff --git a/src/widgets/lastruncrashdialog.cpp b/src/widgets/lastruncrashdialog.cpp index 06f43acc..925d7b10 100644 --- a/src/widgets/lastruncrashdialog.cpp +++ b/src/widgets/lastruncrashdialog.cpp @@ -59,10 +59,20 @@ LastRunCrashDialog::LastRunCrashDialog() case singletons::UpdateManager::NoUpdateAvailable: { update->setText("No update abailable."); } break; - case singletons::UpdateManager::Error: { + case singletons::UpdateManager::SearchFailed: { update->setText("Error while searching for update.\nEither the update service is " "temporarily down or there is an issue with your installation."); } break; + case singletons::UpdateManager::Downloading: { + update->setText( + "Downloading the update. Chatterino will close once the download is done."); + } break; + case singletons::UpdateManager::DownloadFailed: { + update->setText("Download failed."); + } break; + case singletons::UpdateManager::WriteFileFailed: { + update->setText("Writing the update file to the hard drive failed."); + } break; } }; diff --git a/src/widgets/logindialog.cpp b/src/widgets/logindialog.cpp index 961522e4..cccac45e 100644 --- a/src/widgets/logindialog.cpp +++ b/src/widgets/logindialog.cpp @@ -56,6 +56,8 @@ void LogInWithCredentials(const std::string &userID, const std::string &username getApp()->accounts->twitch.reloadUsers(); // messageBox.exec(); + + getApp()->accounts->twitch.currentUsername = username; } } // namespace @@ -77,7 +79,7 @@ BasicLoginWidget::BasicLoginWidget() QDesktopServices::openUrl(QUrl("https://chatterino.com/client_login")); }); - connect(&this->ui.pasteCodeButton, &QPushButton::clicked, []() { + connect(&this->ui.pasteCodeButton, &QPushButton::clicked, [this]() { QClipboard *clipboard = QGuiApplication::clipboard(); QString clipboardString = clipboard->text(); QStringList parameters = clipboardString.split(';'); @@ -108,6 +110,7 @@ BasicLoginWidget::BasicLoginWidget() LogInWithCredentials(userID, username, clientID, oauthToken); clipboard->clear(); + this->window()->close(); }); } @@ -191,7 +194,7 @@ void AdvancedLoginWidget::refreshButtons() LoginWidget::LoginWidget() { #ifdef USEWINSDK - ::SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, + ::SetWindowPos(HWND(this->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); #endif @@ -205,7 +208,7 @@ LoginWidget::LoginWidget() this->ui.buttonBox.setStandardButtons(QDialogButtonBox::Close); - connect(&this->ui.buttonBox, &QDialogButtonBox::rejected, [this]() { + QObject::connect(&this->ui.buttonBox, &QDialogButtonBox::rejected, [this]() { this->close(); // }); diff --git a/src/widgets/settingspages/accountspage.cpp b/src/widgets/settingspages/accountspage.cpp index 6275c92c..75035a1a 100644 --- a/src/widgets/settingspages/accountspage.cpp +++ b/src/widgets/settingspages/accountspage.cpp @@ -8,11 +8,11 @@ #include "widgets/helper/editablemodelview.hpp" #include "widgets/logindialog.hpp" -#include #include #include #include #include +#include namespace chatterino { namespace widgets { diff --git a/src/widgets/settingspages/commandpage.cpp b/src/widgets/settingspages/commandpage.cpp index fdf20789..855705d2 100644 --- a/src/widgets/settingspages/commandpage.cpp +++ b/src/widgets/settingspages/commandpage.cpp @@ -37,7 +37,8 @@ CommandPage::CommandPage() auto layout = layoutCreator.emplace().withoutMargin(); auto warning = layout.emplace("The command system will be reworked in the " - "future!\nYour saved commands will get discarded then."); + "future!\nYour saved commands will get discarded then. " + "Deleting commands crashes chatterino right now."); warning.getElement()->setStyleSheet("color: #f00"); helper::EditableModelView *view = diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index 35adf427..ba1f128e 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -235,6 +235,22 @@ bool Window::event(QEvent *event) return BaseWindow::event(event); } +void Window::showEvent(QShowEvent *event) +{ + if (getApp()->settings->startUpNotification.getValue() < 1) { + getApp()->settings->startUpNotification = 1; + + auto box = + new QMessageBox(QMessageBox::Information, "Chatterino 2 Beta", + "Please note that this software is not stable yet. Things are rough " + "around the edges and everything is subject to change."); + box->setAttribute(Qt::WA_DeleteOnClose); + box->show(); + } + + BaseWindow::showEvent(event); +} + void Window::closeEvent(QCloseEvent *) { if (this->type == Window::Main) { diff --git a/src/widgets/window.hpp b/src/widgets/window.hpp index 75c3b2cd..a7089452 100644 --- a/src/widgets/window.hpp +++ b/src/widgets/window.hpp @@ -38,6 +38,7 @@ public: WindowType getType(); protected: + void showEvent(QShowEvent *) override; void closeEvent(QCloseEvent *event) override; bool event(QEvent *event) override;