From 48d53e276eb6dd9ba62d372006d416056dfbd143 Mon Sep 17 00:00:00 2001 From: perf3ct Date: Sat, 9 Nov 2024 22:16:00 +0000 Subject: [PATCH] more reliably check for version numbers --- src/public/app/services/utils.js | 50 ++++++++++++++++++- src/public/app/widgets/buttons/global_menu.js | 1 - .../app/widgets/buttons/update_available.js | 3 +- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/public/app/services/utils.js b/src/public/app/services/utils.js index e8c92351e..fcc00229c 100644 --- a/src/public/app/services/utils.js +++ b/src/public/app/services/utils.js @@ -527,6 +527,52 @@ function downloadSvg(nameWithoutExtension, svgContent) { document.body.removeChild(element); } +/** + * Compares two semantic version strings. + * Returns: + * 1 if v1 is greater than v2 + * 0 if v1 is equal to v2 + * -1 if v1 is less than v2 + * + * @param {string} v1 First version string + * @param {string} v2 Second version string + * @returns {number} + */ +function compareVersions(v1, v2) { + + // Remove 'v' prefix and everything after dash if present + v1 = v1.replace(/^v/, '').split('-')[0]; + v2 = v2.replace(/^v/, '').split('-')[0]; + + const v1parts = v1.split('.').map(Number); + const v2parts = v2.split('.').map(Number); + + // Pad shorter version with zeros + while (v1parts.length < 3) v1parts.push(0); + while (v2parts.length < 3) v2parts.push(0); + + // Compare major version + if (v1parts[0] !== v2parts[0]) { + return v1parts[0] > v2parts[0] ? 1 : -1; + } + + // Compare minor version + if (v1parts[1] !== v2parts[1]) { + return v1parts[1] > v2parts[1] ? 1 : -1; + } + + // Compare patch version + if (v1parts[2] !== v2parts[2]) { + return v1parts[2] > v2parts[2] ? 1 : -1; + } + + return 0; +} + +function isUpdateAvailable(latestVersion, currentVersion) { + return compareVersions(latestVersion, currentVersion) > 0; +} + export default { reloadFrontendApp, parseDate, @@ -567,5 +613,7 @@ export default { areObjectsEqual, copyHtmlToClipboard, createImageSrcUrl, - downloadSvg + downloadSvg, + compareVersions, + isUpdateAvailable }; diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index d4e65b989..ab3f5a98d 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -333,7 +333,6 @@ export default class GlobalMenuWidget extends BasicWidget { const latestVersion = await this.fetchLatestVersion(); this.updateAvailableWidget.updateVersionStatus(latestVersion); - this.$updateToLatestVersionButton.toggle(latestVersion > glob.triliumVersion); this.$updateToLatestVersionButton.find(".version-text").text(`Version ${latestVersion} is available, click to download.`); } diff --git a/src/public/app/widgets/buttons/update_available.js b/src/public/app/widgets/buttons/update_available.js index 50351cf0e..39db4cfd2 100644 --- a/src/public/app/widgets/buttons/update_available.js +++ b/src/public/app/widgets/buttons/update_available.js @@ -1,5 +1,6 @@ import { t } from "../../services/i18n.js"; import BasicWidget from "../basic_widget.js"; +import utils from "../../services/utils.js"; const TPL = `
@@ -34,6 +35,6 @@ export default class UpdateAvailableWidget extends BasicWidget { } updateVersionStatus(latestVersion) { - this.$widget.toggle(latestVersion > glob.triliumVersion); + this.$widget.toggle(utils.isUpdateAvailable(latestVersion, glob.triliumVersion)); } }