-
Notifications
You must be signed in to change notification settings - Fork 390
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
384 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#include "updateController.h" | ||
|
||
#include <QNetworkAccessManager> | ||
#include <QNetworkReply> | ||
#include <QVersionNumber> | ||
#include <QtConcurrent> | ||
|
||
#include "amnezia_application.h" | ||
#include "core/errorstrings.h" | ||
#include "version.h" | ||
|
||
namespace { | ||
#ifdef Q_OS_MACOS | ||
const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.dmg"; | ||
#elif defined Q_OS_WINDOWS | ||
const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.exe"; | ||
#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) | ||
const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.tar.zip"; | ||
#endif | ||
} | ||
|
||
UpdateController::UpdateController(const std::shared_ptr<Settings> &settings, QObject *parent) : QObject(parent), m_settings(settings) | ||
{ | ||
} | ||
|
||
QString UpdateController::getHeaderText() | ||
{ | ||
return tr("New version released: %1 (%2)").arg(m_version, m_releaseDate); | ||
} | ||
|
||
QString UpdateController::getChangelogText() | ||
{ | ||
return m_changelogText; | ||
} | ||
|
||
void UpdateController::checkForUpdates() | ||
{ | ||
QNetworkRequest request; | ||
request.setTransferTimeout(7000); | ||
QString endpoint = "https://api.github.com/repos/amnezia-vpn/amnezia-client/releases/latest"; | ||
request.setUrl(endpoint); | ||
|
||
QNetworkReply *reply = amnApp->manager()->get(request); | ||
|
||
QObject::connect(reply, &QNetworkReply::finished, [this, reply]() { | ||
if (reply->error() == QNetworkReply::NoError) { | ||
QString contents = QString::fromUtf8(reply->readAll()); | ||
QJsonObject data = QJsonDocument::fromJson(contents.toUtf8()).object(); | ||
m_version = data.value("tag_name").toString(); | ||
|
||
auto currentVersion = QVersionNumber::fromString(QString(APP_VERSION)); | ||
qDebug() << currentVersion; | ||
auto newVersion = QVersionNumber::fromString(m_version); | ||
if (newVersion > currentVersion) { | ||
m_changelogText = data.value("body").toString(); | ||
|
||
QString dateString = data.value("published_at").toString(); | ||
QDateTime dateTime = QDateTime::fromString(dateString, "yyyy-MM-ddTHH:mm:ssZ"); | ||
m_releaseDate = dateTime.toString("MMM dd yyyy"); | ||
|
||
QJsonArray assets = data.value("assets").toArray(); | ||
|
||
for (auto asset : assets) { | ||
QJsonObject assetObject = asset.toObject(); | ||
if (assetObject.value("name").toString().contains(".dmg")) { | ||
m_downloadUrl = assetObject.value("browser_download_url").toString(); | ||
} | ||
} | ||
|
||
emit updateFound(); | ||
} | ||
} else { | ||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError | ||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) { | ||
qDebug() << errorString(ErrorCode::ApiConfigTimeoutError); | ||
} else { | ||
QString err = reply->errorString(); | ||
qDebug() << QString::fromUtf8(reply->readAll()); | ||
qDebug() << reply->error(); | ||
qDebug() << err; | ||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); | ||
qDebug() << errorString(ErrorCode::ApiConfigDownloadError); | ||
} | ||
} | ||
|
||
reply->deleteLater(); | ||
}); | ||
|
||
QObject::connect(reply, &QNetworkReply::errorOccurred, | ||
[this, reply](QNetworkReply::NetworkError error) { qDebug() << reply->errorString() << error; }); | ||
connect(reply, &QNetworkReply::sslErrors, [this, reply](const QList<QSslError> &errors) { | ||
qDebug().noquote() << errors; | ||
qDebug() << errorString(ErrorCode::ApiConfigSslError); | ||
}); | ||
} | ||
|
||
void UpdateController::runInstaller() | ||
{ | ||
QNetworkRequest request; | ||
request.setTransferTimeout(7000); | ||
request.setUrl(m_downloadUrl); | ||
|
||
QNetworkReply *reply = amnApp->manager()->get(request); | ||
|
||
QObject::connect(reply, &QNetworkReply::finished, [this, reply]() { | ||
if (reply->error() == QNetworkReply::NoError) { | ||
QFile file(installerPath); | ||
if (file.open(QIODevice::WriteOnly)) { | ||
file.write(reply->readAll()); | ||
file.close(); | ||
|
||
QFutureWatcher<int> watcher; | ||
QFuture<int> future = QtConcurrent::run([this]() { | ||
QString t = installerPath; | ||
QRemoteObjectPendingReply<int> ipcReply = IpcClient::Interface()->mountDmg(t, true); | ||
ipcReply.waitForFinished(); | ||
QProcess::execute("/Volumes/AmneziaVPN/AmneziaVPN.app/Contents/MacOS/AmneziaVPN"); | ||
ipcReply = IpcClient::Interface()->mountDmg(t, false); | ||
ipcReply.waitForFinished(); | ||
return ipcReply.returnValue(); | ||
}); | ||
|
||
QEventLoop wait; | ||
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit); | ||
watcher.setFuture(future); | ||
wait.exec(); | ||
|
||
qDebug() << future.result(); | ||
|
||
// emit errorOccured(""); | ||
} | ||
} else { | ||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError | ||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) { | ||
qDebug() << errorString(ErrorCode::ApiConfigTimeoutError); | ||
} else { | ||
QString err = reply->errorString(); | ||
qDebug() << QString::fromUtf8(reply->readAll()); | ||
qDebug() << reply->error(); | ||
qDebug() << err; | ||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); | ||
qDebug() << errorString(ErrorCode::ApiConfigDownloadError); | ||
} | ||
} | ||
|
||
reply->deleteLater(); | ||
}); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef UPDATECONTROLLER_H | ||
#define UPDATECONTROLLER_H | ||
|
||
#include <QObject> | ||
|
||
#include "settings.h" | ||
|
||
class UpdateController : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
explicit UpdateController(const std::shared_ptr<Settings> &settings, QObject *parent = nullptr); | ||
|
||
Q_PROPERTY(QString changelogText READ getChangelogText NOTIFY updateFound) | ||
Q_PROPERTY(QString headerText READ getHeaderText NOTIFY updateFound) | ||
public slots: | ||
QString getHeaderText(); | ||
QString getChangelogText(); | ||
|
||
void checkForUpdates(); | ||
void runInstaller(); | ||
signals: | ||
void updateFound(); | ||
void errorOccured(const QString &errorMessage); | ||
private: | ||
std::shared_ptr<Settings> m_settings; | ||
|
||
QString m_changelogText; | ||
QString m_version; | ||
QString m_releaseDate; | ||
QString m_downloadUrl; | ||
}; | ||
|
||
#endif // UPDATECONTROLLER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import QtQuick | ||
import QtQuick.Controls | ||
import QtQuick.Layouts | ||
|
||
import "../Controls2" | ||
import "../Controls2/TextTypes" | ||
|
||
import "../Config" | ||
|
||
DrawerType2 { | ||
id: root | ||
|
||
anchors.fill: parent | ||
expandedHeight: parent.height * 0.9 | ||
|
||
expandedContent: Item { | ||
implicitHeight: root.expandedHeight | ||
|
||
Connections { | ||
target: root | ||
enabled: !GC.isMobile() | ||
function onOpened() { | ||
focusItem.forceActiveFocus() | ||
} | ||
} | ||
|
||
Header2TextType { | ||
id: header | ||
anchors.top: parent.top | ||
anchors.left: parent.left | ||
anchors.right: parent.right | ||
anchors.topMargin: 16 | ||
anchors.rightMargin: 16 | ||
anchors.leftMargin: 16 | ||
|
||
text: UpdateController.headerText | ||
} | ||
|
||
FlickableType { | ||
anchors.top: header.bottom | ||
anchors.bottom: updateButton.top | ||
contentHeight: changelog.height + 32 | ||
|
||
ParagraphTextType { | ||
id: changelog | ||
anchors.top: parent.top | ||
anchors.left: parent.left | ||
anchors.right: parent.right | ||
anchors.topMargin: 48 | ||
anchors.rightMargin: 16 | ||
anchors.leftMargin: 16 | ||
|
||
HoverHandler { | ||
enabled: parent.hoveredLink | ||
cursorShape: Qt.PointingHandCursor | ||
} | ||
|
||
onLinkActivated: function(link) { | ||
Qt.openUrlExternally(link) | ||
} | ||
|
||
text: UpdateController.changelogText | ||
textFormat: Text.MarkdownText | ||
} | ||
} | ||
|
||
Item { | ||
id: focusItem | ||
KeyNavigation.tab: updateButton | ||
} | ||
|
||
BasicButtonType { | ||
id: updateButton | ||
anchors.bottom: skipButton.top | ||
anchors.left: parent.left | ||
anchors.right: parent.right | ||
anchors.topMargin: 16 | ||
anchors.bottomMargin: 8 | ||
anchors.rightMargin: 16 | ||
anchors.leftMargin: 16 | ||
|
||
text: qsTr("Update") | ||
|
||
clickedFunc: function() { | ||
PageController.showBusyIndicator(true) | ||
UpdateController.runInstaller() | ||
PageController.showBusyIndicator(false) | ||
root.close() | ||
} | ||
|
||
KeyNavigation.tab: skipButton | ||
} | ||
|
||
BasicButtonType { | ||
id: skipButton | ||
anchors.bottom: parent.bottom | ||
anchors.left: parent.left | ||
anchors.right: parent.right | ||
anchors.bottomMargin: 16 | ||
anchors.rightMargin: 16 | ||
anchors.leftMargin: 16 | ||
|
||
defaultColor: "transparent" | ||
hoveredColor: Qt.rgba(1, 1, 1, 0.08) | ||
pressedColor: Qt.rgba(1, 1, 1, 0.12) | ||
disabledColor: "#878B91" | ||
textColor: "#D7D8DB" | ||
borderWidth: 1 | ||
|
||
text: qsTr("Skip this version") | ||
|
||
clickedFunc: function() { | ||
root.close() | ||
} | ||
|
||
KeyNavigation.tab: focusItem | ||
} | ||
} | ||
} |
Oops, something went wrong.