From 6865f67f66d60bcbf1db0f0d0cad95f46e6d5987 Mon Sep 17 00:00:00 2001 From: blavenie Date: Tue, 9 Jan 2018 13:09:53 +0100 Subject: [PATCH] [enh] Display warning when new release available - fix #80 --- www/i18n/locale-en-GB.json | 6 +- www/i18n/locale-en.json | 9 ++- www/i18n/locale-es-ES.json | 9 ++- www/i18n/locale-fr-FR.json | 6 +- www/js/controllers/app-controllers.js | 1 + www/js/platform.js | 41 ++++++++++- www/js/services/device-services.js | 18 +++-- www/js/services/http-services.js | 64 ++++++++++++++++- www/js/services/modal-services.js | 19 ++++- www/js/services/settings-services.js | 3 + www/templates/menu.html | 16 ++++- www/templates/modal_about.html | 99 +++++++++++++++------------ 12 files changed, 223 insertions(+), 68 deletions(-) diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index 2b8e0cd3..18ba747d 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -98,12 +98,12 @@ "ABOUT": { "TITLE": "About", "LICENSE": "Free/libre software (License GNU GPLv3).", + "LATEST_RELEASE": "There is a newer version of {{'COMMON.APP_NAME' | translate}} (v{{version}})", + "PLEASE_UPDATE": "Please update {{'COMMON.APP_NAME' | translate}} (latest version: v{{version}})", "CODE": "Source code:", "DEVELOPERS": "Developers:", "FORUM": "Forum:", - "DEV_WARNING": "Warning", - "DEV_WARNING_MESSAGE": "This application is still in active development.
Please report any issue to us!", - "DEV_WARNING_MESSAGE_SHORT": "This App is still unstable (still under development).", + "PLEASE_REPORT_ISSUE": "Please report any issue to us!", "REPORT_ISSUE": "Report an issue" }, "HOME": { diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 45a3e702..e71bf79e 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -98,12 +98,12 @@ "ABOUT": { "TITLE": "About", "LICENSE": "Free/libre software (License GNU GPLv3).", + "LATEST_RELEASE": "There is a newer version of {{'COMMON.APP_NAME' | translate}} (v{{version}})", + "PLEASE_UPDATE": "Please update {{'COMMON.APP_NAME' | translate}} (latest version: v{{version}})", "CODE": "Source code:", "DEVELOPERS": "Developers:", "FORUM": "Forum:", - "DEV_WARNING": "Warning", - "DEV_WARNING_MESSAGE": "This application is still in active development.
Please report any issue to us!", - "DEV_WARNING_MESSAGE_SHORT": "This App is still unstable (still under development).", + "PLEASE_REPORT_ISSUE": "Please report any issue to us!", "REPORT_ISSUE": "Report an issue" }, "HOME": { @@ -342,6 +342,9 @@ "NO_PENDING": "No pending registrations.", "NO_NEWCOMERS": "No members." }, + "CONTACTS": { + "TITLE": "Contacts" + }, "MODAL": { "TITLE": "Search" }, diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json index 23bfda35..8b327d6d 100644 --- a/www/i18n/locale-es-ES.json +++ b/www/i18n/locale-es-ES.json @@ -98,12 +98,12 @@ "ABOUT": { "TITLE": "A propósito ", "LICENSE": "Aplicación libre (licencia GNU GPLv3).", + "LATEST_RELEASE": "Hay una versión más nueva de {{'COMMON.APP_NAME' | translate}} (v{{version}})", + "PLEASE_UPDATE": "Por favor actualice {{'COMMON.APP_NAME' | translate}} (última versión: v{{version}})", "CODE": "Codigo fuente :", "DEVELOPERS": "Desarrollado por :", "FORUM": "Foro :", - "DEV_WARNING": "Advertencia", - "DEV_WARNING_MESSAGE": "Esta applicación ya no es estabilizada (Desarrollo en proceso).
No duda a informarnos de las anomalías encontradas !", - "DEV_WARNING_MESSAGE_SHORT": "Esta Ap ya no es estabilizada (Desarrollo en proceso).", + "PLEASE_REPORT_ISSUE": "No duda a informarnos de las anomalías encontradas", "REPORT_ISSUE": "Informar de un problema" }, "HOME": { @@ -342,6 +342,9 @@ "NO_PENDING": "Ninguna inscripción en espera.", "NO_NEWCOMERS": "Ningun miembro." }, + "CONTACTS": { + "TITLE": "Contactos" + }, "MODAL": { "TITLE": "Búsqueda" }, diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 831079a8..25beb99a 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -98,12 +98,12 @@ "ABOUT": { "TITLE": "À propos", "LICENSE": "Application libre (licence GNU GPLv3).", + "LATEST_RELEASE": "Il existe une version plus récente de {{'COMMON.APP_NAME'|translate}} (v{{version}})", + "PLEASE_UPDATE": "Veuillez mettre à jour {{'COMMON.APP_NAME'|translate}} (dernière version : v{{version}})", "CODE": "Code source :", "DEVELOPERS": "Développé par :", "FORUM": "Forum :", - "DEV_WARNING": "Avertissement", - "DEV_WARNING_MESSAGE": "Cette application est encore en plein développement.
N'hésitez pas à nous remonter les anomalies rencontrées !", - "DEV_WARNING_MESSAGE_SHORT": "Cette App est en plein développement.", + "PLEASE_REPORT_ISSUE": "N'hésitez pas à nous remonter les anomalies rencontrées", "REPORT_ISSUE": "Remonter un problème" }, "HOME": { diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js index b36b2823..b8336155 100644 --- a/www/js/controllers/app-controllers.js +++ b/www/js/controllers/app-controllers.js @@ -411,6 +411,7 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $ $scope.doMotion = function(options) { return $scope.motion.show(options); }; + } diff --git a/www/js/platform.js b/www/js/platform.js index d2d00e3b..0c314f91 100644 --- a/www/js/platform.js +++ b/www/js/platform.js @@ -161,6 +161,30 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'] return started; } + + function getLatestRelease() { + var latestRelease = csSettings.data.latestReleaseUrl && csHttp.uri.parse(csSettings.data.latestReleaseUrl); + if (latestRelease) { + return csHttp.get(latestRelease.host, latestRelease.port, "/" + latestRelease.pathname)() + .then(function (json) { + //console.debug(json); + if (json && json.name && json.tag_name && json.html_url) { + return { + version: json.name, + url: json.html_url, + isNewer: (csHttp.version.compare(csConfig.version, json.name) < 0) + }; + } + }) + .catch(function(err) { + // silent (just log it) + console.error('[platform] Failed to get latest version', err); + }) + ; + } + return $q.when(); + } + function addListeners() { listeners = [ // Listen if node changed @@ -254,7 +278,10 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'] ready: ready, restart: restart, start: start, - stop: stop + stop: stop, + version: { + latest: getLatestRelease + } }; }) @@ -318,6 +345,18 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'] StatusBar.styleDefault(); } + // Get latest release + csPlatform.version.latest() + .then(function(release) { + if (release.isNewer) { + console.info('[app] New release detected: {0}'.format(release.version)); + $rootScope.newRelease = release; + } + else { + console.info('[app] Already use latest release {0}'.format(csConfig.version)); + } + }); + // Make sure platform is started return csPlatform.ready(); }); diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js index 455ab753..60c4de56 100644 --- a/www/js/services/device-services.js +++ b/www/js/services/device-services.js @@ -19,6 +19,7 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti // workaround to quickly no is device or not (even before the ready() event) enable: true }, + cache = {}, started = false, startPromise; @@ -204,12 +205,19 @@ angular.module('cesium.device.services', ['cesium.utils.services', 'cesium.setti }; exports.isDesktop = function() { - try { - // Has NodeJs + NW ? - return !!process && !!App; - } catch (err) { - return false; + if (!angular.isDefined(cache.isDesktop)) { + try { + // Should have NodeJs and NW + cache.isDesktop = !exports.enable && !!process && !!App; + } catch (err) { + cache.isDesktop = false; + } } + return cache.isDesktop; + }; + + exports.isWeb = function() { + return !exports.enable && !exports.isDesktop(); }; exports.ready = function() { diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js index 48032353..892cf86a 100644 --- a/www/js/services/http-services.js +++ b/www/js/services/http-services.js @@ -346,10 +346,71 @@ angular.module('cesium.http.services', ['cesium.cache.services']) return Math.floor(moment().utc().valueOf() / 1000); } + function isPositiveInteger(x) { + // http://stackoverflow.com/a/1019526/11236 + return /^\d+$/.test(x); + } + + /** + * Compare two software version numbers (e.g. 1.7.1) + * Returns: + * + * 0 if they're identical + * negative if v1 < v2 + * positive if v1 > v2 + * Nan if they in the wrong format + * + * E.g.: + * + * assert(version_number_compare("1.7.1", "1.6.10") > 0); + * assert(version_number_compare("1.7.1", "1.7.10") < 0); + * + * "Unit tests": http://jsfiddle.net/ripper234/Xv9WL/28/ + * + * Taken from http://stackoverflow.com/a/6832721/11236 + */ + function compareVersionNumbers(v1, v2){ + var v1parts = v1.split('.'); + var v2parts = v2.split('.'); + + // First, validate both numbers are true version numbers + function validateParts(parts) { + for (var i = 0; i < parts.length; ++i) { + if (!isPositiveInteger(parts[i])) { + return false; + } + } + return true; + } + if (!validateParts(v1parts) || !validateParts(v2parts)) { + return NaN; + } + + for (var i = 0; i < v1parts.length; ++i) { + if (v2parts.length === i) { + return 1; + } + + if (v1parts[i] === v2parts[i]) { + continue; + } + if (v1parts[i] > v2parts[i]) { + return 1; + } + return -1; + } + + if (v1parts.length != v2parts.length) { + return -1; + } + + return 0; + } + function isVersionCompatible(minVersion, actualVersion) { // TODO: add implementation console.debug('[http] TODO: implement check version [{0}] compatible with [{1}]'.format(actualVersion, minVersion)); - return true; + return compareVersionNumbers(minVersion, actualVersion) <= 0; } var cache = angular.copy(csCache.constants); @@ -374,6 +435,7 @@ angular.module('cesium.http.services', ['cesium.cache.services']) now: getDateNow }, version: { + compare: compareVersionNumbers, isCompatible: isVersionCompatible }, cache: cache diff --git a/www/js/services/modal-services.js b/www/js/services/modal-services.js index 3ad9f7cb..39de3652 100644 --- a/www/js/services/modal-services.js +++ b/www/js/services/modal-services.js @@ -1,11 +1,26 @@ angular.module('cesium.modal.services', []) // Useful for modal with no controller -.controller('EmptyModalCtrl', function ($scope, parameters) { +.controller('EmptyModalCtrl', function () { 'ngInject'; }) +.controller('AboutModalCtrl', function ($scope, UIUtils, csHttp) { + 'ngInject'; + + $scope.openLink = function(event, uri, options) { + options = options || {}; + + // If unable to open, just copy value + options.onError = function() { + return UIUtils.popover.copy(event, uri); + }; + + return csHttp.uri.open(uri, options); + }; +}) + .factory('ModalUtils', function($ionicModal, $rootScope, $q, $injector, $controller, $timeout) { 'ngInject'; @@ -164,7 +179,7 @@ angular.module('cesium.modal.services', []) } function showAbout(parameters) { - return ModalUtils.show('templates/modal_about.html','EmptyModalCtrl', + return ModalUtils.show('templates/modal_about.html','AboutModalCtrl', parameters); } diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index a1e1656d..26def58c 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -68,6 +68,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) uiEffects: true, minVersion: '1.1.0', newIssueUrl: "https://git.duniter.org/clients/cesium/cesium/issues/new", + latestReleaseUrl: "https://api.github.com/repos/duniter/cesium/releases/latest", helptip: { enable: true, installDocUrl: "https://duniter.org/en/wiki/duniter/install/", @@ -191,6 +192,8 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership; data.cacheTimeMs = defaultSettings.cacheTimeMs; data.timeout = defaultSettings.timeout; + data.minVersion = defaultSettings.minVersion; + data.latestReleaseUrl = defaultSettings.latestReleaseUrl; // Apply the new locale (only if need) if (localeChanged) { diff --git a/www/templates/menu.html b/www/templates/menu.html index aa01419d..7221d87c 100644 --- a/www/templates/menu.html +++ b/www/templates/menu.html @@ -200,14 +200,24 @@

diff --git a/www/templates/modal_about.html b/www/templates/modal_about.html index 9dd76499..9955c7a9 100644 --- a/www/templates/modal_about.html +++ b/www/templates/modal_about.html @@ -7,50 +7,61 @@

ABOUT.TITLE

-
-
-
- {{'COMMON.APP_NAME'|translate}} {{'COMMON.APP_VERSION'|translate:$root.config}} -

{{'COMMON.APP_BUILD'|translate:$root.config}}

- ABOUT.LICENSE -
-
-
-
- - {{'ABOUT.CODE' | translate}} -

https://git.duniter.org/clients/cesium/cesium

-
-
-
-
- - {{'ABOUT.FORUM' | translate}} -

https://forum.duniter.org -

-
-
-
- - {{'ABOUT.DEVELOPERS' | translate}} -

- cgeek, - DiG, - Benoit Lavenier -

-
-
-
-
- -

{{'ABOUT.DEV_WARNING'|translate}}

- ABOUT.DEV_WARNING_MESSAGE -
- ABOUT.REPORT_ISSUE -
-
+ + + {{'COMMON.APP_NAME'|translate}} {{'COMMON.APP_VERSION'|translate:$root.config}} + +

{{'COMMON.APP_BUILD'|translate:$root.config}}

+ ABOUT.LICENSE +
+ + + + + + + + + +

+ {{$root.newRelease.url}} +

+
+ + + + + ABOUT.PLEASE_REPORT_ISSUE +

+ ABOUT.REPORT_ISSUE +

+
+ + + + + + {{'ABOUT.CODE' | translate}} +

https://git.duniter.org/clients/cesium/cesium

+
+ + + + + {{'ABOUT.FORUM' | translate}} +

https://forum.duniter.org

+
+ + + + + {{'ABOUT.DEVELOPERS' | translate}} +

+ cgeek, + DiG, + Benoit Lavenier +

+