|
|
@@ -0,0 +1,104 @@
|
|
|
+#include "updater.h"
|
|
|
+
|
|
|
+#include <QHBoxLayout>
|
|
|
+#include <QFormLayout>
|
|
|
+#include <QTimer>
|
|
|
+#include <QLabel>
|
|
|
+#include <QApplication>
|
|
|
+#include <QPushButton>
|
|
|
+#include <QNetworkAccessManager>
|
|
|
+#include <QNetworkReply>
|
|
|
+#include <QJsonObject>
|
|
|
+#include <QPointer>
|
|
|
+
|
|
|
+#include <widgets/widgetsfactory.h>
|
|
|
+#include <utils/widgetutils.h>
|
|
|
+#include <utils/utils.h>
|
|
|
+#include <vtextedit/networkutils.h>
|
|
|
+
|
|
|
+using namespace vnotex;
|
|
|
+
|
|
|
+Updater::Updater(QWidget *p_parent)
|
|
|
+ : Dialog(p_parent)
|
|
|
+{
|
|
|
+ setupUI();
|
|
|
+}
|
|
|
+
|
|
|
+void Updater::setupUI()
|
|
|
+{
|
|
|
+ auto mainWidget = new QWidget(this);
|
|
|
+ setCentralWidget(mainWidget);
|
|
|
+
|
|
|
+ auto mainLayout = WidgetsFactory::createFormLayout(mainWidget);
|
|
|
+
|
|
|
+ mainLayout->addRow(tr("Version:"), new QLabel(qApp->applicationVersion(), mainWidget));
|
|
|
+
|
|
|
+ m_latestVersionLabel = new QLabel(tr("Fetching information..."), mainWidget);
|
|
|
+ mainLayout->addRow(tr("Latest version:"), m_latestVersionLabel);
|
|
|
+
|
|
|
+ setDialogButtonBox(QDialogButtonBox::Ok);
|
|
|
+
|
|
|
+ {
|
|
|
+ auto btnBox = getDialogButtonBox();
|
|
|
+ auto viewBtn = btnBox->addButton(tr("View Releases"), QDialogButtonBox::AcceptRole);
|
|
|
+ connect(viewBtn, &QPushButton::clicked,
|
|
|
+ this, [this]() {
|
|
|
+ WidgetUtils::openUrlByDesktop(QUrl("https://github.com/vnotex/vnote/releases"));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ setWindowTitle(tr("Check for Updates"));
|
|
|
+}
|
|
|
+
|
|
|
+void Updater::showEvent(QShowEvent *p_event)
|
|
|
+{
|
|
|
+ Dialog::showEvent(p_event);
|
|
|
+
|
|
|
+ QTimer::singleShot(1000, this, &Updater::start);
|
|
|
+}
|
|
|
+
|
|
|
+void Updater::start()
|
|
|
+{
|
|
|
+ checkForUpdates(this, [this](bool p_hasUpdate, const QString &p_version, const QString &p_errMsg) {
|
|
|
+ Q_UNUSED(p_hasUpdate);
|
|
|
+ if (p_version.isEmpty()) {
|
|
|
+ setInformationText(tr("Failed to fetch information (%1).").arg(p_errMsg), InformationLevel::Warning);
|
|
|
+ m_latestVersionLabel->setText("");
|
|
|
+ } else {
|
|
|
+ clearInformationText();
|
|
|
+ m_latestVersionLabel->setText(p_version);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+void Updater::checkForUpdates(QObject *p_receiver, const std::function<void(bool, const QString &, const QString &)> &p_callback)
|
|
|
+{
|
|
|
+ QPointer<QObject> receiver(p_receiver);
|
|
|
+
|
|
|
+ // Will delete it in the callback.
|
|
|
+ auto mgr = new QNetworkAccessManager();
|
|
|
+ connect(mgr, &QNetworkAccessManager::finished,
|
|
|
+ mgr, [mgr, receiver, p_callback](QNetworkReply *p_reply) {
|
|
|
+ bool hasUpdate = false;
|
|
|
+ QString version;
|
|
|
+ QString errMsg;
|
|
|
+ if (p_reply->error() != QNetworkReply::NoError) {
|
|
|
+ errMsg = vte::NetworkUtils::networkErrorStr(p_reply->error());
|
|
|
+ } else {
|
|
|
+ auto obj = Utils::fromJsonString(p_reply->readAll());
|
|
|
+ version = obj["tag_name"].toString();
|
|
|
+ if (version.startsWith('v')) {
|
|
|
+ version = version.mid(1);
|
|
|
+ }
|
|
|
+ hasUpdate = version != qApp->applicationVersion();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (receiver) {
|
|
|
+ p_callback(hasUpdate, version, errMsg);
|
|
|
+ }
|
|
|
+ p_reply->deleteLater();
|
|
|
+ mgr->deleteLater();
|
|
|
+ });
|
|
|
+
|
|
|
+ mgr->get(vte::NetworkUtils::networkRequest(QUrl("https://api.github.com/repos/vnotex/vnote/releases/latest")));
|
|
|
+}
|