added updating mechanic

This commit is contained in:
fourtf 2018-06-21 22:02:35 +02:00
parent 2f91e3097a
commit e204dfdb17
10 changed files with 117 additions and 10 deletions

View file

@ -71,7 +71,7 @@ void PathManager::initAppDataDirectory()
this->rootAppDataDirectory = [&]() -> QString { this->rootAppDataDirectory = [&]() -> QString {
// portable // portable
if (this->portable) { if (this->isPortable()) {
return QCoreApplication::applicationDirPath(); return QCoreApplication::applicationDirPath();
} }

View file

@ -125,6 +125,9 @@ public:
QStringSetting preferredQuality = {"/external/streamlink/quality", "Choose"}; QStringSetting preferredQuality = {"/external/streamlink/quality", "Choose"};
QStringSetting streamlinkOpts = {"/external/streamlink/options", ""}; QStringSetting streamlinkOpts = {"/external/streamlink/options", ""};
/// Misc
IntSetting startUpNotification = {"/misc/startUpNotification", 0};
void updateWordTypeMask(); void updateWordTypeMask();
void saveSnapshot(); void saveSnapshot();

View file

@ -1,8 +1,12 @@
#include "updatemanager.hpp" #include "updatemanager.hpp"
#include "util/combine_path.hpp"
#include "util/networkrequest.hpp" #include "util/networkrequest.hpp"
#include "version.hpp" #include "version.hpp"
#include <QMessageBox>
#include <QProcess>
namespace chatterino { namespace chatterino {
namespace singletons { namespace singletons {
@ -32,32 +36,90 @@ const QString &UpdateManager::getOnlineVersion() const
void UpdateManager::installUpdates() 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() void UpdateManager::checkForUpdates()
{ {
#ifdef Q_OS_WIN
QString url = "https://notitia.chatterino.com/version/chatterino/" CHATTERINO_OS "/stable"; QString url = "https://notitia.chatterino.com/version/chatterino/" CHATTERINO_OS "/stable";
util::NetworkRequest req(url); util::NetworkRequest req(url);
req.setTimeout(30000); req.setTimeout(30000);
req.getJSON([this](QJsonObject &object) { req.getJSON([this](QJsonObject &object) {
QJsonValue version_val = object.value("version"); QJsonValue version_val = object.value("version");
if (!version_val.isString()) { QJsonValue update_val = object.value("update");
this->setStatus_(Error);
if (!version_val.isString() || !update_val.isString()) {
this->setStatus_(SearchFailed);
qDebug() << "error updating"; 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; return;
} }
this->onlineVersion_ = version_val.toString(); this->onlineVersion_ = version_val.toString();
this->updateUrl_ = update_val.toString();
if (this->currentVersion_ != this->onlineVersion_) { if (this->currentVersion_ != this->onlineVersion_) {
this->setStatus_(UpdateAvailable); 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 { } else {
this->setStatus_(NoUpdateAvailable); this->setStatus_(NoUpdateAvailable);
} }
}); });
this->setStatus_(Searching); this->setStatus_(Searching);
req.execute(); req.execute();
#endif
} }
UpdateManager::UpdateStatus UpdateManager::getStatus() const UpdateManager::UpdateStatus UpdateManager::getStatus() const

View file

@ -11,7 +11,16 @@ class UpdateManager
UpdateManager(); UpdateManager();
public: 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 // fourtf: don't add this class to the application class
static UpdateManager &getInstance(); static UpdateManager &getInstance();
@ -29,6 +38,8 @@ private:
QString onlineVersion_; QString onlineVersion_;
UpdateStatus status_ = None; UpdateStatus status_ = None;
QString updateUrl_;
void setStatus_(UpdateStatus status); void setStatus_(UpdateStatus status);
}; };

View file

@ -59,10 +59,20 @@ LastRunCrashDialog::LastRunCrashDialog()
case singletons::UpdateManager::NoUpdateAvailable: { case singletons::UpdateManager::NoUpdateAvailable: {
update->setText("No update abailable."); update->setText("No update abailable.");
} break; } break;
case singletons::UpdateManager::Error: { case singletons::UpdateManager::SearchFailed: {
update->setText("Error while searching for update.\nEither the update service is " update->setText("Error while searching for update.\nEither the update service is "
"temporarily down or there is an issue with your installation."); "temporarily down or there is an issue with your installation.");
} break; } 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;
} }
}; };

View file

@ -56,6 +56,8 @@ void LogInWithCredentials(const std::string &userID, const std::string &username
getApp()->accounts->twitch.reloadUsers(); getApp()->accounts->twitch.reloadUsers();
// messageBox.exec(); // messageBox.exec();
getApp()->accounts->twitch.currentUsername = username;
} }
} // namespace } // namespace
@ -77,7 +79,7 @@ BasicLoginWidget::BasicLoginWidget()
QDesktopServices::openUrl(QUrl("https://chatterino.com/client_login")); 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(); QClipboard *clipboard = QGuiApplication::clipboard();
QString clipboardString = clipboard->text(); QString clipboardString = clipboard->text();
QStringList parameters = clipboardString.split(';'); QStringList parameters = clipboardString.split(';');
@ -108,6 +110,7 @@ BasicLoginWidget::BasicLoginWidget()
LogInWithCredentials(userID, username, clientID, oauthToken); LogInWithCredentials(userID, username, clientID, oauthToken);
clipboard->clear(); clipboard->clear();
this->window()->close();
}); });
} }
@ -191,7 +194,7 @@ void AdvancedLoginWidget::refreshButtons()
LoginWidget::LoginWidget() LoginWidget::LoginWidget()
{ {
#ifdef USEWINSDK #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); SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
#endif #endif
@ -205,7 +208,7 @@ LoginWidget::LoginWidget()
this->ui.buttonBox.setStandardButtons(QDialogButtonBox::Close); this->ui.buttonBox.setStandardButtons(QDialogButtonBox::Close);
connect(&this->ui.buttonBox, &QDialogButtonBox::rejected, [this]() { QObject::connect(&this->ui.buttonBox, &QDialogButtonBox::rejected, [this]() {
this->close(); // this->close(); //
}); });

View file

@ -8,11 +8,11 @@
#include "widgets/helper/editablemodelview.hpp" #include "widgets/helper/editablemodelview.hpp"
#include "widgets/logindialog.hpp" #include "widgets/logindialog.hpp"
#include <algorithm>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QHeaderView> #include <QHeaderView>
#include <QTableView> #include <QTableView>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <algorithm>
namespace chatterino { namespace chatterino {
namespace widgets { namespace widgets {

View file

@ -37,7 +37,8 @@ CommandPage::CommandPage()
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin(); auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
auto warning = layout.emplace<QLabel>("The command system will be reworked in the " auto warning = layout.emplace<QLabel>("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"); warning.getElement()->setStyleSheet("color: #f00");
helper::EditableModelView *view = helper::EditableModelView *view =

View file

@ -235,6 +235,22 @@ bool Window::event(QEvent *event)
return BaseWindow::event(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 *) void Window::closeEvent(QCloseEvent *)
{ {
if (this->type == Window::Main) { if (this->type == Window::Main) {

View file

@ -38,6 +38,7 @@ public:
WindowType getType(); WindowType getType();
protected: protected:
void showEvent(QShowEvent *) override;
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
bool event(QEvent *event) override; bool event(QEvent *event) override;