diff --git a/www/index.html b/www/index.html index 3efbaa0dd38de5916345510cfdf46e33ed079ae6..933daa740709e10bd25279f72f7f599dac29b86f 100644 --- a/www/index.html +++ b/www/index.html @@ -33,6 +33,7 @@ <script src="lib/ionic/js/angular/angular-translate-loader-static-files.min.js"></script> <script src="lib/ionic/js/angular/angular-messages.min.js"></script> <script src="lib/ionic/js/angular/angular-moment.min.js"></script> + <script src="lib/ionic/js/angular/angular-api.js"></script> <!-- crypto libs --> <script src="js/vendor/scrypt-em.js"></script> diff --git a/www/js/app.js b/www/js/app.js index 4a59bf3594fe7eafa9ab5338f850d6ef7ad066dc..2e5a51bbc589b4b3129356ef2017a453969dbc96 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -4,7 +4,7 @@ // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) // the 2nd parameter is an array of 'requires' // 'starter.controllers' is found in controllers.js -angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate', 'pascalprecht.translate', 'angularMoment', +angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate', 'pascalprecht.translate', 'angularMoment', 'ngApi', 'cesium.controllers', 'cesium.templates','cesium.translations', // removeIf(no-device) 'ngCordova', 'ionic-native-transitions', @@ -143,8 +143,8 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate', .config(function($ionicNativeTransitionsProvider){ 'ngInject'; // Use native transition - var enableNativeTransitions = (ionic.Platform.isAndroid() || ionic.Platform.isIOS()) && - ionic.Platform.grade.toLowerCase()=='a'; + var enableNativeTransitions = ionic.Platform.isAndroid() || ionic.Platform.isIOS()/*) && + ionic.Platform.grade.toLowerCase()=='a';*/ $ionicNativeTransitionsProvider.enable(enableNativeTransitions); }) // endRemoveIf(no-device) diff --git a/www/js/config.js b/www/js/config.js index 01bcddc725e2d5e9bc105a04f8a5c178db635b61..1756f746ea4e8012f5af4647a6d12e42276e09df 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -13,8 +13,8 @@ angular.module("cesium.config", []) "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug", "TIMEOUT": 4000, "DEBUG": false, - "VERSION": "0.1.25", - "BUILD_DATE": "2016-07-04T12:37:12.038Z" + "VERSION": "0.1.26", + "BUILD_DATE": "2016-07-04T15:23:49.649Z" }) -; \ No newline at end of file +; diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index fb8deb2bc9a80c2ed9528b07a0fee6618511db53..9c4ede326fa23e302d11714908b0c3f95badea0f 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -1,7 +1,7 @@ -angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services']) +angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services']) -.factory('Wallet', function($q, CryptoUtils, BMA, $translate, localStorage, $filter) { +.factory('Wallet', function($q, CryptoUtils, BMA, $translate, localStorage, $filter, Api) { 'ngInject'; Wallet = function(id) { @@ -53,6 +53,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', ' } }, + api = new Api(this, id), + resetData = function() { data.pubkey= null; data.keypair ={ @@ -552,7 +554,13 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', ' loadSources(), // Get transactions - loadTransactions() + loadTransactions(), + + // API extension + $q(function(resolve, reject){ + api.events.raise.loadData(); + resolve(); + }) ]) .then(function() { // Process transactions and sources @@ -990,6 +998,9 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', ' }); }; + // Register extension points + api.registerEvent('events', 'loadData'); + return { id: id, data: data, @@ -1013,7 +1024,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', ' // serialization toJson: toJson, fromJson: fromJson, - defaultSettings: defaultSettings + defaultSettings: defaultSettings, + api: api }; }; diff --git a/www/lib/ionic/js/angular/angular-api.js b/www/lib/ionic/js/angular/angular-api.js new file mode 100644 index 0000000000000000000000000000000000000000..909c1dc387a52acb8d186e6c1e604c5a4f221136 --- /dev/null +++ b/www/lib/ionic/js/angular/angular-api.js @@ -0,0 +1,155 @@ +// Source: https://github.com/Schweigi/angular-api-demo/blob/master/api.js +(function(window, angular, undefined) {'use strict'; + + // This file is adapted from Angular UI ngGrid project + // MIT License + // https://github.com/angular-ui/ng-grid/blob/v3.0.0-rc.20/src/js/core/factories/GridApi.js + angular.module('ngApi', []).factory('Api', ['$q', '$rootScope', function($q, $rootScope) { + /** + * Api provides the ability to register public methods events inside an app and allow + * for other components to use the api via featureName.raise.methodName and featureName.on.eventName(function(args){}). + * + * @appInstance: App which the API is for + * @apiId: Unique id in case multiple API instances do exist inside the same Angular environment + */ + var Api = function Api(appInstance, apiId) { + this.gantt = appInstance; + this.apiId = apiId; + this.eventListeners = []; + }; + + /** + * Used to execute a function while disabling the specified event listeners. + * Disables the listenerFunctions, executes the callbackFn, and then enables the listenerFunctions again + * + * @listenerFuncs: Listener function or array of listener functions to suppress. These must be the same + * @functions that were used in the .on.eventName method + * @callBackFn: Function to execute with surpressed events + * + * Example: + * var clicked = function (){ + * // Button clicked event handler + * } + * + * api.suppressEvents(clicked, function() { + * // No clicked events will be fired + * api.ui.form.main.submit.click(scope); + * }); + */ + Api.prototype.suppressEvents = function(listenerFuncs, callBackFn) { + var self = this; + var listeners = angular.isArray(listenerFuncs) ? listenerFuncs : [listenerFuncs]; + + var foundListeners = []; + listeners.forEach(function(l) { + foundListeners = self.eventListeners.filter(function(lstnr) { + return l === lstnr.handler; + }); + }); + + foundListeners.forEach(function(l) { + l.dereg(); + }); + + callBackFn(); + + foundListeners.forEach(function(l) { + l.dereg = registerEventWithAngular(l.eventId, l.handler, self.gantt, l._this); + }); + + }; + + /** + * Registers a new event for the given feature. + * + * @featureName: Name of the feature that raises the event + * @eventName: Name of the event + * + * To trigger the event call: + * .raise.eventName() + * + * To register a event listener call: + * .on.eventName(scope, callBackFn, _this) + * scope: A scope reference to add a deregister call to the scopes .$on('destroy') + * callBackFn: The function to call + * _this: Optional this context variable for callbackFn. If omitted, gantt.api will be used for the context + * + * .on.eventName returns a de-register funtion that will remove the listener. It's not necessary to use it as the listener + * will be removed when the scope is destroyed. + */ + Api.prototype.registerEvent = function(featureName, eventName) { + var self = this; + if (!self[featureName]) { + self[featureName] = {}; + } + + var feature = self[featureName]; + if (!feature.on) { + feature.on = {}; + feature.raise = {}; + } + + var eventId = 'event:api:' + this.apiId + ':' + featureName + ':' + eventName; + + // Creating raise event method: featureName.raise.eventName + feature.raise[eventName] = function() { + $rootScope.$emit.apply($rootScope, [eventId].concat(Array.prototype.slice.call(arguments))); + }; + + // Creating on event method: featureName.oneventName + feature.on[eventName] = function(scope, handler, _this) { + var deregAngularOn = registerEventWithAngular(eventId, handler, self.gantt, _this); + + var listener = { + handler: handler, + dereg: deregAngularOn, + eventId: eventId, + scope: scope, + _this: _this + }; + self.eventListeners.push(listener); + + var removeListener = function() { + listener.dereg(); + var index = self.eventListeners.indexOf(listener); + self.eventListeners.splice(index, 1); + }; + + scope.$on('$destroy', function() { + removeListener(); + }); + + return removeListener; + }; + }; + + function registerEventWithAngular(eventId, handler, app, _this) { + return $rootScope.$on(eventId, function() { + var args = Array.prototype.slice.call(arguments); + args.splice(0, 1); // Remove evt argument + handler.apply(_this ? _this : app, args); + }); + } + + /** + * Registers a new event for the given feature + * + * @featureName: Name of the feature + * @methodName: Name of the method + * @callBackFn: Function to execute + * @_this: Binds callBackFn 'this' to _this. Defaults to Api.app + */ + Api.prototype.registerMethod = function(featureName, methodName, callBackFn, _this) { + if (!this[featureName]) { + this[featureName] = {}; + } + + var feature = this[featureName]; + feature[methodName] = function() { + callBackFn.apply(_this || this.app, arguments); + }; + }; + + return Api; + }]); +})(window, window.angular);