diff --git a/app/config.json b/app/config.json index a2828157b93cf9685100fb20859373dc43ff5558..8b00dabb0849a9cd7204af33c82726387b0110d8 100644 --- a/app/config.json +++ b/app/config.json @@ -50,7 +50,7 @@ "initPhase": true, "expertMode": false, "decimalCount": 4, - "httpsMode": "clever", + "httpsMode": "force", "helptip": { "enable": true, "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index dda81b99799ef025c88dfdefca7937e170e05d99..0905a4b32bb5e8686bae893e05d9c294d018fa36 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -114,6 +114,7 @@ "PEER": "Duniter peer address", "USE_LOCAL_STORAGE": "Enable local storage", "ENABLE_HELPTIP": "Enable contextual help tips", + "ENABLE_UI_EFFECTS": "Enable visual effects", "HISTORY_SETTINGS": "My Account", "DISPLAY_UD_HISTORY": "Display produced dividends?", "AUTHENTICATION_SETTINGS": "Authentication", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 72d17d615ecacf6476fe8dd665c90fc51fcc04fe..9e5475167cd6d5dc6553eb5d52c52115ec93e0bf 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -114,6 +114,7 @@ "PEER": "Duniter peer address", "USE_LOCAL_STORAGE": "Enable local storage", "ENABLE_HELPTIP": "Enable contextual help tips", + "ENABLE_UI_EFFECTS": "Enable visual effects", "HISTORY_SETTINGS": "My Account", "DISPLAY_UD_HISTORY": "Display produced dividends?", "AUTHENTICATION_SETTINGS": "Authentication", diff --git a/www/js/config.js b/www/js/config.js index 401aab98d70952733dda01bc8a987a4b816e1354..e6d6d502ba19e243044e7db51ac185f9beb24bcf 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -38,7 +38,6 @@ angular.module("cesium.config", []) "askEnable": false, "host": "localhost", "port": 9200, - "wsPort": 9400, "notifications": { "txSent": true, "txReceived": true, @@ -52,4 +51,4 @@ angular.module("cesium.config", []) "newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug" }) -; \ No newline at end of file +; diff --git a/www/js/controllers/network-controllers.js b/www/js/controllers/network-controllers.js index 68c5c5d93771af3e4609749e368fe270fdbc9385..dafb1d7bb7c63a2c5487ed3fe074f965567b7719 100644 --- a/www/js/controllers/network-controllers.js +++ b/www/js/controllers/network-controllers.js @@ -153,7 +153,9 @@ function NetworkLookupController($scope, $state, $ionicHistory, $ionicPopover, $scope.search.memberPeersCount = data.memberPeersCount; // Always tru if network not started (e.g. after leave+renter the view) $scope.search.loading = !$scope.networkStarted || csNetwork.isBusy(); - $scope.motion.show({selector: '.item-peer'}); + if ($scope.motion && $scope.search.results && $scope.search.results.length > 0) { + $scope.motion.show({selector: '.item-peer'}); + } }; $scope.refresh = function() { diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js index 4c93074f0618071c80475ef8ba52d9514c9e14b3..e13027a2239b8a21c481ac55ec4ec0a0b2941983 100644 --- a/www/js/controllers/settings-controllers.js +++ b/www/js/controllers/settings-controllers.js @@ -76,25 +76,26 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt $scope.changeNode= function(node) { $scope.showNodePopup(node || $scope.formData.node) .then(function(newNode) { + console.log(newNode); if (newNode.host === $scope.formData.node.host && newNode.port === $scope.formData.node.port) { return; // same node = nothing to do } UIUtils.loading.show(); var nodeBMA = BMA.instance(newNode.host, newNode.port); - nodeBMA.node.summary() // ping the node - .then(function() { - UIUtils.loading.hide(); - $scope.formData.node = newNode; - BMA.copy(nodeBMA); - }) - .catch(function(err){ - UIUtils.loading.hide(); - UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY') - .then(function(){ - $scope.changeNode(newNode); // loop - }); - }); + nodeBMA.isAlive() + .then(function(alive) { + if (!alive) { + UIUtils.loading.hide(); + return UIUtils.alert.error('ERROR.INVALID_NODE_SUMMARY') + .then(function(){ + $scope.changeNode(newNode); // loop + }); + } + UIUtils.loading.hide(); + $scope.formData.node = newNode; + BMA.copy(nodeBMA); + }); }); }; diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js index 02369e476df238a91adc39749649a006bc2738db..63ab54f18b5cb9a879e9be22ee6af1c35d4195f6 100644 --- a/www/js/services/bma-services.js +++ b/www/js/services/bma-services.js @@ -1,15 +1,11 @@ //var Base58, Base64, scrypt_module_factory = null, nacl_factory = null; -angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'cesium.settings.services']) +angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.services', 'cesium.settings.services']) -.factory('BMA', function($q, csSettings, csHttp, csCache, $rootScope, $timeout) { +.factory('BMA', function($q, Api, Device, csSettings, csHttp, csCache, $rootScope, $timeout) { 'ngInject'; - function factory(host, port, cacheEnable) { - - function exact(regexpContent) { - return new RegExp("^" + regexpContent + "$"); - } + function BMA(host, port, useSsl, useCache) { var regex = { @@ -42,7 +38,172 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce LIMIT_REQUEST_COUNT: 5, // simultaneous async request to a Duniter node LIMIT_REQUEST_DELAY: 1000, // time (in second) to wait between to call of a rest request regex: regex + }, + listeners, + that = this; + + that.date = {now: csHttp.date.now}; + that.api = new Api(this, 'BMA-' + that.server); + + init(host, port, useSsl, useCache); + + function init(host, port, useSsl, useCache) { + if (!host) { + throw new Error('new BMA() need mandatory argument [host]'); + } + that.alive = false; + that.cache = _emptyCache(); + that.host = host; + that.port = port || 80; + that.useSsl = angular.isDefined(useSsl) ? useSsl : (that.port == 443); + that.useCache = angular.isDefined(useCache) ? useCache : false; + + that.server = csHttp.getServer(host, port); + that.url = csHttp.getUrl(host, port, useSsl); + } + + function exact(regexpContent) { + return new RegExp("^" + regexpContent + "$"); + } + + function _emptyCache() { + return { + getByPath: {}, + postByPath: {}, + wsByPath: {} }; + } + + that.cleanCache = function() { + console.debug('[BMA] Cleaning requests cache...'); + _.keys(that.cache.wsByPath).forEach(function(key) { + var sock = that.cache.wsByPath[key]; + sock.close(); + }); + that.cache = _emptyCache(); + }; + + get = function (path, cacheTime) { + cacheTime = that.useCache && cacheTime; + var cacheKey = path + (cacheTime ? ('#'+cacheTime) : ''); + return function(params) { + var request = that.cache.getByPath[cacheKey]; + if (!request) { + if (cacheTime) { + request = csHttp.getWithCache(that.host, that.port, path, that.useSsl, cacheTime); + } + else { + request = csHttp.get(that.host, that.port, path, that.useSsl); + } + that.cache.getByPath[cacheKey] = request; + } + return request(params); + }; + }; + + post = function(path) { + return function(obj, params) { + var request = that.cache.postByPath[path]; + if (!request) { + request = csHttp.post(that.host, that.port, path, that.useSsl); + that.cache.postByPath[path] = request; + } + return request(obj, params); + }; + }; + + ws = function(path) { + return function() { + var sock = that.cache.wsByPath[path]; + if (!sock) { + sock = csHttp.ws(that.host, that.port, path, that.useSsl); + that.cache.wsByPath[path] = sock; + } + return sock; + }; + }; + + that.isAlive = function() { + return that.node.summary() + .then(function(json) { + var isDuniter = json && json.duniter && json.duniter.software == 'duniter' && json.duniter.version; + var isCompatible = isDuniter && csHttp.version.isCompatible(csSettings.data.minVersion, json.duniter.version); + if (isDuniter && !isCompatible) { + console.error('[BMA] Uncompatible version [{0}] - expected at least [{1}]'.format(json.duniter.version, csSettings.data.minVersion)); + } + return isCompatible; + }) + .catch(function() { + return false; + }); + }; + + function removeListeners() { + _.forEach(listeners, function(remove){ + remove(); + }); + listeners = []; + } + + function addListeners() { + listeners = [ + // Listen if node changed + csSettings.api.data.on.changed($rootScope, onSettingsChanged, this) + ]; + } + + function onSettingsChanged(settings) { + + var server = csHttp.getUrl(settings.node.host, settings.node.port, '', settings.node.useSsl); + var hasChanged = (server != that.url); + if (hasChanged) { + init(settings.node.host, settings.node.port, settings.node.useSsl, that.useCache); + that.restart(); + } + } + + that.start = function() { + + console.debug('[BMA] Starting [{0}]...'.format(that.server)); + var now = new Date().getTime(); + + return that.isAlive() + .then(function(alive) { + that.alive = alive; + if (!alive) { + // TODO : alert user ? + console.error('[BMA] Could not start [{0}]: node unreachable'.format(that.server)); + return false; + } + + // Add listeners + if (!listeners || listeners.length === 0) { + addListeners(); + } + console.debug('[BMA] Started in '+(new Date().getTime()-now)+'ms'); + + that.api.node.raise.start(); + return true; + }); + }; + + that.stop = function() { + console.debug('[BMA] Stopping...'); + that.alive = false; + removeListeners(); + that.cleanCache(); + that.api.node.raise.stop(); + }; + + that.restart = function() { + that.stop(); + return $timeout(function() { + that.start(); + }, 200); + }; + + that.api.registerEvent('node', 'start'); + that.api.registerEvent('node', 'stop'); var exports = { errorCodes: errorCodes, @@ -57,61 +218,61 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce BMAS_ENDPOINT: exact(regex.BMAS_ENDPOINT) }, node: { - server: csHttp.getServer(host, port), - url: csHttp.getUrl(host, port), + server: that.server, + url: that.url, host: host, port: port, - summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG), + summary: get('/node/summary', csHttp.cache.LONG), same: function(host2, port2) { return host2 == host && ((!port && !port2) || (port == port2)); } }, network: { peering: { - self: csHttp.get(host, port, '/network/peering'), - peers: csHttp.get(host, port, '/network/peering/peers') + self: get('/network/peering'), + peers: get('/network/peering/peers') }, - peers: csHttp.get(host, port, '/network/peers') + peers: get('/network/peers') }, wot: { - lookup: csHttp.get(host, port, '/wot/lookup/:search'), - certifiedBy: csHttp.get(host, port, '/wot/certified-by/:pubkey'), - certifiersOf: csHttp.get(host, port, '/wot/certifiers-of/:pubkey'), + lookup: get('/wot/lookup/:search'), + certifiedBy: get('/wot/certified-by/:pubkey'), + certifiersOf: get('/wot/certifiers-of/:pubkey'), member: { - all: cacheEnable ? csHttp.getWithCache(host, port, '/wot/members') : csHttp.get(host, port, '/wot/members'), - pending: csHttp.get(host, port, '/wot/pending') + all: get('/wot/members', csHttp.cache.LONG), + pending: get('/wot/pending') }, - requirements: csHttp.get(host, port, '/wot/requirements/:pubkey'), - add: csHttp.post(host, port, '/wot/add'), - certify: csHttp.post(host, port, '/wot/certify'), - revoke: csHttp.post(host, port, '/wot/revoke') + requirements: get('/wot/requirements/:pubkey'), + add: post('/wot/add'), + certify: post('/wot/certify'), + revoke: post('/wot/revoke') }, blockchain: { - parameters: csHttp.getWithCache(host, port, '/blockchain/parameters', csHttp.cache.LONG), - block: cacheEnable ? csHttp.getWithCache(host, port, '/blockchain/block/:block', csHttp.cache.SHORT) : csHttp.get(host, port, '/blockchain/block/:block'), - blocksSlice: csHttp.get(host, port, '/blockchain/blocks/:count/:from'), - current: csHttp.get(host, port, '/blockchain/current'), - membership: csHttp.post(host, port, '/blockchain/membership'), + parameters: get('/blockchain/parameters', csHttp.cache.LONG), + block: get('/blockchain/block/:block', csHttp.cache.SHORT), + blocksSlice: get('/blockchain/blocks/:count/:from'), + current: get('/blockchain/current'), + membership: post('/blockchain/membership'), stats: { - ud: cacheEnable ? csHttp.getWithCache(host, port, '/blockchain/with/ud', csHttp.cache.SHORT) : csHttp.get(host, port, '/blockchain/with/ud'), - tx: csHttp.get(host, port, '/blockchain/with/tx'), - newcomers: csHttp.get(host, port, '/blockchain/with/newcomers'), - hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey') + ud: get('/blockchain/with/ud', csHttp.cache.SHORT), + tx: get('/blockchain/with/tx'), + newcomers: get('/blockchain/with/newcomers'), + hardship: get('/blockchain/hardship/:pubkey') } }, tx: { - sources: csHttp.get(host, port, '/tx/sources/:pubkey'), - process: csHttp.post(host, port, '/tx/process'), + sources: get('/tx/sources/:pubkey'), + process: post('/tx/process'), history: { - all: csHttp.get(host, port, '/tx/history/:pubkey'), - times: cacheEnable ? csHttp.getWithCache(host, port, '/tx/history/:pubkey/times/:from/:to') : csHttp.get(host, port, '/tx/history/:pubkey/times/:from/:to'), - timesNoCache: csHttp.get(host, port, '/tx/history/:pubkey/times/:from/:to'), - blocks: cacheEnable ? csHttp.getWithCache(host, port, '/tx/history/:pubkey/blocks/:from/:to') : csHttp.get(host, port, '/tx/history/:pubkey/blocks/:from/:to'), - pending: csHttp.get(host, port, '/tx/history/:pubkey/pending') + all: get('/tx/history/:pubkey'), + times: get('/tx/history/:pubkey/times/:from/:to', csHttp.cache.LONG), + timesNoCache: get('/tx/history/:pubkey/times/:from/:to'), + blocks: get('/tx/history/:pubkey/blocks/:from/:to', csHttp.cache.LONG), + pending: get('/tx/history/:pubkey/pending') } }, ud: { - history: csHttp.get(host, port, '/ud/history/:pubkey') + history: get('/ud/history/:pubkey') }, uri: {}, raw: { @@ -119,26 +280,6 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce } }; - exports.lightInstance = function(host, port) { - return { - node: { - summary: csHttp.getWithCache(host, port, '/node/summary', csHttp.cache.LONG) - }, - network: { - peering: { - self: csHttp.get(host, port, '/network/peering') - }, - peers: csHttp.get(host, port, '/network/peers') - }, - blockchain: { - current: csHttp.get(host, port, '/blockchain/current'), - stats: { - hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey') - } - } - }; - }; - exports.node.parseEndPoint = function(endpoint) { var matches = exports.regex.BMA_ENDPOINT.exec(endpoint); if (!matches) return; @@ -151,15 +292,8 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce }; exports.copy = function(otherNode) { - if (!!this.instance) { // if main service impl - var instance = this.instance; // keep factory - csCache.clearAll(); // clean all caches - angular.copy(otherNode, this); - this.instance = instance; - } - else { - angular.copy(otherNode, this); - } + init(otherNode.host, otherNode.port, otherNode.useSsl, that.useCache); + return that.restart(); }; exports.wot.member.uids = function() { @@ -277,6 +411,8 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce if (exact(regex.PUBKEY).test(uri)) { resolve({ pubkey: uri + + }); } else if(uri.startsWith('duniter://')) { @@ -377,31 +513,49 @@ angular.module('cesium.bma.services', ['ngResource', 'cesium.http.services', 'ce }; exports.websocket = { - block: function() { - return csHttp.ws((exports.node.port == 443 ? 'wss' : 'ws') + '://' + exports.node.server + '/ws/block'); - }, - peer: function() { - return csHttp.ws((exports.node.port == 443 ? 'wss' : 'ws') + '://' + exports.node.server + '/ws/peer'); - }, + block: ws('/ws/block'), + peer: ws('/ws/peer'), close : csHttp.closeAllWs }; - return exports; + angular.merge(that, exports); } - var service = factory(csSettings.data.node.host, csSettings.data.node.port, true /*cache*/); - service.instance = factory; + var service = new BMA( + csSettings.data.node.host, + csSettings.data.node.port, + csSettings.data.node.port == 443 || csSettings.data.node.useSsl, + true /*cache*/); - // Listen settings changes - csSettings.api.data.on.changed($rootScope, function(settings) { - - var nodeServer = csHttp.getServer(settings.node.host, settings.node.port); - if (nodeServer != service.node.server) { - var newService = factory(settings.node.host, settings.node.port, true /*cache*/); - service.copy(newService); // reload service - } + service.instance = function(host, port, useSsl, useCache) { + return new BMA(host, port, useSsl, useCache); + }; - }); + service.lightInstance = function(host, port, useSsl) { + port = port || 80; + useSsl = angular.isDefined(useSsl) ? useSsl : (port == 443); + return { + node: { + summary: csHttp.getWithCache(host, port, '/node/summary', useSsl, csHttp.cache.LONG) + }, + network: { + peering: { + self: csHttp.get(host, port, '/network/peering', useSsl) + }, + peers: csHttp.get(host, port, '/network/peers', useSsl) + }, + blockchain: { + current: csHttp.get(host, port, '/blockchain/current', useSsl), + stats: { + hardship: csHttp.get(host, port, '/blockchain/hardship/:pubkey', useSsl) + } + } + }; + }; + /*Device.ready().then(function() { + return service.start(); + });*/ + service.start(); return service; }) diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js index 0e276ba9549ef23054611d879ce241779536f617..92948c4386101ed1ff28959795a17b3749a337bd 100644 --- a/www/js/services/http-services.js +++ b/www/js/services/http-services.js @@ -3,256 +3,279 @@ angular.module('cesium.http.services', ['ngResource', 'cesium.cache.services']) .factory('csHttp', function($http, $q, csSettings, csCache, $timeout) { 'ngInject'; - function factory(timeout) { + var timeout = csSettings.data.timeout; - var - sockets = [], - cachePrefix = 'csHttp' - ; + var + sockets = [], + cachePrefix = 'csHttp' + ; - if (!timeout) { - timeout=4000; // default - } + if (!timeout) { + timeout=4000; // default + } - function getServer(host, port) { - return !host ? null : (host + (port ? ':' + port : '')); - } + function getServer(host, port) { + return !host ? null : (host + (port ? ':' + port : '')); + } - function getUrl(host, port, path, useSsl) { - var protocol = (port == 443 || useSsl) ? 'https' : 'http'; - return protocol + '://' + getServer(host, port) + (path ? path : ''); - } + function getUrl(host, port, path, useSsl) { + var protocol = (port == 443 || useSsl) ? 'https' : 'http'; + return protocol + '://' + getServer(host, port) + (path ? path : ''); + } - function processError(reject, data, url, status) { - if (data && data.message) { - reject(data); + function getWsUrl(host, port, path, useSsl) { + var protocol = (port == 443 || useSsl) ? 'wss' : 'ws'; + return protocol + '://' + getServer(host, port) + (path ? path : ''); + } + + function processError(reject, data, url, status) { + if (data && data.message) { + reject(data); + } + else { + if (status == 404) { + reject({ucode: 404, message: 'Resource not found ' + (url ? ' ('+url+')' : '')}); + } + if (url) { + reject('Error from node (' + url + ')'); } else { - if (status == 404) { - reject({ucode: 404, message: 'Resource not found ' + (url ? ' ('+url+')' : '')}); - } - if (url) { - reject('Error from node (' + url + ')'); - } - else { - reject('Unknown error from node'); - } + reject('Unknown error from node'); } } + } - function prepare(url, params, config, callback) { - var pkeys = [], queryParams = {}, newUri = url; - if (typeof params == 'object') { - pkeys = _.keys(params); - } - - _.forEach(pkeys, function(pkey){ - var prevURI = newUri; - newUri = newUri.replace(':' + pkey, params[pkey]); - if (prevURI == newUri) { - queryParams[pkey] = params[pkey]; - } - }); - config.params = queryParams; - return callback(newUri, config); + function prepare(url, params, config, callback) { + var pkeys = [], queryParams = {}, newUri = url; + if (typeof params == 'object') { + pkeys = _.keys(params); } - function getResource(host, port, path) { - var url = getUrl(host, port, path); - return function(params) { - return $q(function(resolve, reject) { - var config = { - timeout: timeout - }; + _.forEach(pkeys, function(pkey){ + var prevURI = newUri; + newUri = newUri.replace(':' + pkey, params[pkey]); + if (prevURI == newUri) { + queryParams[pkey] = params[pkey]; + } + }); + config.params = queryParams; + return callback(newUri, config); + } - prepare(url, params, config, function(url, config) { - $http.get(url, config) - .success(function(data, status, headers, config) { - resolve(data); - }) - .error(function(data, status, headers, config) { - processError(reject, data, url, status); - }); - }); + function getResource(host, port, path, useSsl) { + var url = getUrl(host, port, path, useSsl); + return function(params) { + return $q(function(resolve, reject) { + var config = { + timeout: timeout + }; + + prepare(url, params, config, function(url, config) { + $http.get(url, config) + .success(function(data, status, headers, config) { + resolve(data); + }) + .error(function(data, status, headers, config) { + processError(reject, data, url, status); + }); }); - }; - } + }); + }; + } - function getResourceWithCache(host, port, path, maxAge, autoRefresh) { - var url = getUrl(host, port, path); - maxAge = maxAge || csCache.constants.LONG; - //console.debug('[http] will cache ['+url+'] ' + maxAge + 'ms' + (autoRefresh ? ' with auto-refresh' : '')); + function getResourceWithCache(host, port, path, useSsl, maxAge, autoRefresh) { + var url = getUrl(host, port, path, useSsl); + maxAge = maxAge || csCache.constants.LONG; + //console.debug('[http] will cache ['+url+'] ' + maxAge + 'ms' + (autoRefresh ? ' with auto-refresh' : '')); - return function(params) { - return $q(function(resolve, reject) { - var config = { - timeout: timeout - }; - if (autoRefresh) { // redo the request if need - config.cache = csCache.get(cachePrefix, maxAge, function (key, value) { - console.debug('[http] Refreshing cache for ['+key+'] '); - $http.get(key, config) - .success(function (data) { - config.cache.put(key, data); - }); + return function(params) { + return $q(function(resolve, reject) { + var config = { + timeout: timeout + }; + if (autoRefresh) { // redo the request if need + config.cache = csCache.get(cachePrefix, maxAge, function (key, value) { + console.debug('[http] Refreshing cache for ['+key+'] '); + $http.get(key, config) + .success(function (data) { + config.cache.put(key, data); }); - } - else { - config.cache = csCache.get(cachePrefix, maxAge); - } + }); + } + else { + config.cache = csCache.get(cachePrefix, maxAge); + } - prepare(url, params, config, function(url, config) { - $http.get(url, config) - .success(function(data) { - resolve(data); - }) - .error(function(data, status) { - processError(reject, data, url, status); - }); - }); + prepare(url, params, config, function(url, config) { + $http.get(url, config) + .success(function(data) { + resolve(data); + }) + .error(function(data, status) { + processError(reject, data, url, status); + }); }); - }; - } + }); + }; + } - function postResource(host, port, path) { - var url = getUrl(host, port, path); - return function(data, params) { - return $q(function(resolve, reject) { - var config = { - timeout: timeout, - headers : {'Content-Type' : 'application/json'} - }; + function postResource(host, port, path) { + var url = getUrl(host, port, path); + return function(data, params) { + return $q(function(resolve, reject) { + var config = { + timeout: timeout, + headers : {'Content-Type' : 'application/json'} // TODO: test using "application/json;charset=UTF-8" + }; - prepare(url, params, config, function(url, config) { - $http.post(url, data, config) - .success(function(data) { - resolve(data); - }) - .error(function(data, status) { - processError(reject, data, status); - }); - }); + prepare(url, params, config, function(url, config) { + $http.post(url, data, config) + .success(function(data) { + resolve(data); + }) + .error(function(data, status) { + processError(reject, data, status); + }); }); - }; - } + }); + }; + } - function ws(host, port, path, useSsl) { - var uri = ((port == 443 || useSsl) ? 'wss' : 'ws') + '://' + getServer(host, port) + path; - var sock = null; - var callbacks = []; + function ws(host, port, path, useSsl) { + if (!path) { + console.error('calling csHttp.ws without path argument'); + throw 'calling csHttp.ws without path argument'; + } + var uri = getWsUrl(host, port, path, useSsl); + var sock = null; + var callbacks = []; - function _waitOpen() { - if (!sock) throw new Error('Websocket not opened'); - if (sock.readyState == 1) { - return $q.when(sock); - } - if (sock.readyState == 3) { - return $q.reject('Unable to connect to Websocket ['+sock.url+']'); - } - return $timeout(_waitOpen, 100); + function _waitOpen() { + if (!sock) throw new Error('Websocket not opened'); + if (sock.readyState == 1) { + return $q.when(sock); } - - function _open(self, callback, params) { - if (!sock) { - prepare(uri, params, {}, function(uri) { - console.debug('[http] Listening on websocket ['+path+']...'); - sock = new WebSocket(uri); - sock.onerror = function(e) { - sock.readyState=3; - }; - sock.onmessage = function(e) { - var obj = JSON.parse(e.data); - _.forEach(callbacks, function(callback) { - callback(obj); - }); - }; - sockets.push(self); - }); - } - if (callback) callbacks.push(callback); - return _waitOpen(); + if (sock.readyState == 3) { + return $q.reject('Unable to connect to Websocket ['+sock.url+']'); } - - return { - open: function(params) { - return _open(this, null, params); - }, - on: function(callback, params) { - return _open(this, callback, params); - }, - send: function(data) { - return _waitOpen() - .then(function(){ - sock.send(data); - }); - }, - close: function() { - if (sock) { - console.debug('[http] Stopping websocket ['+path+']...'); - sock.close(); - sock = null; - callbacks = []; - } - } - }; + return $timeout(_waitOpen, 100); } - function closeAllWs() { - if (sockets.length > 0) { - _.forEach(sockets, function(sock) { - sock.close(); + function _open(self, callback, params) { + if (!sock) { + prepare(uri, params, {}, function(uri) { + console.debug('[http] Listening on websocket ['+path+']...'); + sock = new WebSocket(uri); + sock.onerror = function(e) { + sock.readyState=3; + }; + sock.onmessage = function(e) { + var obj = JSON.parse(e.data); + _.forEach(callbacks, function(callback) { + callback(obj); + }); + }; + sockets.push(self); }); - sockets = []; // Reset socks list } + if (callback) callbacks.push(callback); + return _waitOpen(); } - // See doc : https://gist.github.com/jlong/2428561 - function parseUri(uri) { - var protocol; - if (uri.startsWith('duniter://')) { - protocol = 'duniter'; - uri = uri.replace('duniter://', 'http://'); + return { + open: function(params) { + return _open(this, null, params); + }, + on: function(callback, params) { + return _open(this, callback, params); + }, + send: function(data) { + return _waitOpen() + .then(function(){ + sock.send(data); + }); + }, + close: function() { + if (sock) { + console.debug('[http] Stopping websocket ['+path+']...'); + sock.close(); + sock = null; + callbacks = []; + } } + }; + } - var parser = document.createElement('a'); - parser.href = uri; + function closeAllWs() { + if (sockets.length > 0) { + _.forEach(sockets, function(sock) { + sock.close(); + }); + sockets = []; // Reset socks list + } + } - var pathname = parser.pathname; - if (pathname && pathname.startsWith('/')) { - pathname = pathname.substring(1); - } + // See doc : https://gist.github.com/jlong/2428561 + function parseUri(uri) { + var protocol; + if (uri.startsWith('duniter://')) { + protocol = 'duniter'; + uri = uri.replace('duniter://', 'http://'); + } - result = { - protocol: protocol ? protocol : parser.protocol, - hostname: parser.hostname, - host: parser.host, - port: parser.port, - username: parser.username, - password: parser.password, - pathname: pathname, - search: parser.search, - hash: parser.hash - }; - parser.remove(); - return result; + var parser = document.createElement('a'); + parser.href = uri; + + var pathname = parser.pathname; + if (pathname && pathname.startsWith('/')) { + pathname = pathname.substring(1); } - return { - get: getResource, - getWithCache: getResourceWithCache, - post: postResource, - ws: ws, - closeAllWs: closeAllWs, - getUrl : getUrl, - getServer: getServer, - uri: { - parse: parseUri - }, - cache: csCache.constants + result = { + protocol: protocol ? protocol : parser.protocol, + hostname: parser.hostname, + host: parser.host, + port: parser.port, + username: parser.username, + password: parser.password, + pathname: pathname, + search: parser.search, + hash: parser.hash }; + parser.remove(); + return result; + } + + // Get time (UTC) + function getDateNow() { + return Math.floor(moment().utc().valueOf() / 1000); } - return factory(csSettings.data.timeout); + function isVersionCompatible(minVersion, actualVersion) { + // TODO: add implementation + console.debug('[http] TODO: implement check version [{0}] compatible with [{1}]'.format(actualVersion, minVersion)); + return true; + } + + return { + get: getResource, + getWithCache: getResourceWithCache, + post: postResource, + ws: ws, + closeAllWs: closeAllWs, + getUrl : getUrl, + getServer: getServer, + uri: { + parse: parseUri + }, + date: { + now: getDateNow + }, + version: { + isCompatible: isVersionCompatible + }, + cache: csCache.constants + }; }) ; diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index 6c763ba3a2d1a96fb2de4c4180396b6858bf9234..53dca121e713343731af846b91ee184f70bc704a 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -58,6 +58,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi decimalCount: 4, forceNetworkViewToHttp: false, uiEffects: true, + minVersion: csConfig.compatProtocol_0_80 ? '0.80.0' : '0.90.0', // TODO update this if need newIssueUrl: "https://github.com/duniter/cesium/issues/new?labels=bug", helptip: { enable: true, @@ -86,8 +87,12 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi api = new Api(this, "csSettings"), reset = function() { + _.keys(data).forEach(function(key){ + delete data[key]; + }); angular.merge(data, defaultSettings); - store(); + api.data.raisePromise.reset(data) + .then(store); }, getByPath = function(path, defaultValue) { @@ -198,6 +203,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi }); }; + api.registerEvent('data', 'reset'); api.registerEvent('data', 'changed'); api.registerEvent('data', 'store'); api.registerEvent('data', 'ready'); @@ -215,7 +221,7 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi }; } - var service = Factory(); + var service = new Factory(); service.restore() .then(function() { diff --git a/www/plugins/es/i18n/locale-en-GB.json b/www/plugins/es/i18n/locale-en-GB.json index 83d3acdce5af2dbaddb0698437eafc465e5bc14f..a6871c8f34feee0c21147810b0a631b022be2bb2 100644 --- a/www/plugins/es/i18n/locale-en-GB.json +++ b/www/plugins/es/i18n/locale-en-GB.json @@ -31,6 +31,9 @@ }, "EVENT": { "MEMBER_WITHOUT_PROFILE": "To obtain your certification more quickly, fill in <a href=\"#/app/user/profile/edit\">your user profile</a>. Members will more easily put their trust in a verifiable identity." + }, + "ERROR": { + "WS_CONNECTION_FAILED": "Cesium can not receive notifications because of a technical error (connection to the Cesium + data node).<br/><br/>If the problem persists, please <b>choose another data node</b> in Cesium+ settings." } }, "COMMENTS": { diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json index 83d3acdce5af2dbaddb0698437eafc465e5bc14f..a6871c8f34feee0c21147810b0a631b022be2bb2 100644 --- a/www/plugins/es/i18n/locale-en.json +++ b/www/plugins/es/i18n/locale-en.json @@ -31,6 +31,9 @@ }, "EVENT": { "MEMBER_WITHOUT_PROFILE": "To obtain your certification more quickly, fill in <a href=\"#/app/user/profile/edit\">your user profile</a>. Members will more easily put their trust in a verifiable identity." + }, + "ERROR": { + "WS_CONNECTION_FAILED": "Cesium can not receive notifications because of a technical error (connection to the Cesium + data node).<br/><br/>If the problem persists, please <b>choose another data node</b> in Cesium+ settings." } }, "COMMENTS": { diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json index 9c2e50753955a154acb5c980daf19fb6cdad418c..d609686f9f1efe9890747473d23f115ef0441bdf 100644 --- a/www/plugins/es/i18n/locale-fr-FR.json +++ b/www/plugins/es/i18n/locale-fr-FR.json @@ -33,7 +33,7 @@ "MEMBER_WITHOUT_PROFILE": "Pour obtenir vos certifications plus rapidement, completez <a href=\"#/app/user/profile/edit\">votre profil utilisateur</a>. Les membres accorderont plus facilement leur confiance à une identité vérifiable." }, "ERROR": { - "WS_CONNECTION_FAILED": "Cesium ne peut plus recevoir les nouvelles notifications, à cause d'une erreur technique (connexion au noeud de noeud Cesium+).<br/><br/>Si le problème persiste, veuillez <b>changer de noeud de données</b> dans les paramètres de l'extension Cesium+." + "WS_CONNECTION_FAILED": "Cesium ne peut pas recevoir les notifications, à cause d'une erreur technique (connexion au noeud de données Cesium+).<br/><br/>Si le problème persiste, veuillez <b>choisir un autre noeud de données</b> dans les paramètres Cesium+." } }, "COMMENTS": { diff --git a/www/plugins/es/js/controllers/message-controllers.js b/www/plugins/es/js/controllers/message-controllers.js index 4e7e04c977b3664032c3ae6829344f291fd25aa1..49d5b30b1a439133880a014d2ccf250d95f96d03 100644 --- a/www/plugins/es/js/controllers/message-controllers.js +++ b/www/plugins/es/js/controllers/message-controllers.js @@ -52,7 +52,7 @@ angular.module('cesium.es.message.controllers', ['cesium.es.services']) ; -function ESMessageListController($scope, $rootScope, $state, $timeout, $translate, $ionicHistory, $ionicPopover, +function ESMessageListController($scope, $rootScope, $state, $translate, $ionicHistory, $ionicPopover, esModals, UIUtils, esMessage) { 'ngInject'; @@ -480,7 +480,7 @@ function ESMessageViewController($scope, $state, $timeout, $translate, $ionicHis }; } -function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, esNotification, esMessage, esModals) { +function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, esHttp, esNotification, esMessage, esModals) { 'ngInject'; var defaultSearchLimit = 40; @@ -493,6 +493,12 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e limit: defaultSearchLimit }; + $scope.$on('popover.shown', function() { + if ($scope.search.loading) { + $scope.load(); + } + }); + $scope.load = function(from, size) { var options = {}; options.from = from || 0; @@ -570,7 +576,6 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e delete $scope.search.limit; }; - csWallet.api.data.on.logout($scope, $scope.resetData); /* -- Modals -- */ @@ -582,11 +587,11 @@ function PopoverMessageController($scope, $timeout, UIUtils, $state, csWallet, e }); }; - esNotification.api.data.on.new($scope, $scope.onNewNotification); + /* -- listeners -- */ - /* -- default popover action -- */ - if ($scope.search.loading) { - $scope.load(); - } + csWallet.api.data.on.logout($scope, $scope.resetData); + esHttp.api.node.on.stop($scope, $scope.resetData); + esHttp.api.node.on.start($scope, $scope.load); + esNotification.api.data.on.new($scope, $scope.onNewNotification); } diff --git a/www/plugins/es/js/controllers/notification-controllers.js b/www/plugins/es/js/controllers/notification-controllers.js index 586b8b805b80c3424dcd00375c2271e4d5e211b8..79102d32038b2a8a9951db47aab72cd82ba616f1 100644 --- a/www/plugins/es/js/controllers/notification-controllers.js +++ b/www/plugins/es/js/controllers/notification-controllers.js @@ -25,7 +25,7 @@ angular.module('cesium.es.notification.controllers', ['cesium.es.services']) ; -function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet, esNotification) { +function NotificationsController($scope, $rootScope, UIUtils, $state, esHttp, csWallet, esNotification) { 'ngInject'; var defaultSearchLimit = 40; @@ -128,7 +128,6 @@ function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet, $scope.updateView(); } }; - esNotification.api.data.on.new($scope, $scope.onNewNotification); $scope.resetData = function() { if ($scope.search.loading) return; @@ -138,8 +137,14 @@ function NotificationsController($scope, $rootScope, UIUtils, $state, csWallet, $scope.search.loading = true; delete $scope.search.limit; }; - // When logout: force reload + + /* -- listeners -- */ + + esNotification.api.data.on.new($scope, $scope.onNewNotification); csWallet.api.data.on.logout($scope, $scope.resetData); + esHttp.api.node.on.stop($scope, $scope.resetData); + esHttp.api.node.on.start($scope, $scope.load); + } function PopoverNotificationsController($scope, $timeout, $controller, UIUtils, $state, csWallet, csSettings) { diff --git a/www/plugins/es/js/controllers/settings-controllers.js b/www/plugins/es/js/controllers/settings-controllers.js index ff6ca7ba8601c8248a02287cdf8fd83f30f1cade..130ef5d3300cb2080794ae043dd260f0fe83d036 100644 --- a/www/plugins/es/js/controllers/settings-controllers.js +++ b/www/plugins/es/js/controllers/settings-controllers.js @@ -61,7 +61,8 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti angular.copy(csSettings.data.plugins.es) : { enable: false, host: null, - port: null + port: null, + wsPort: null }; $scope.loading = false; }); @@ -74,8 +75,9 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti $scope.changeEsNode= function(node) { $scope.showNodePopup(node || $scope.formData) .then(function(newNode) { - if (newNode.host === $scope.formData.host && - newNode.port === $scope.formData.port) { + if (newNode.host == $scope.formData.host && + newNode.port == $scope.formData.port && + newNode.wsPort == $scope.formData.wsPort) { UIUtils.loading.hide(); return; // same node = nothing to do } @@ -95,6 +97,7 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti UIUtils.loading.hide(); $scope.formData.host = newNode.host; $scope.formData.port = newNode.port; + $scope.formData.wsPort = newNode.wsPort; esHttp.copy(newEsNode); }); @@ -104,7 +107,15 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti // Show node popup $scope.showNodePopup = function(node) { return $q(function(resolve, reject) { - $scope.popupData.newNode = node.port ? [node.host, node.port].join(':') : node.host; + var parts = [node.host]; + if (node.wsPort && node.wsPort != (node.port||80)) { + parts.push(node.port||80); + parts.push(node.wsPort); + } + else if (node.port && node.port != 80) { + parts.push(node.port); + } + $scope.popupData.newNode = parts.join(':'); if (!!$scope.popupForm) { $scope.popupForm.$setPristine(); } @@ -139,10 +150,10 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti return; } var parts = node.split(':'); - parts[1] = parts[1] ? parts[1] : 80; resolve({ host: parts[0], - port: parts[1] + port: parts[1] || 80, + wsPort: parts[2] || parts[1] || 80 }); }); }); @@ -198,6 +209,7 @@ function ESPluginSettingsController ($scope, $q, $translate, $ionicPopup, UIUti $scope.$watch('formData', $scope.onFormChanged, true); $scope.getServer = function() { - return csHttp.getServer($scope.formData.host, $scope.formData.port); + var server = csHttp.getServer($scope.formData.host, $scope.formData.port != 80 ? $scope.formData.port : undefined); + return server + ($scope.formData.wsPort && $scope.formData.wsPort != $scope.formData.port ? ':' + $scope.formData.wsPort : ''); }; } diff --git a/www/plugins/es/js/entities/notification.js b/www/plugins/es/js/entities/notification.js index c7b553154be00d28f1d11d603396e7295041fdb2..54c61296bcb805eb148be0e07dacd2b118b62d38 100644 --- a/www/plugins/es/js/entities/notification.js +++ b/www/plugins/es/js/entities/notification.js @@ -8,7 +8,7 @@ function Notification(json, markAsReadCallback) { var that = this; - that.type = json.type.toLowerCase(); + that.type = json.type && json.type.toLowerCase(); that.time = json.time; that.hash = json.hash; that.read = json.read_signature ? true : false; diff --git a/www/plugins/es/js/services/http-services.js b/www/plugins/es/js/services/http-services.js index 6f6e4e8f6301fac80ca223aa4c4781d1f325acab..f2c6fd8052f335cf22d88b1b48193c8cf9316435 100644 --- a/www/plugins/es/js/services/http-services.js +++ b/www/plugins/es/js/services/http-services.js @@ -16,14 +16,13 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic USER_TAG: match('@(\\w+)') }; - this.cache = _emptyCache(); + that.cache = _emptyCache(); that.alive = false; that.host = host; that.port = port || 80; - that.wsPort = wsPort || 80; + that.wsPort = wsPort || port || 80; that.useSsl = angular.isDefined(useSsl) ? useSsl : false; that.server = csHttp.getServer(host, port); - that.date = {}; that.api = new Api(this, "esHttp"); function exact(regexpContent) { @@ -42,11 +41,11 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic } that.cleanCache = function() { + console.debug('[ES] [http] Cleaning requests cache...'); _.keys(that.cache.wsByPath).forEach(function(key) { var sock = that.cache.wsByPath[key]; sock.close(); }); - console.debug('[ES] [http] Cleaning requests cache'); that.cache = _emptyCache(); }; @@ -60,10 +59,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic }; // Get time (UTC) - that.date.now = function() { - // TODO : use the block chain time - return Math.floor(moment().utc().valueOf() / 1000); - }; + that.date = { now : csHttp.date.now }; that.getUrl = function(path) { return csHttp.getUrl(that.host, that.port, path, that.useSsl); @@ -131,7 +127,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic }; that.stop = function() { - console.debug('[ES] [http] Stopped'); + console.debug('[ES] [http] Stopping...'); that.alive = false; that.cleanCache(); that.api.node.raise.stop(); @@ -429,7 +425,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic var host = csSettings.data.plugins && csSettings.data.plugins.es ? csSettings.data.plugins.es.host : null; var port = host ? csSettings.data.plugins.es.port : null; - var wsPort = host ? csSettings.data.plugins.es.wsPort : port; + var wsPort = host ? csSettings.data.plugins.es.wsPort : null; var service = new Factory(host, port, wsPort); diff --git a/www/plugins/es/js/services/message-services.js b/www/plugins/es/js/services/message-services.js index 9a8afcf20042c20621b4d722edefe69a959fbd2f..937ef5ac67f76e8c5b0312da13c1bd599f1d1fd6 100644 --- a/www/plugins/es/js/services/message-services.js +++ b/www/plugins/es/js/services/message-services.js @@ -459,24 +459,27 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.services', ' } function addListeners() { - console.debug("[ES] [message] Enable"); - // Extend csWallet.loadData() listeners = [ csWallet.api.data.on.login($rootScope, onWalletLogin, this), csWallet.api.data.on.init($rootScope, onWalletInit, this), - csWallet.api.data.on.reset($rootScope, onWalletReset, this), + csWallet.api.data.on.reset($rootScope, onWalletReset, this) ]; } - function refreshListeners() { + function refreshState() { var enable = esHttp.alive; if (!enable && listeners && listeners.length > 0) { + console.debug("[ES] [message] Disable"); removeListeners(); + if (csWallet.isLogin()) { + onWalletReset(csWallet.data); + } } else if (enable && (!listeners || listeners.length === 0)) { + console.debug("[ES] [message] Enable"); addListeners(); - if (csWallet.isLogin() && !csWallet.data.messages) { + if (csWallet.isLogin()) { onWalletLogin(csWallet.data); } } @@ -484,9 +487,9 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.services', ' // Default action Device.ready().then(function() { - refreshListeners(); - esHttp.api.node.on.start($rootScope, refreshListeners, this); - esHttp.api.node.on.stop($rootScope, refreshListeners, this); + esHttp.api.node.on.start($rootScope, refreshState, this); + esHttp.api.node.on.stop($rootScope, refreshState, this); + return refreshState(); }); return { diff --git a/www/plugins/es/js/services/notification-services.js b/www/plugins/es/js/services/notification-services.js index 9d3469a6af53c0f9db2e7ae10194fa99c6f552bd..2180ba00a6d64afc4a7c78901ead3434ac9920b3 100644 --- a/www/plugins/es/js/services/notification-services.js +++ b/www/plugins/es/js/services/notification-services.js @@ -159,7 +159,7 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es notification.read = true; CryptoUtils.sign(notification.hash, csWallet.data.keypair) .then(function(signature){ - return postReadById(signature, {id:notification.id}); + return that.raw.postReadById(signature, {id:notification.id}); }) .catch(function(err) { console.error('Error while trying to mark event as read:' + (err.message ? err.message : err)); @@ -242,10 +242,13 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es ]; } - function refreshListeners() { + function refreshState() { var enable = esHttp.alive; if (!enable && listeners && listeners.length > 0) { removeListeners(); + if (csWallet.isLogin()) { + onWalletReset(csWallet.data); + } } else if (enable && (!listeners || listeners.length === 0)) { addListeners(); @@ -260,9 +263,9 @@ angular.module('cesium.es.notification.services', ['cesium.services', 'cesium.es // Default actions Device.ready().then(function() { - esHttp.api.node.on.start($rootScope, refreshListeners, this); - esHttp.api.node.on.stop($rootScope, refreshListeners, this); - return refreshListeners(); + esHttp.api.node.on.start($rootScope, refreshState, this); + esHttp.api.node.on.stop($rootScope, refreshState, this); + return refreshState(); }); return { diff --git a/www/plugins/es/js/services/settings-services.js b/www/plugins/es/js/services/settings-services.js index b835fa1e2275ca031e1bf0931e19574348f52fa8..c0c2dc81512c108699d517b2abf72103df501681 100644 --- a/www/plugins/es/js/services/settings-services.js +++ b/www/plugins/es/js/services/settings-services.js @@ -29,6 +29,19 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt excludes: ['installDocUrl'] } }, + defaultSettings = angular.merge({ + plugins: { + es: { + askEnable: false, + notifications: { + txSent: true, + txReceived: true, + certSent: true, + certReceived: true + } + } + } + }, {plugins: {es: csConfig.plugins && csConfig.plugins.es || {}}}), that = this, previousRemoteData, listeners, @@ -118,6 +131,13 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt }); } + function onSettingsReset(data, deferred) { + deferred = deferred || $q.defer(); + angular.merge(data, defaultSettings); + deferred.resolve(data); + return deferred.promise; + } + function onWalletLogin(data, deferred) { deferred = deferred || $q.defer(); if (!data || !data.pubkey || !data.keypair) { @@ -164,7 +184,7 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt var wasEnable = listeners && listeners.length > 0; - refreshListeners(); + refreshState(); var isEnable = that.isEnable(); if (csWallet.isLogin()) { @@ -250,7 +270,6 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt } function removeListeners() { - console.debug("[ES] [settings] Disable"); _.forEach(listeners, function(remove){ remove(); }); @@ -258,29 +277,33 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt } function addListeners() { - console.debug("[ES] [settings] Enable"); - // Extend csWallet.login() listeners = [ - csWallet.api.data.on.login($rootScope, onWalletLogin, this), - + csSettings.api.data.on.reset($rootScope, onSettingsReset, this), + csWallet.api.data.on.login($rootScope, onWalletLogin, this) ]; } - function refreshListeners() { + function refreshState() { var enable = that.isEnable(); + + // Disable if (!enable && listeners && listeners.length > 0) { + console.debug("[ES] [settings] Disable"); removeListeners(); return esHttp.stop(); } + + // Enable else if (enable && (!listeners || listeners.length === 0)) { return esHttp.start() .then(function(started) { if (!started) { // TODO : alert user ? - console.error('ES node could not be started !!'); + console.error('[ES] node could not be started !!'); } else { + console.debug("[ES] [settings] Enable"); addListeners(); if (csWallet.isLogin()) { return onWalletLogin(csWallet.data); @@ -296,7 +319,7 @@ angular.module('cesium.es.settings.services', ['cesium.services', 'cesium.es.htt esHttp.api.node.on.stop($rootScope, function() { previousRemoteData = null; }, this); - return refreshListeners(); + return refreshState(); }) .then(function() {