add check for updates

This commit is contained in:
Le Tan 2021-08-21 13:06:56 +08:00
parent bcec79fe17
commit 0f1be2883a
12 changed files with 203 additions and 2 deletions

@ -1 +1 @@
Subproject commit f17e9bf898d86c2990b5831dea45673c3269030b
Subproject commit 392c0e218f5981b4fc6566512103b6149f714931

View File

@ -57,6 +57,8 @@ void CoreConfig::init(const QJsonObject &p_app,
m_recoverLastSessionOnStartEnabled = READBOOL(QStringLiteral("recover_last_session_on_start"));
m_checkForUpdatesOnStartEnabled = READBOOL(QStringLiteral("check_for_updates_on_start"));
m_historyMaxCount = READINT(QStringLiteral("history_max_count"));
if (m_historyMaxCount < 0) {
m_historyMaxCount = 100;
@ -72,6 +74,7 @@ QJsonObject CoreConfig::toJson() const
obj[QStringLiteral("toolbar_icon_size")] = m_toolBarIconSize;
obj[QStringLiteral("docks_tabbar_icon_size")] = m_docksTabBarIconSize;
obj[QStringLiteral("recover_last_session_on_start")] = m_recoverLastSessionOnStartEnabled;
obj[QStringLiteral("check_for_updates_on_start")] = m_checkForUpdatesOnStartEnabled;
obj[QStringLiteral("history_max_count")] = m_historyMaxCount;
return obj;
}
@ -186,6 +189,16 @@ void CoreConfig::setRecoverLastSessionOnStartEnabled(bool p_enabled)
updateConfig(m_recoverLastSessionOnStartEnabled, p_enabled, this);
}
bool CoreConfig::isCheckForUpdatesOnStartEnabled() const
{
return m_checkForUpdatesOnStartEnabled;
}
void CoreConfig::setCheckForUpdatesOnStartEnabled(bool p_enabled)
{
updateConfig(m_checkForUpdatesOnStartEnabled, p_enabled, this);
}
int CoreConfig::getHistoryMaxCount() const
{
return m_historyMaxCount;

View File

@ -97,6 +97,9 @@ namespace vnotex
bool isRecoverLastSessionOnStartEnabled() const;
void setRecoverLastSessionOnStartEnabled(bool p_enabled);
bool isCheckForUpdatesOnStartEnabled() const;
void setCheckForUpdatesOnStartEnabled(bool p_enabled);
int getHistoryMaxCount() const;
private:
@ -128,6 +131,8 @@ namespace vnotex
// Whether recover last session on start.
bool m_recoverLastSessionOnStartEnabled = true;
bool m_checkForUpdatesOnStartEnabled = true;
// Max count of the history items for each notebook and session config.
int m_historyMaxCount = 100;

View File

@ -70,6 +70,7 @@
}
},
"recover_last_session_on_start" : true,
"check_for_updates_on_start" : true,
"//comment" : "Max count of the history items for each notebook and session config",
"history_max_count" : 100
},

View File

@ -79,6 +79,16 @@ void GeneralPage::setupUI()
connect(m_recoverLastSessionCheckBox, &QCheckBox::stateChanged,
this, &GeneralPage::pageIsChanged);
}
{
const QString label(tr("Check for updates on start"));
m_checkForUpdatesCheckBox = WidgetsFactory::createCheckBox(label, this);
m_checkForUpdatesCheckBox->setToolTip(tr("Check for updates on start of VNote"));
mainLayout->addRow(m_checkForUpdatesCheckBox);
addSearchItem(label, m_checkForUpdatesCheckBox->toolTip(), m_checkForUpdatesCheckBox);
connect(m_checkForUpdatesCheckBox, &QCheckBox::stateChanged,
this, &GeneralPage::pageIsChanged);
}
}
void GeneralPage::loadInternal()
@ -104,6 +114,8 @@ void GeneralPage::loadInternal()
}
m_recoverLastSessionCheckBox->setChecked(coreConfig.isRecoverLastSessionOnStartEnabled());
m_checkForUpdatesCheckBox->setChecked(coreConfig.isCheckForUpdatesOnStartEnabled());
}
bool GeneralPage::saveInternal()
@ -128,6 +140,8 @@ bool GeneralPage::saveInternal()
coreConfig.setRecoverLastSessionOnStartEnabled(m_recoverLastSessionCheckBox->isChecked());
coreConfig.setCheckForUpdatesOnStartEnabled(m_checkForUpdatesCheckBox->isChecked());
return true;
}

View File

@ -31,6 +31,8 @@ namespace vnotex
QCheckBox *m_systemTrayCheckBox = nullptr;
QCheckBox *m_recoverLastSessionCheckBox = nullptr;
QCheckBox *m_checkForUpdatesCheckBox = nullptr;
};
}

View File

@ -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")));
}

View File

@ -0,0 +1,34 @@
#ifndef UPDATER_H
#define UPDATER_H
#include "dialog.h"
#include <functional>
class QLabel;
namespace vnotex
{
class Updater : public Dialog
{
Q_OBJECT
public:
explicit Updater(QWidget *p_parent = nullptr);
// Callback(hasUpdate, VersionOnSuccess, errMsg).
static void checkForUpdates(QObject *p_receiver, const std::function<void(bool, const QString &, const QString &)> &p_callback);
protected:
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
private slots:
void start();
private:
void setupUI();
QLabel *m_latestVersionLabel = nullptr;
};
}
#endif // UPDATER_H

View File

@ -51,6 +51,7 @@
#include <utils/docsutils.h>
#include <utils/iconutils.h>
#include <core/thememgr.h>
#include "dialogs/updater.h"
using namespace vnotex;
@ -122,6 +123,10 @@ void MainWindow::kickOffOnStart(const QStringList &p_paths)
emit VNoteX::getInst().openFileRequested(file, paras);
}
}
if (ConfigMgr::getInst().getCoreConfig().isCheckForUpdatesOnStartEnabled()) {
QTimer::singleShot(5 * 60 * 1000, this, &MainWindow::checkForUpdates);
}
});
}
@ -937,3 +942,14 @@ QDockWidget *MainWindow::createDockWidget(DockIndex p_dockIndex, const QString &
m_docks.push_back(dock);
return dock;
}
void MainWindow::checkForUpdates()
{
Updater::checkForUpdates(this, [this](bool p_hasUpdate, const QString &p_version, const QString &p_errMsg) {
if (p_version.isEmpty()) {
statusBar()->showMessage(tr("Failed to check for updates (%1)").arg(p_errMsg), 3000);
} else if (p_hasUpdate) {
statusBar()->showMessage(tr("Updates available: %1").arg(p_version));
}
});
}

View File

@ -169,6 +169,8 @@ namespace vnotex
QDockWidget *createDockWidget(DockIndex p_dockIndex, const QString &p_title, QWidget *p_parent);
void checkForUpdates();
ToolBarHelper m_toolBarHelper;
StatusBarHelper m_statusBarHelper;

View File

@ -25,6 +25,7 @@
#include "propertydefs.h"
#include "dialogs/settings/settingsdialog.h"
#include "messageboxhelper.h"
#include "dialogs/updater.h"
using namespace vnotex;
@ -511,7 +512,7 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too
WidgetUtils::openUrlByDesktop(QUrl("https://vnotex.github.io/vnote"));
});
menu->addAction(MainWindow::tr("Feedback And Discussions"),
menu->addAction(MainWindow::tr("Feedback and Discussions"),
menu,
[]() {
WidgetUtils::openUrlByDesktop(QUrl("https://github.com/vnotex/vnote/discussions"));
@ -519,6 +520,13 @@ QToolBar *ToolBarHelper::setupSettingsToolBar(MainWindow *p_win, QToolBar *p_too
menu->addSeparator();
menu->addAction(MainWindow::tr("Check for Updates"),
menu,
[p_win]() {
Updater updater(p_win);
updater.exec();
});
menu->addAction(MainWindow::tr("About"),
menu,
[p_win]() {

View File

@ -33,6 +33,7 @@ SOURCES += \
$$PWD/dialogs/snippetpropertiesdialog.cpp \
$$PWD/dialogs/sortdialog.cpp \
$$PWD/dialogs/tableinsertdialog.cpp \
$$PWD/dialogs/updater.cpp \
$$PWD/dragdropareaindicator.cpp \
$$PWD/editors/editormarkdownvieweradapter.cpp \
$$PWD/editors/graphhelper.cpp \
@ -147,6 +148,7 @@ HEADERS += \
$$PWD/dialogs/snippetpropertiesdialog.h \
$$PWD/dialogs/sortdialog.h \
$$PWD/dialogs/tableinsertdialog.h \
$$PWD/dialogs/updater.h \
$$PWD/dragdropareaindicator.h \
$$PWD/editors/editormarkdownvieweradapter.h \
$$PWD/editors/graphhelper.h \