Only alert user at most once per new release
This commit is contained in:
parent
e76729ce62
commit
73b5c0501d
8 changed files with 54 additions and 45 deletions
|
@ -10,9 +10,12 @@
|
||||||
#include <QMultiMap>
|
#include <QMultiMap>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QVersionNumber>
|
||||||
|
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
|
||||||
|
static const QVersionNumber porymapVersion = QVersionNumber::fromString(PORYMAP_VERSION);
|
||||||
|
|
||||||
// In both versions the default new map border is a generic tree
|
// In both versions the default new map border is a generic tree
|
||||||
#define DEFAULT_BORDER_RSE (QList<uint16_t>{0x1D4, 0x1D5, 0x1DC, 0x1DD})
|
#define DEFAULT_BORDER_RSE (QList<uint16_t>{0x1D4, 0x1D5, 0x1DC, 0x1DD})
|
||||||
#define DEFAULT_BORDER_FRLG (QList<uint16_t>{0x14, 0x15, 0x1C, 0x1D})
|
#define DEFAULT_BORDER_FRLG (QList<uint16_t>{0x14, 0x15, 0x1C, 0x1D})
|
||||||
|
@ -78,6 +81,7 @@ public:
|
||||||
this->warpBehaviorWarningDisabled = false;
|
this->warpBehaviorWarningDisabled = false;
|
||||||
this->checkForUpdates = true;
|
this->checkForUpdates = true;
|
||||||
this->lastUpdateCheckTime = QDateTime();
|
this->lastUpdateCheckTime = QDateTime();
|
||||||
|
this->lastUpdateCheckVersion = porymapVersion;
|
||||||
this->rateLimitTimes.clear();
|
this->rateLimitTimes.clear();
|
||||||
}
|
}
|
||||||
void addRecentProject(QString project);
|
void addRecentProject(QString project);
|
||||||
|
@ -112,6 +116,7 @@ public:
|
||||||
void setWarpBehaviorWarningDisabled(bool disabled);
|
void setWarpBehaviorWarningDisabled(bool disabled);
|
||||||
void setCheckForUpdates(bool enabled);
|
void setCheckForUpdates(bool enabled);
|
||||||
void setLastUpdateCheckTime(QDateTime time);
|
void setLastUpdateCheckTime(QDateTime time);
|
||||||
|
void setLastUpdateCheckVersion(QVersionNumber version);
|
||||||
void setRateLimitTimes(QMap<QUrl, QDateTime> map);
|
void setRateLimitTimes(QMap<QUrl, QDateTime> map);
|
||||||
QString getRecentProject();
|
QString getRecentProject();
|
||||||
QStringList getRecentProjects();
|
QStringList getRecentProjects();
|
||||||
|
@ -145,6 +150,7 @@ public:
|
||||||
bool getWarpBehaviorWarningDisabled();
|
bool getWarpBehaviorWarningDisabled();
|
||||||
bool getCheckForUpdates();
|
bool getCheckForUpdates();
|
||||||
QDateTime getLastUpdateCheckTime();
|
QDateTime getLastUpdateCheckTime();
|
||||||
|
QVersionNumber getLastUpdateCheckVersion();
|
||||||
QMap<QUrl, QDateTime> getRateLimitTimes();
|
QMap<QUrl, QDateTime> getRateLimitTimes();
|
||||||
protected:
|
protected:
|
||||||
virtual QString getConfigFilepath() override;
|
virtual QString getConfigFilepath() override;
|
||||||
|
@ -196,6 +202,7 @@ private:
|
||||||
bool warpBehaviorWarningDisabled;
|
bool warpBehaviorWarningDisabled;
|
||||||
bool checkForUpdates;
|
bool checkForUpdates;
|
||||||
QDateTime lastUpdateCheckTime;
|
QDateTime lastUpdateCheckTime;
|
||||||
|
QVersionNumber lastUpdateCheckVersion;
|
||||||
QMap<QUrl, QDateTime> rateLimitTimes;
|
QMap<QUrl, QDateTime> rateLimitTimes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QVersionNumber>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class UpdatePromoter;
|
class UpdatePromoter;
|
||||||
|
@ -29,7 +30,7 @@ private:
|
||||||
|
|
||||||
QString changelog;
|
QString changelog;
|
||||||
QUrl downloadUrl;
|
QUrl downloadUrl;
|
||||||
bool breakingChanges;
|
QVersionNumber newVersion;
|
||||||
bool foundReleases;
|
bool foundReleases;
|
||||||
|
|
||||||
QSet<QUrl> visitedUrls; // Prevent infinite redirection
|
QSet<QUrl> visitedUrls; // Prevent infinite redirection
|
||||||
|
@ -38,7 +39,6 @@ private:
|
||||||
void get(const QUrl &url);
|
void get(const QUrl &url);
|
||||||
void processWebpage(const QJsonDocument &data, const QUrl &nextUrl);
|
void processWebpage(const QJsonDocument &data, const QUrl &nextUrl);
|
||||||
void error(const QString &err, const QDateTime time = QDateTime());
|
void error(const QString &err, const QDateTime time = QDateTime());
|
||||||
bool isNewerVersion(int major, int minor, int patch);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void dialogButtonClicked(QAbstractButton *button);
|
void dialogButtonClicked(QAbstractButton *button);
|
||||||
|
|
10
porymap.pro
10
porymap.pro
|
@ -14,14 +14,8 @@ RC_ICONS = resources/icons/porymap-icon-2.ico
|
||||||
ICON = resources/icons/porymap.icns
|
ICON = resources/icons/porymap.icns
|
||||||
QMAKE_CXXFLAGS += -std=c++17 -Wall
|
QMAKE_CXXFLAGS += -std=c++17 -Wall
|
||||||
QMAKE_TARGET_BUNDLE_PREFIX = com.pret
|
QMAKE_TARGET_BUNDLE_PREFIX = com.pret
|
||||||
VERSION_MAJOR = 5
|
VERSION = 5.3.0
|
||||||
VERSION_MINOR = 3
|
DEFINES += PORYMAP_VERSION=\\\"$$VERSION\\\"
|
||||||
VERSION_PATCH = 0
|
|
||||||
VERSION = $${VERSION_MAJOR}.$${VERSION_MINOR}.$${VERSION_PATCH}
|
|
||||||
DEFINES += PORYMAP_VERSION_MAJOR=$$VERSION_MAJOR \
|
|
||||||
PORYMAP_VERSION_MINOR=$$VERSION_MINOR \
|
|
||||||
PORYMAP_VERSION_PATCH=$$VERSION_PATCH \
|
|
||||||
PORYMAP_VERSION=\\\"$$VERSION\\\"
|
|
||||||
|
|
||||||
SOURCES += src/core/block.cpp \
|
SOURCES += src/core/block.cpp \
|
||||||
src/core/bitpacker.cpp \
|
src/core/bitpacker.cpp \
|
||||||
|
|
|
@ -411,6 +411,14 @@ void PorymapConfig::parseConfigKeyValue(QString key, QString value) {
|
||||||
this->checkForUpdates = getConfigBool(key, value);
|
this->checkForUpdates = getConfigBool(key, value);
|
||||||
} else if (key == "last_update_check_time") {
|
} else if (key == "last_update_check_time") {
|
||||||
this->lastUpdateCheckTime = QDateTime::fromString(value).toLocalTime();
|
this->lastUpdateCheckTime = QDateTime::fromString(value).toLocalTime();
|
||||||
|
} else if (key == "last_update_check_version") {
|
||||||
|
auto version = QVersionNumber::fromString(value);
|
||||||
|
if (version.segmentCount() != 3) {
|
||||||
|
logWarn(QString("Invalid config value for %1: '%2'. Must be 3 numbers separated by '.'").arg(key).arg(value));
|
||||||
|
this->lastUpdateCheckVersion = porymapVersion;
|
||||||
|
} else {
|
||||||
|
this->lastUpdateCheckVersion = version;
|
||||||
|
}
|
||||||
} else if (key.startsWith("rate_limit_time/")) {
|
} else if (key.startsWith("rate_limit_time/")) {
|
||||||
static const QRegularExpression regex("\\brate_limit_time/(?<url>.+)");
|
static const QRegularExpression regex("\\brate_limit_time/(?<url>.+)");
|
||||||
QRegularExpressionMatch match = regex.match(key);
|
QRegularExpressionMatch match = regex.match(key);
|
||||||
|
@ -465,6 +473,7 @@ QMap<QString, QString> PorymapConfig::getKeyValueMap() {
|
||||||
map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled));
|
map.insert("warp_behavior_warning_disabled", QString::number(this->warpBehaviorWarningDisabled));
|
||||||
map.insert("check_for_updates", QString::number(this->checkForUpdates));
|
map.insert("check_for_updates", QString::number(this->checkForUpdates));
|
||||||
map.insert("last_update_check_time", this->lastUpdateCheckTime.toUTC().toString());
|
map.insert("last_update_check_time", this->lastUpdateCheckTime.toUTC().toString());
|
||||||
|
map.insert("last_update_check_version", this->lastUpdateCheckVersion.toString());
|
||||||
for (auto i = this->rateLimitTimes.cbegin(), end = this->rateLimitTimes.cend(); i != end; i++){
|
for (auto i = this->rateLimitTimes.cbegin(), end = this->rateLimitTimes.cend(); i != end; i++){
|
||||||
// Only include rate limit times that are still active (i.e., in the future)
|
// Only include rate limit times that are still active (i.e., in the future)
|
||||||
const QDateTime time = i.value();
|
const QDateTime time = i.value();
|
||||||
|
@ -664,6 +673,11 @@ void PorymapConfig::setLastUpdateCheckTime(QDateTime time) {
|
||||||
this->save();
|
this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PorymapConfig::setLastUpdateCheckVersion(QVersionNumber version) {
|
||||||
|
this->lastUpdateCheckVersion = version;
|
||||||
|
this->save();
|
||||||
|
}
|
||||||
|
|
||||||
void PorymapConfig::setRateLimitTimes(QMap<QUrl, QDateTime> map) {
|
void PorymapConfig::setRateLimitTimes(QMap<QUrl, QDateTime> map) {
|
||||||
this->rateLimitTimes = map;
|
this->rateLimitTimes = map;
|
||||||
this->save();
|
this->save();
|
||||||
|
@ -831,6 +845,10 @@ QDateTime PorymapConfig::getLastUpdateCheckTime() {
|
||||||
return this->lastUpdateCheckTime;
|
return this->lastUpdateCheckTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVersionNumber PorymapConfig::getLastUpdateCheckVersion() {
|
||||||
|
return this->lastUpdateCheckVersion;
|
||||||
|
}
|
||||||
|
|
||||||
QMap<QUrl, QDateTime> PorymapConfig::getRateLimitTimes() {
|
QMap<QUrl, QDateTime> PorymapConfig::getRateLimitTimes() {
|
||||||
return this->rateLimitTimes;
|
return this->rateLimitTimes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
cleanupLargeLog();
|
cleanupLargeLog();
|
||||||
logInfo(QString("Launching Porymap v%1").arg(PORYMAP_VERSION));
|
logInfo(QString("Launching Porymap v%1").arg(QCoreApplication::applicationVersion()));
|
||||||
|
|
||||||
this->initWindow();
|
this->initWindow();
|
||||||
if (porymapConfig.getReopenOnLaunch() && this->openProject(porymapConfig.getRecentProject(), true))
|
if (porymapConfig.getReopenOnLaunch() && this->openProject(porymapConfig.getRecentProject(), true))
|
||||||
|
|
|
@ -78,9 +78,9 @@ void Scripting::populateGlobalObject(MainWindow *mainWindow) {
|
||||||
|
|
||||||
// Get version numbers
|
// Get version numbers
|
||||||
QJSValue version = instance->engine->newObject();
|
QJSValue version = instance->engine->newObject();
|
||||||
version.setProperty("major", PORYMAP_VERSION_MAJOR);
|
version.setProperty("major", porymapVersion.majorVersion());
|
||||||
version.setProperty("minor", PORYMAP_VERSION_MINOR);
|
version.setProperty("minor", porymapVersion.minorVersion());
|
||||||
version.setProperty("patch", PORYMAP_VERSION_PATCH);
|
version.setProperty("patch", porymapVersion.microVersion());
|
||||||
constants.setProperty("version", version);
|
constants.setProperty("version", version);
|
||||||
|
|
||||||
// Get basic tileset information
|
// Get basic tileset information
|
||||||
|
|
|
@ -8,7 +8,7 @@ AboutPorymap::AboutPorymap(QWidget *parent) :
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
this->ui->label_Version->setText(QString("Version %1 - %2").arg(PORYMAP_VERSION).arg(QStringLiteral(__DATE__)));
|
this->ui->label_Version->setText(QString("Version %1 - %2").arg(QCoreApplication::applicationVersion()).arg(QStringLiteral(__DATE__)));
|
||||||
this->ui->textBrowser->setSource(QUrl("qrc:/CHANGELOG.md"));
|
this->ui->textBrowser->setSource(QUrl("qrc:/CHANGELOG.md"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ void UpdatePromoter::resetDialog() {
|
||||||
|
|
||||||
this->changelog = QString();
|
this->changelog = QString();
|
||||||
this->downloadUrl = QString();
|
this->downloadUrl = QString();
|
||||||
this->breakingChanges = false;
|
this->newVersion = QVersionNumber();
|
||||||
this->foundReleases = false;
|
this->foundReleases = false;
|
||||||
this->visitedUrls.clear();
|
this->visitedUrls.clear();
|
||||||
}
|
}
|
||||||
|
@ -87,19 +87,12 @@ void UpdatePromoter::processWebpage(const QJsonDocument &data, const QUrl &nextU
|
||||||
|
|
||||||
// Convert tag string to version numbers
|
// Convert tag string to version numbers
|
||||||
const QString tagName = release.value("tag_name").toString();
|
const QString tagName = release.value("tag_name").toString();
|
||||||
const QStringList tag = tagName.split(".");
|
const QVersionNumber version = QVersionNumber::fromString(tagName);
|
||||||
if (tag.length() != 3) continue;
|
if (version.segmentCount() != 3) continue;
|
||||||
bool ok;
|
|
||||||
int major = tag.at(0).toInt(&ok);
|
|
||||||
if (!ok) continue;
|
|
||||||
int minor = tag.at(1).toInt(&ok);
|
|
||||||
if (!ok) continue;
|
|
||||||
int patch = tag.at(2).toInt(&ok);
|
|
||||||
if (!ok) continue;
|
|
||||||
|
|
||||||
// We've found a valid release tag. If the version number is not newer than the host version then we can stop looking at releases.
|
// We've found a valid release tag. If the version number is not newer than the host version then we can stop looking at releases.
|
||||||
this->foundReleases = true;
|
this->foundReleases = true;
|
||||||
if (!this->isNewerVersion(major, minor, patch))
|
if (porymapVersion >= version)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const QString description = release.value("body").toString();
|
const QString description = release.value("body").toString();
|
||||||
|
@ -116,7 +109,7 @@ void UpdatePromoter::processWebpage(const QJsonDocument &data, const QUrl &nextU
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this->downloadUrl = url;
|
this->downloadUrl = url;
|
||||||
this->breakingChanges = (major > PORYMAP_VERSION_MAJOR);
|
this->newVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the changelog of this release so we can show all changes since the host release.
|
// Record the changelog of this release so we can show all changes since the host release.
|
||||||
|
@ -137,20 +130,25 @@ void UpdatePromoter::processWebpage(const QJsonDocument &data, const QUrl &nextU
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate dialog with result
|
// Populate dialog with result
|
||||||
bool updateAvailable = !this->changelog.isEmpty();
|
|
||||||
ui->label_Status->setText(updateAvailable ? "A new version of Porymap is available!"
|
|
||||||
: "Your version of Porymap is up to date!");
|
|
||||||
ui->label_Warning->setVisible(this->breakingChanges);
|
|
||||||
ui->text_Changelog->setMarkdown(this->changelog);
|
ui->text_Changelog->setMarkdown(this->changelog);
|
||||||
ui->text_Changelog->setVisible(updateAvailable);
|
ui->text_Changelog->setVisible(!this->changelog.isEmpty());
|
||||||
this->button_Downloads->setEnabled(!this->downloadUrl.isEmpty());
|
this->button_Downloads->setEnabled(!this->downloadUrl.isEmpty());
|
||||||
this->button_Retry->setEnabled(true);
|
this->button_Retry->setEnabled(true);
|
||||||
|
if (!this->newVersion.isNull()) {
|
||||||
|
ui->label_Status->setText("A new version of Porymap is available!");
|
||||||
|
ui->label_Warning->setVisible(this->newVersion.majorVersion() > porymapVersion.majorVersion());
|
||||||
|
|
||||||
// Alert the user if there's a new update available and the dialog wasn't already open.
|
// Alert the user about the new version if the dialog wasn't already open.
|
||||||
// Show the window, but also show the option to turn off automatic alerts in the future.
|
// Show the window, but also show the option to turn off automatic alerts in the future.
|
||||||
if (updateAvailable && !this->isVisible()) {
|
// We only show this alert once for a given release.
|
||||||
ui->checkBox_StopAlerts->setVisible(true);
|
if (!this->isVisible() && this->newVersion > porymapConfig.getLastUpdateCheckVersion()) {
|
||||||
this->show();
|
ui->checkBox_StopAlerts->setVisible(true);
|
||||||
|
this->show();
|
||||||
|
}
|
||||||
|
porymapConfig.setLastUpdateCheckVersion(this->newVersion);
|
||||||
|
} else {
|
||||||
|
ui->label_Status->setText("Your version of Porymap is up to date!");
|
||||||
|
ui->label_Warning->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,14 +171,6 @@ void UpdatePromoter::error(const QString &err, const QDateTime retryAfter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UpdatePromoter::isNewerVersion(int major, int minor, int patch) {
|
|
||||||
if (major != PORYMAP_VERSION_MAJOR)
|
|
||||||
return major > PORYMAP_VERSION_MAJOR;
|
|
||||||
if (minor != PORYMAP_VERSION_MINOR)
|
|
||||||
return minor > PORYMAP_VERSION_MINOR;
|
|
||||||
return patch > PORYMAP_VERSION_PATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdatePromoter::updatePreferences() {
|
void UpdatePromoter::updatePreferences() {
|
||||||
const QSignalBlocker blocker(ui->checkBox_StopAlerts);
|
const QSignalBlocker blocker(ui->checkBox_StopAlerts);
|
||||||
ui->checkBox_StopAlerts->setChecked(!porymapConfig.getCheckForUpdates());
|
ui->checkBox_StopAlerts->setChecked(!porymapConfig.getCheckForUpdates());
|
||||||
|
|
Loading…
Reference in a new issue