You do not have any wallet
diff --git a/src/css/main.css b/src/css/main.css
index 007adb6eb..b2b831fcd 100644
--- a/src/css/main.css
+++ b/src/css/main.css
@@ -1106,104 +1106,6 @@ input.ng-invalid-match, input.ng-invalid-match:focus {
cursor: pointer !important;
}
-
-
-
-.updating {
- -webkit-animation-iteration-count: infinite;
- -webkit-animation-name: up-animation;
- -webkit-animation-duration: 1s;
- -webkit-animation-iteration-count: infinite;
- animation-iteration-count: infinite;
- animation-name: up-animation;
- animation-duration: 1s;
- animation-iteration-count: infinite;
-}
-
-
-
-/* Generated with Bounce.js. Edit at http://goo.gl/Vn2Euz */
-
-@-webkit-keyframes up-animation {
- 0% { -webkit-transform: matrix3d(0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 3.4% { -webkit-transform: matrix3d(0.658, 0, 0, 0, 0, 0.703, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.658, 0, 0, 0, 0, 0.703, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 4.7% { -webkit-transform: matrix3d(0.725, 0, 0, 0, 0, 0.8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.725, 0, 0, 0, 0, 0.8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 6.81% { -webkit-transform: matrix3d(0.83, 0, 0, 0, 0, 0.946, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.83, 0, 0, 0, 0, 0.946, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 9.41% { -webkit-transform: matrix3d(0.942, 0, 0, 0, 0, 1.084, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.942, 0, 0, 0, 0, 1.084, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 10.21% { -webkit-transform: matrix3d(0.971, 0, 0, 0, 0, 1.113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.971, 0, 0, 0, 0, 1.113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 13.61% { -webkit-transform: matrix3d(1.062, 0, 0, 0, 0, 1.166, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.062, 0, 0, 0, 0, 1.166, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 14.11% { -webkit-transform: matrix3d(1.07, 0, 0, 0, 0, 1.165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.07, 0, 0, 0, 0, 1.165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 17.52% { -webkit-transform: matrix3d(1.104, 0, 0, 0, 0, 1.12, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.104, 0, 0, 0, 0, 1.12, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 18.72% { -webkit-transform: matrix3d(1.106, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.106, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 21.32% { -webkit-transform: matrix3d(1.098, 0, 0, 0, 0, 1.035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.098, 0, 0, 0, 0, 1.035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 24.32% { -webkit-transform: matrix3d(1.075, 0, 0, 0, 0, 0.98, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.075, 0, 0, 0, 0, 0.98, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 25.23% { -webkit-transform: matrix3d(1.067, 0, 0, 0, 0, 0.969, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.067, 0, 0, 0, 0, 0.969, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 29.03% { -webkit-transform: matrix3d(1.031, 0, 0, 0, 0, 0.948, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.031, 0, 0, 0, 0, 0.948, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 29.93% { -webkit-transform: matrix3d(1.024, 0, 0, 0, 0, 0.949, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.024, 0, 0, 0, 0, 0.949, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 35.54% { -webkit-transform: matrix3d(0.99, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.99, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 36.74% { -webkit-transform: matrix3d(0.986, 0, 0, 0, 0, 0.989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.986, 0, 0, 0, 0, 0.989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 41.04% { -webkit-transform: matrix3d(0.98, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.98, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 44.44% { -webkit-transform: matrix3d(0.983, 0, 0, 0, 0, 1.016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.983, 0, 0, 0, 0, 1.016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 52.15% { -webkit-transform: matrix3d(0.996, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.996, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 59.86% { -webkit-transform: matrix3d(1.003, 0, 0, 0, 0, 0.995, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.003, 0, 0, 0, 0, 0.995, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 63.26% { -webkit-transform: matrix3d(1.004, 0, 0, 0, 0, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.004, 0, 0, 0, 0, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 75.28% { -webkit-transform: matrix3d(1.001, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.001, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 85.49% { -webkit-transform: matrix3d(0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 90.69% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 100% { -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
-}
-
-
-@keyframes up-animation {
- 0% { transform: matrix3d(0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 3.4% { transform: matrix3d(0.658, 0, 0, 0, 0, 0.703, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.658, 0, 0, 0, 0, 0.703, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 4.7% { transform: matrix3d(0.725, 0, 0, 0, 0, 0.8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.725, 0, 0, 0, 0, 0.8, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 6.81% { transform: matrix3d(0.83, 0, 0, 0, 0, 0.946, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.83, 0, 0, 0, 0, 0.946, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 9.41% { transform: matrix3d(0.942, 0, 0, 0, 0, 1.084, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.942, 0, 0, 0, 0, 1.084, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 10.21% { transform: matrix3d(0.971, 0, 0, 0, 0, 1.113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.971, 0, 0, 0, 0, 1.113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 13.61% { transform: matrix3d(1.062, 0, 0, 0, 0, 1.166, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.062, 0, 0, 0, 0, 1.166, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 14.11% { transform: matrix3d(1.07, 0, 0, 0, 0, 1.165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.07, 0, 0, 0, 0, 1.165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 17.52% { transform: matrix3d(1.104, 0, 0, 0, 0, 1.12, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.104, 0, 0, 0, 0, 1.12, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 18.72% { transform: matrix3d(1.106, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.106, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 21.32% { transform: matrix3d(1.098, 0, 0, 0, 0, 1.035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.098, 0, 0, 0, 0, 1.035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 24.32% { transform: matrix3d(1.075, 0, 0, 0, 0, 0.98, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.075, 0, 0, 0, 0, 0.98, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 25.23% { transform: matrix3d(1.067, 0, 0, 0, 0, 0.969, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.067, 0, 0, 0, 0, 0.969, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 29.03% { transform: matrix3d(1.031, 0, 0, 0, 0, 0.948, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.031, 0, 0, 0, 0, 0.948, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 29.93% { transform: matrix3d(1.024, 0, 0, 0, 0, 0.949, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.024, 0, 0, 0, 0, 0.949, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 35.54% { transform: matrix3d(0.99, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.99, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 36.74% { transform: matrix3d(0.986, 0, 0, 0, 0, 0.989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.986, 0, 0, 0, 0, 0.989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 41.04% { transform: matrix3d(0.98, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.98, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 44.44% { transform: matrix3d(0.983, 0, 0, 0, 0, 1.016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.983, 0, 0, 0, 0, 1.016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 52.15% { transform: matrix3d(0.996, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.996, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 59.86% { transform: matrix3d(1.003, 0, 0, 0, 0, 0.995, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.003, 0, 0, 0, 0, 0.995, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 63.26% { transform: matrix3d(1.004, 0, 0, 0, 0, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.004, 0, 0, 0, 0, 0.996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 75.28% { transform: matrix3d(1.001, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1.001, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 85.49% { transform: matrix3d(0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 90.69% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
- 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
-}
-
-
-.opacityCycle {
- -webkit-animation-iteration-count: infinite;
- -webkit-animation-name: opCycle-animation;
- -webkit-animation-duration: 20s;
- -webkit-animation-iteration-count: infinite;
-}
-
-
-
-@-webkit-keyframes opCycle-animation
-{
-0% {opacity:1}
-15% {opacity:0.7}
-30% {opacity:0.85}
-45% {opacity:0.5}
-60% {opacity:0.8}
-75% {opacity:0.7}
-99% {opacity:1;}
-}
-
.onGoingProcess {
text-align: center;
max-width: 14.5rem;
diff --git a/src/js/controllers/history.js b/src/js/controllers/history.js
index 7dc20d6ec..9f9275abe 100644
--- a/src/js/controllers/history.js
+++ b/src/js/controllers/history.js
@@ -3,76 +3,4 @@
angular.module('copayApp.controllers').controller('historyController',
function($scope, $rootScope, $filter, $timeout, $modal, $log, profileService, notification, go, configService, rateService, lodash) {
- function strip(number) {
- return (parseFloat(number.toPrecision(12)));
- }
-
- var fc = profileService.focusedClient;
- var config = configService.getSync().wallet.settings;
- this.unitToSatoshi = config.unitToSatoshi;
- this.satToUnit = 1 / this.unitToSatoshi;
- this.unitName = config.unitName;
- this.alternativeIsoCode = config.alternativeIsoCode;
-
- this.getUnitName = function() {
- return this.unitName;
- };
-
- this.getAlternativeIsoCode = function() {
- return this.alternativeIsoCode;
- };
-
- this._addRates = function(txs, cb) {
- if (!txs || txs.length == 0) return cb();
- var index = lodash.groupBy(txs, 'rateTs');
-
- rateService.getHistoricRates(config.alternativeIsoCode, lodash.keys(index), function(err, res) {
- if (err || !res) return cb(err);
- lodash.each(res, function(r) {
- lodash.each(index[r.ts], function(tx) {
- var alternativeAmount = (r.rate != null ? tx.amount * rateService.SAT_TO_BTC * r.rate : null);
- tx.alternativeAmount = alternativeAmount ? $filter('noFractionNumber')(alternativeAmount, 2) : null;
- });
- });
- return cb();
- });
- };
-
- this.openTxModal = function(btx) {
- var self = this;
- var fc = profileService.focusedClient;
- var ModalInstanceCtrl = function($scope, $modalInstance) {
- $scope.btx = btx;
- $scope.settings = config;
- $scope.color = fc.backgroundColor;
-
- $scope.getAmount = function(amount) {
- return self.getAmount(amount);
- };
-
- $scope.getUnitName = function() {
- return self.getUnitName();
- };
-
- $scope.getShortNetworkName = function() {
- var n = fc.credentials.network;
- return n.substring(0, 4);
- };
-
- $scope.cancel = function() {
- $modalInstance.dismiss('cancel');
- };
- };
-
- $modal.open({
- templateUrl: 'views/modals/tx-details.html',
- windowClass: 'full',
- controller: ModalInstanceCtrl,
- });
- };
-
- this.hasAction = function(actions, action) {
- return actions.hasOwnProperty('create');
- };
-
});
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js
index 78fc79ad4..310ae7388 100644
--- a/src/js/controllers/index.js
+++ b/src/js/controllers/index.js
@@ -28,6 +28,8 @@ angular.module('copayApp.controllers').controller('indexController', function($r
'link': 'history'
}];
+ self.tab = 'walletHome';
+
self.availableLanguages = [{
name: 'English',
isoCode: 'en',
diff --git a/src/js/controllers/receive.js b/src/js/controllers/receive.js
index bd5d47acc..dd82b60f6 100644
--- a/src/js/controllers/receive.js
+++ b/src/js/controllers/receive.js
@@ -3,8 +3,6 @@
angular.module('copayApp.controllers').controller('receiveController',
function($rootScope, $scope, $timeout, $modal, $log, isCordova, isMobile, profileService, storageService) {
var self = this;
- var fc = profileService.focusedClient;
-
this.isCordova = isCordova;
self.addresses = [];
@@ -15,6 +13,7 @@ angular.module('copayApp.controllers').controller('receiveController',
$scope.$on('$destroy', newAddrListener);
this.newAddress = function() {
+ var fc = profileService.focusedClient;
self.generatingAddress = true;
self.error = null;
fc.createAddress(function(err, addr) {
@@ -32,6 +31,7 @@ angular.module('copayApp.controllers').controller('receiveController',
};
this.getAddress = function() {
+ var fc = profileService.focusedClient;
$timeout(function() {
storageService.getLastAddress(fc.credentials.walletId, function(err, addr) {
if (addr) {
diff --git a/src/js/controllers/walletHome.js b/src/js/controllers/walletHome.js
index 2450616cb..ff72de7f0 100644
--- a/src/js/controllers/walletHome.js
+++ b/src/js/controllers/walletHome.js
@@ -1,8 +1,57 @@
'use strict';
-angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, notification, txStatus, isCordova, profileService, lodash) {
+angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, notification, txStatus, isCordova, profileService, lodash, configService, rateService, storageService) {
+ var self = this;
$rootScope.hideMenuBar = false;
+ $rootScope.wpInputFocused = false;
+
+ // INIT
+ var config = configService.getSync().wallet.settings;
+ this.unitToSatoshi = config.unitToSatoshi;
+ this.satToUnit = 1 / this.unitToSatoshi;
+ this.unitName = config.unitName;
+ this.alternativeIsoCode = config.alternativeIsoCode;
+ this.alternativeName = config.alternativeName;
+ this.alternativeAmount = 0;
+ this.unitDecimals = config.unitDecimals;
+ this.isCordova = isCordova;
+ this.addresses = [];
+ this.isMobile = isMobile.any();
+ this.isWindowsPhoneApp = isMobile.Windows() && isCordova;
+ this.blockUx = false;
+ this.isRateAvailable = false;
+ this.showScanner = false;
+ this.isMobile = isMobile.any();
+
+ var disableScannerListener = $rootScope.$on('dataScanned', function(event, data) {
+ self.setForm(data);
+ });
+
+ var disablePaymentUriListener = $rootScope.$on('paymentUri', function(event, uri) {
+ $timeout(function() {
+ self.setForm(uri);
+ }, 100);
+ });
+
+ var disableAddrListener = $rootScope.$on('Local/NeedNewAddress', function() {
+ self.getAddress();
+ });
+
+ $scope.$on('$destroy', function() {
+ disableAddrListener();
+ disableScannerListener();
+ disablePaymentUriListener();
+ $rootScope.hideMenuBar = false;
+ });
+
+ rateService.whenAvailable(function() {
+ self.isRateAvailable = true;
+ $rootScope.$digest();
+ });
+
+ // walletHome
+
$scope.openCopayersModal = function(copayers, copayerId) {
var fc = profileService.focusedClient;
@@ -21,8 +70,6 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
});
};
-
-
$scope.openTxModal = function(tx, copayers) {
var fc = profileService.focusedClient;
var ModalInstanceCtrl = function($scope, $modalInstance) {
@@ -213,4 +260,509 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
};
+ // Receive
+
+ this.newAddress = function() {
+ var fc = profileService.focusedClient;
+ self.generatingAddress = true;
+ self.error = null;
+ fc.createAddress(function(err, addr) {
+ self.generatingAddress = false;
+ if (err) {
+ $log.debug('Creating address ERROR:', err);
+ $scope.$emit('Local/ClientError', err);
+ self.error = 'Could not generate address';
+ } else {
+ self.addr = addr.address;
+ storageService.storeLastAddress(fc.credentials.walletId, addr.address, function() {});
+ }
+ $scope.$digest();
+ });
+ };
+
+ this.getAddress = function() {
+ var fc = profileService.focusedClient;
+ $timeout(function() {
+ storageService.getLastAddress(fc.credentials.walletId, function(err, addr) {
+ if (addr) {
+ self.addr = addr;
+ } else {
+ self.newAddress();
+ }
+ });
+ });
+ };
+
+ this.copyAddress = function(addr) {
+ if (isCordova) {
+ window.cordova.plugins.clipboard.copy('bitcoin:' + addr);
+ window.plugins.toast.showShortCenter('Copied to clipboard');
+ }
+ };
+
+ this.shareAddress = function(addr) {
+ if (isCordova) {
+ if (isMobile.Android() || isMobile.Windows()) {
+ window.ignoreMobilePause = true;
+ }
+ window.plugins.socialsharing.share('bitcoin:' + addr, null, null, null);
+ }
+ };
+
+ // Send
+ this.resetError = function() {
+ this.error = this.success = null;
+ };
+
+
+ var hideMenuBar = lodash.debounce(function(hide) {
+ if (hide) {
+ $rootScope.hideMenuBar = true;
+ } else {
+ $rootScope.hideMenuBar = false;
+ }
+ $rootScope.$digest();
+ }, 100);
+
+
+ this.formFocus = function(what) {
+ if (isCordova) {
+ hideMenuBar(what);
+ }
+ if (!this.isWindowsPhoneApp) return
+
+ if (!what) {
+ this.hideAddress = false;
+ this.hideAmount = false;
+
+ } else {
+ if (what == 'amount') {
+ this.hideAddress = true;
+ } else if (what == 'msg') {
+ this.hideAddress = true;
+ this.hideAmount = true;
+ }
+ }
+ $timeout(function() {
+ $rootScope.$digest();
+ }, 1);
+ };
+
+ this.setInputs = function() {
+ var unitToSat = this.unitToSatoshi;
+ var satToUnit = 1 / unitToSat;
+ /**
+ * Setting the two related amounts as properties prevents an infinite
+ * recursion for watches while preserving the original angular updates
+ *
+ */
+ Object.defineProperty($scope,
+ "_alternative", {
+ get: function() {
+ return $scope.__alternative;
+ },
+ set: function(newValue) {
+ $scope.__alternative = newValue;
+ if (typeof(newValue) === 'number' && self.isRateAvailable) {
+ $scope._amount = parseFloat((rateService.fromFiat(newValue, self.alternativeIsoCode) * satToUnit).toFixed(self.unitDecimals), 10);
+ }
+ },
+ enumerable: true,
+ configurable: true
+ });
+ Object.defineProperty($scope,
+ "_amount", {
+ get: function() {
+ return $scope.__amount;
+ },
+ set: function(newValue) {
+ $scope.__amount = newValue;
+ if (typeof(newValue) === 'number' && self.isRateAvailable) {
+ $scope.__alternative = parseFloat((rateService.toFiat(newValue * self.unitToSatoshi, self.alternativeIsoCode)).toFixed(2), 10);
+ } else {
+ $scope.__alternative = 0;
+ }
+ self.alternativeAmount = $scope.__alternative;
+ self.resetError();
+ },
+ enumerable: true,
+ configurable: true
+ });
+
+ Object.defineProperty($scope,
+ "_address", {
+ get: function() {
+ return $scope.__address;
+ },
+ set: function(newValue) {
+ $scope.__address = self.onAddressChange(newValue);
+ },
+ enumerable: true,
+ configurable: true
+ });
+ };
+
+ this.setError = function(err) {
+ $log.warn(err);
+ var errMessage = 'The transaction' + (fc.credentials.m > 1 ? ' proposal' : '') +
+
+ ' could not be created: ' + (err.message ? err.message : err);
+
+ this.error = errMessage;
+
+ $timeout(function() {
+ $scope.$digest();
+ }, 1);
+ };
+
+
+ this.setOngoingProcess = function(name) {
+ var self = this;
+ $timeout(function() {
+ self.onGoingProcess = name;
+ $rootScope.$apply();
+ })
+ };
+
+ this.submitForm = function(form) {
+ var unitToSat = this.unitToSatoshi;
+
+ if (form.$invalid) {
+ this.error = 'Unable to send transaction proposal';
+ return;
+ }
+
+ if (fc.isPrivKeyEncrypted()) {
+ profileService.unlockFC(function(err) {
+ if (err) return self.setError(err);
+ return self.submitForm(form);
+ });
+ return;
+ };
+
+ self.blockUx = true;
+ self.setOngoingProcess('Sending');
+
+ if (isCordova) {
+ window.plugins.spinnerDialog.show(null, 'Creating transaction...', true);
+ }
+
+ $timeout(function() {
+ var comment = form.comment.$modelValue;
+ var paypro = self._paypro;
+ var address, amount;
+
+ address = form.address.$modelValue;
+ amount = parseInt((form.amount.$modelValue * unitToSat).toFixed(0));
+
+ fc.sendTxProposal({
+ toAddress: address,
+ amount: amount,
+ message: comment,
+ payProUrl: paypro ? paypro.url : null,
+ }, function(err, txp) {
+ self.setOngoingProcess();
+ if (err) {
+ profileService.lockFC();
+ if (isCordova) {
+ window.plugins.spinnerDialog.hide();
+ }
+ self.blockUx = false;
+ return self.setError(err);
+ }
+
+ self.signAndBroadcast(txp, function(err) {
+ self.setOngoingProcess();
+ if (isCordova) {
+ window.plugins.spinnerDialog.hide();
+ }
+ self.blockUx = false;
+ if (err) {
+ profileService.lockFC();
+ return self.setError(err);
+ }
+ self.resetForm(form);
+ });
+ });
+ }, 100);
+ };
+
+
+ this.signAndBroadcast = function(txp, cb) {
+ self.setOngoingProcess('Signing');
+ fc.signTxProposal(txp, function(err, signedTx) {
+ profileService.lockFC();
+ self.setOngoingProcess();
+
+ if (err) return cb(err);
+
+ if (signedTx.status == 'accepted') {
+ self.setOngoingProcess('Broadcasting');
+ fc.broadcastTxProposal(signedTx, function(err, btx) {
+ self.setOngoingProcess();
+ if (err) {
+ $scope.error = 'Transaction not broadcasted. Please try again.';
+ $scope.$digest();
+ } else {
+ txStatus.notify(btx);
+ $scope.$emit('Local/TxProposalAction');
+ }
+ return cb();
+ });
+ } else {
+ txStatus.notify(signedTx);
+ $scope.$emit('Local/TxProposalAction');
+ return cb();
+ }
+ });
+ };
+
+ this.setTopAmount = function() {
+ throw new Error('todo: setTopAmount');
+ var form = $scope.sendForm;
+ if (form) {
+ form.amount.$setViewValue(w.balanceInfo.topAmount);
+ form.amount.$render();
+ form.amount.$isValid = true;
+ }
+ };
+
+ this.setForm = function(to, amount, comment) {
+ var form = $scope.sendForm;
+ if (to) {
+ form.address.$setViewValue(to);
+ form.address.$isValid = true;
+ form.address.$render();
+ this.lockAddress = true;
+ }
+
+ if (amount) {
+ form.amount.$setViewValue("" + amount);
+ form.amount.$isValid = true;
+ form.amount.$render();
+ this.lockAmount = true;
+ }
+
+ if (comment) {
+ form.comment.$setViewValue(comment);
+ form.comment.$isValid = true;
+ form.comment.$render();
+ }
+ };
+
+
+
+ this.resetForm = function(form) {
+ this.resetError();
+ this.fetchingURL = null;
+ this._paypro = null;
+
+ this.lockAddress = false;
+ this.lockAmount = false;
+
+ this._amount = this._address = null;
+
+ if (form && form.amount) {
+ form.amount.$pristine = true;
+ form.amount.$setViewValue('');
+ form.amount.$render();
+
+ form.comment.$setViewValue('');
+ form.comment.$render();
+ form.$setPristine();
+
+ if (form.address) {
+ form.address.$pristine = true;
+ form.address.$setViewValue('');
+ form.address.$render();
+ }
+ }
+ $timeout(function() {
+ $rootScope.$digest();
+ }, 1);
+ };
+
+ this.openPPModal = function(paypro) {
+ var ModalInstanceCtrl = function($scope, $modalInstance) {
+ var satToUnit = 1 / self.unitToSatoshi;
+ $scope.paypro = paypro;
+ $scope.alternative = self.alternativeAmount;
+ $scope.alternativeIsoCode = self.alternativeIsoCode;
+ $scope.isRateAvailable = self.isRateAvailable;
+ $scope.unitTotal = (paypro.amount * satToUnit).toFixed(self.unitDecimals);
+ $scope.unitName = self.unitName;
+ $scope.color = fc.backgroundColor;
+
+ $scope.cancel = function() {
+ $modalInstance.dismiss('cancel');
+ };
+ };
+ $modal.open({
+ templateUrl: 'views/modals/paypro.html',
+ windowClass: 'full',
+ controller: ModalInstanceCtrl,
+ });
+ };
+
+ this.setFromPayPro = function(uri, form) {
+ if (isChromeApp) {
+ this.error = 'Payment Protocol not supported on Chrome App';
+ return;
+ }
+
+ var satToUnit = 1 / this.unitToSatoshi;
+ this.fetchingURL = uri;
+ this.blockUx = true;
+ var self = this;
+
+ $log.debug('Fetch PayPro Request...', uri);
+ $timeout(function() {
+ fc.fetchPayPro({
+ payProUrl: uri,
+ }, function(err, paypro) {
+ $log.debug(paypro);
+ self.blockUx = false;
+ self.fetchingURL = null;
+
+ if (err) {
+ $log.warn(err);
+ self.resetForm(form);
+ var msg = err.toString();
+ if (msg.match('HTTP')) {
+ msg = 'Could not fetch payment information';
+ }
+ self.error = msg;
+ } else {
+ self._paypro = paypro;
+ self.setForm(paypro.toAddress, (paypro.amount * satToUnit).toFixed(self.unitDecimals),
+ paypro.memo);
+ }
+ });
+ }, 1);
+ };
+
+ this.setFromUri = function(uri) {
+ function sanitizeUri(uri) {
+ // Fixes when a region uses comma to separate decimals
+ var regex = /[\?\&]amount=(\d+([\,\.]\d+)?)/i;
+ var match = regex.exec(uri);
+ if (!match || match.length === 0) {
+ return uri;
+ }
+ var value = match[0].replace(',', '.');
+ var newUri = uri.replace(regex, value);
+ return newUri;
+ };
+
+ var satToUnit = 1 / this.unitToSatoshi;
+
+ uri = sanitizeUri(uri);
+
+ if (!bitcore.URI.isValid(uri)) {
+ return uri;
+ }
+ var parsed = new bitcore.URI(uri);
+ var addr = parsed.address.toString();
+ var message = parsed.message;
+ if (parsed.r)
+ return this.setFromPayPro(parsed.r);
+
+ var amount = parsed.amount ?
+ (parsed.amount.toFixed(0) * satToUnit).toFixed(this.unitDecimals) : 0;
+
+ this.setForm(addr, amount, message);
+ return addr;
+ };
+
+ this.onAddressChange = function(value) {
+ this.resetError();
+ if (!value) return '';
+
+ if (this._paypro)
+ return value;
+
+ if (value.indexOf('bitcoin:') === 0) {
+ return this.setFromUri(value);
+ } else if (/^https?:\/\//.test(value)) {
+ return this.setFromPayPro(value);
+ } else {
+ return value;
+ }
+ };
+
+
+ // History
+
+ function strip(number) {
+ return (parseFloat(number.toPrecision(12)));
+ }
+
+ this.getUnitName = function() {
+ return this.unitName;
+ };
+
+ this.getAlternativeIsoCode = function() {
+ return this.alternativeIsoCode;
+ };
+
+ this._addRates = function(txs, cb) {
+ if (!txs || txs.length == 0) return cb();
+ var index = lodash.groupBy(txs, 'rateTs');
+
+ rateService.getHistoricRates(config.alternativeIsoCode, lodash.keys(index), function(err, res) {
+ if (err || !res) return cb(err);
+ lodash.each(res, function(r) {
+ lodash.each(index[r.ts], function(tx) {
+ var alternativeAmount = (r.rate != null ? tx.amount * rateService.SAT_TO_BTC * r.rate : null);
+ tx.alternativeAmount = alternativeAmount ? $filter('noFractionNumber')(alternativeAmount, 2) : null;
+ });
+ });
+ return cb();
+ });
+ };
+
+ this.openTxModal = function(btx) {
+ var self = this;
+ var fc = profileService.focusedClient;
+ var ModalInstanceCtrl = function($scope, $modalInstance) {
+ $scope.btx = btx;
+ $scope.settings = config;
+ $scope.color = fc.backgroundColor;
+
+ $scope.getAmount = function(amount) {
+ return self.getAmount(amount);
+ };
+
+ $scope.getUnitName = function() {
+ return self.getUnitName();
+ };
+
+ $scope.getShortNetworkName = function() {
+ var n = fc.credentials.network;
+ return n.substring(0, 4);
+ };
+
+ $scope.cancel = function() {
+ $modalInstance.dismiss('cancel');
+ };
+ };
+
+ $modal.open({
+ templateUrl: 'views/modals/tx-details.html',
+ windowClass: 'full',
+ controller: ModalInstanceCtrl,
+ });
+ };
+
+ this.hasAction = function(actions, action) {
+ return actions.hasOwnProperty('create');
+ };
+
+ // ToDo a send...
+ this.resetError();
+ this.setInputs();
+ // Todo Receive
+ this.getAddress();
+
+
});
diff --git a/src/js/routes.js b/src/js/routes.js
index 831c301a7..b8122ac63 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -179,63 +179,6 @@ angular
templateUrl: 'views/profile.html',
needProfile: true
})
- .state('receive', {
- url: '/receive',
- walletShouldBeComplete: true,
- needProfile: true,
- views: {
- 'main': {
- templateUrl: 'views/receive.html'
- },
- 'topbar': {
- templateUrl: 'views/includes/topbar.html'
- },
- 'menu': {
- templateUrl: 'views/includes/menu.html',
- controller: function($scope) {
- $scope.activeMenu = 'receive';
- }
- }
- }
- })
- .state('send', {
- url: '/send',
- walletShouldBeComplete: true,
- needProfile: true,
- views: {
- 'main': {
- templateUrl: 'views/send.html'
- },
- 'topbar': {
- templateUrl: 'views/includes/topbar.html'
- },
- 'menu': {
- templateUrl: 'views/includes/menu.html',
- controller: function($scope) {
- $scope.activeMenu = 'send';
- }
- }
- }
- })
- .state('history', {
- url: '/history',
- walletShouldBeComplete: true,
- needProfile: true,
- views: {
- 'main': {
- templateUrl: 'views/history.html'
- },
- 'topbar': {
- templateUrl: 'views/includes/topbar.html'
- },
- 'menu': {
- templateUrl: 'views/includes/menu.html',
- controller: function($scope) {
- $scope.activeMenu = 'history';
- }
- }
- }
- })
.state('preferences', {
url: '/preferences',
templateUrl: 'views/preferences.html',