+
Transaction finally rejected
diff --git a/js/controllers/addresses.js b/js/controllers/addresses.js
index 36bc1d2e0..bba9aced4 100644
--- a/js/controllers/addresses.js
+++ b/js/controllers/addresses.js
@@ -2,15 +2,17 @@
angular.module('copay.addresses').controller('AddressesController',
function($scope, $rootScope, controllerUtils) {
-
- var w = $rootScope.wallet;
$scope.loading = false;
-
+ var w = $rootScope.wallet;
$scope.newAddr = function() {
- $scope.loading = true;
- w.generateAddress();
- controllerUtils.updateBalance(function() {
- $scope.loading = false;
+ $scope.loading=true;
+ w.generateAddress(null, function() {
+ setTimeout(function() {
+ controllerUtils.setSocketHandlers();
+ controllerUtils.updateAddressList();
+ $scope.loading=false;
+ $rootScope.$digest();
+ },1);
});
};
diff --git a/js/controllers/footer.js b/js/controllers/footer.js
index bd71d68df..7fe81808d 100644
--- a/js/controllers/footer.js
+++ b/js/controllers/footer.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copay.footer').controller('FooterController', function($scope, $http) {
+angular.module('copay.footer').controller('FooterController', function($rootScope, $sce, $scope, $http) {
if (config.themes && Array.isArray(config.themes) && config.themes[0]) {
$scope.themes = config.themes;
@@ -15,4 +15,20 @@ angular.module('copay.footer').controller('FooterController', function($scope, $
$scope.theme = 'css/tpl-' + name + '.css';
};
$scope.version = copay.version;
+
+ $scope.getVideoURL = function(copayer) {
+ var vi = $rootScope.videoInfo[copayer]
+ if (!vi) return;
+
+ if ($rootScope.wallet.getOnlinePeerIDs().indexOf(copayer) === -1) {
+ // peer disconnected, remove his video
+ delete $rootScope.videoInfo[copayer]
+ return;
+ }
+
+ var encoded = vi.url;
+ var url = decodeURI(encoded);
+ var trusted = $sce.trustAsResourceUrl(url);
+ return trusted;
+ };
});
diff --git a/js/controllers/signin.js b/js/controllers/signin.js
index d13c8b471..f05202b42 100644
--- a/js/controllers/signin.js
+++ b/js/controllers/signin.js
@@ -7,6 +7,8 @@ angular.module('copay.signin').controller('SigninController',
return v1 > v2 ? 1 : ( v1 < v2 ) ? -1 : 0;
};
+ $rootScope.videoInfo = {};
+
$scope.loading = $scope.failure = false;
$scope.wallets = walletFactory.getWallets().sort(cmp);
$scope.selectedWalletId = $scope.wallets.length ? $scope.wallets[0].id : null;
@@ -20,6 +22,8 @@ angular.module('copay.signin').controller('SigninController',
$rootScope.walletName = form.walletName.$modelValue;
$rootScope.walletPassword = form.createPassword.$modelValue;
+
+
$location.path('setup');
};
@@ -31,7 +35,10 @@ angular.module('copay.signin').controller('SigninController',
$scope.loading = true;
var password = form.openPassword.$modelValue;
+
+ console.log('## Obtaining passphrase...');
Passphrase.getBase64Async(password, function(passphrase){
+ console.log('## Done.');
var w = walletFactory.open($scope.selectedWalletId, { passphrase: passphrase});
if (!w) {
$scope.loading = $scope.failure = false;
@@ -39,8 +46,8 @@ angular.module('copay.signin').controller('SigninController',
$rootScope.$digest();
return;
}
+ installStartupHandlers(w);
controllerUtils.startNetwork(w);
- listenErrors(w);
});
};
@@ -67,16 +74,19 @@ angular.module('copay.signin').controller('SigninController',
controllerUtils.onErrorDigest();
} else {
controllerUtils.startNetwork(w);
- listenErrors(w);
+ installStartupHandlers(w);
}
});
});
};
- function listenErrors(wallet) {
+ function installStartupHandlers(wallet) {
wallet.network.on('error', function(err) {
$scope.failure = true;
});
+ wallet.on('ready', function() {
+ $scope.loading = false;
+ });
}
});
diff --git a/js/controllers/transactions.js b/js/controllers/transactions.js
index 0a66e1dec..36f04904c 100644
--- a/js/controllers/transactions.js
+++ b/js/controllers/transactions.js
@@ -6,7 +6,13 @@ angular.module('copay.transactions').controller('TransactionsController',
$scope.title = 'Transactions';
$scope.loading = false;
- $scope.send = function (ntxid) {
+ $scope.update = function () {
+ $scope.loading = false;
+ controllerUtils.updateTxs();
+ $rootScope.$digest();
+ };
+
+ $scope.send = function (ntxid,cb) {
$scope.loading = true;
$rootScope.txAlertCount = 0;
var w = $rootScope.wallet;
@@ -16,34 +22,32 @@ angular.module('copay.transactions').controller('TransactionsController',
? {type:'success', message: 'Transaction broadcasted. txid: ' + txid}
: {type:'error', message: 'There was an error sending the Transaction'}
;
- controllerUtils.updateTxs();
- $scope.loading = false;
- $rootScope.$digest();
+ if (cb) return cb();
+ else $scope.update();
});
};
$scope.sign = function (ntxid) {
$scope.loading = true;
var w = $rootScope.wallet;
- var ret = w.sign(ntxid);
-
- if (!ret) {
- $rootScope.flashMessage = {type:'error', message: 'There was an error signing the Transaction'};
- controllerUtils.updateTxs();
- $scope.loading = false;
- $rootScope.$digest();
- return;
- }
- var p = w.txProposals.getTxProposal(ntxid);
- if (p.builder.isFullySigned()) {
- $scope.send(ntxid);
- controllerUtils.updateTxs();
- }
- else {
- controllerUtils.updateTxs();
- $scope.loading = false;
- $rootScope.$digest();
- }
+ w.sign(ntxid, function(ret){
+ if (!ret) {
+ $rootScope.flashMessage = {
+ type:'error',
+ message: 'There was an error signing the Transaction',
+ };
+ $scope.update();
+ }
+ else {
+ var p = w.txProposals.getTxProposal(ntxid);
+ if (p.builder.isFullySigned()) {
+ $scope.send(ntxid, function() {
+ $scope.update();
+ });
+ }
+ else $scope.update();
+ }
+ });
};
$scope.getTransactions = function() {
diff --git a/js/directives.js b/js/directives.js
index 156adac74..cefb4bbc4 100644
--- a/js/directives.js
+++ b/js/directives.js
@@ -23,7 +23,7 @@ angular.module('copay.directives')
};
}
])
- .directive('notification', ['$rootScope',
+ .directive('notification', ['$rootScope',
function($rootScope) {
return {
restrict: 'A',
@@ -82,13 +82,14 @@ angular.module('copay.directives')
.directive('loading', function() {
return {
restrict: 'A',
- link: function(scope, element, attr) {
+ link: function($scope, element, attr) {
var a = element.html();
var text = attr.loading;
- scope.$watch('loading', function(val) {
- if (val) {
+ element.on('click', function() {
element.html(' ' + text + '...');
- } else {
+ });
+ $scope.$watch('loading', function(val) {
+ if (!val) {
element.html(a);
}
});
@@ -104,14 +105,14 @@ angular.module('copay.directives')
});
}
}
- }).directive('avatar', function($rootScope) {
+ }).directive('avatar', function($rootScope, controllerUtils) {
return {
link: function(scope, element, attrs) {
var peer = JSON.parse(attrs.peer)
var peerId = peer.peerId;
var nick = peer.nick;
element.addClass('video-small');
- var muted = $rootScope.getVideoMutedStatus(peerId);
+ var muted = controllerUtils.getVideoMutedStatus(peerId);
if (muted) {
element.attr("muted", true);
}
diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js
index 398fefe36..9a2e07b24 100644
--- a/js/models/core/Wallet.js
+++ b/js/models/core/Wallet.js
@@ -79,7 +79,7 @@ Wallet.prototype._handlePublicKeyRing = function(senderId, data, isInbound) {
recipients = null;
this.sendPublicKeyRing(recipients);
}
- this.emit('refresh', this.publicKeyRing);
+ this.emit('publicKeyRingUpdated');
this.store();
};
@@ -222,11 +222,15 @@ Wallet.prototype.netStart = function() {
if (this.publicKeyRing.isComplete()) {
this._lockIncomming();
}
-
net.start(startOpts, function() {
- self.connectToAll();
self.emit('ready', net.getPeer());
- self.emit('refresh');
+ setTimeout(function(){
+console.log('[EMIT publicKeyRingUpdated:]'); //TODO
+ self.emit('publicKeyRingUpdated');
+console.log('[CONNECT:]'); //TODO
+ self.connectToAll();
+ self.emit('txProposalsUpdated');
+ },10);
});
};
@@ -346,11 +350,20 @@ Wallet.prototype.sendPublicKeyRing = function(recipients) {
});
};
+Wallet.prototype.getName = function() {
+ return this.name || this.id;
+};
-Wallet.prototype.generateAddress = function(isChange) {
- var addr = this.publicKeyRing.generateAddress(isChange);
+Wallet.prototype._doGenerateAddress = function(isChange) {
+ return this.publicKeyRing.generateAddress(isChange);
+};
+
+
+Wallet.prototype.generateAddress = function(isChange, cb) {
+ var addr = this._doGenerateAddress(isChange);
this.sendPublicKeyRing();
this.store();
+ if (cb) return cb(addr);
return addr;
};
@@ -383,27 +396,30 @@ Wallet.prototype.reject = function(ntxid) {
};
-Wallet.prototype.sign = function(ntxid) {
+Wallet.prototype.sign = function(ntxid, cb) {
var self = this;
- var myId = this.getMyCopayerId();
- var txp = self.txProposals.txps[ntxid];
- if (!txp || txp.rejectedBy[myId] || txp.signedBy[myId]) return;
+ setTimeout(function() {
+ var myId = self.getMyCopayerId();
+ var txp = self.txProposals.txps[ntxid];
+ if (!txp || txp.rejectedBy[myId] || txp.signedBy[myId]) return;
- var pkr = self.publicKeyRing;
- var keys = self.privateKey.getAll(pkr.addressIndex, pkr.changeAddressIndex);
+ var pkr = self.publicKeyRing;
+ var keys = self.privateKey.getAll(pkr.addressIndex, pkr.changeAddressIndex);
- var b = txp.builder;
- var before = b.signaturesAdded;
- b.sign(keys);
+ var b = txp.builder;
+ var before = b.signaturesAdded;
+ b.sign(keys);
- if (b.signaturesAdded > before) {
- txp.signedBy[myId] = Date.now();
- this.sendTxProposals(null, ntxid);
- this.store();
- this.emit('txProposalsUpdated');
- return true;
- }
- return false;
+ var ret = false;
+ if (b.signaturesAdded > before) {
+ txp.signedBy[myId] = Date.now();
+ self.sendTxProposals(null, ntxid);
+ self.store();
+ self.emit('txProposalsUpdated');
+ ret = true;
+ }
+ if (cb) return cb(ret);
+ },10);
};
Wallet.prototype.sendTx = function(ntxid, cb) {
@@ -423,9 +439,9 @@ Wallet.prototype.sendTx = function(ntxid, cb) {
self.log('BITCOND txid:', txid); //TODO
if (txid) {
self.txProposals.setSent(ntxid, txid);
+ self.sendTxProposals(null, ntxid);
+ self.store();
}
- self.sendTxProposals(null, ntxid);
- self.store();
return cb(txid);
});
};
@@ -536,7 +552,7 @@ Wallet.prototype.createTx = function(toAddress, amountSatStr, opts, cb) {
self.getUnspent(function(safeUnspent) {
var ntxid = self.createTxSync(toAddress, amountSatStr, safeUnspent, opts);
if (ntxid) {
- self.sendPublicKeyRing(); // For the new change Address
+ self.sendPublicKeyRing();
self.sendTxProposals(null, ntxid);
self.store();
self.emit('txProposalsUpdated');
@@ -558,7 +574,7 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) {
if (!opts.remainderOut) {
opts.remainderOut = {
- address: this.generateAddress(true).toString()
+ address: this._doGenerateAddress(true).toString()
};
}
diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js
index 357bf6af8..a176b4191 100644
--- a/js/services/controllerUtils.js
+++ b/js/services/controllerUtils.js
@@ -3,26 +3,8 @@
angular.module('copay.controllerUtils')
.factory('controllerUtils', function($rootScope, $sce, $location, Socket, video) {
var root = {};
- $rootScope.videoInfo = {};
- $rootScope.loading = false;
- $rootScope.getVideoURL = function(copayer) {
- var vi = $rootScope.videoInfo[copayer]
- if (!vi) return;
-
- if ($rootScope.wallet.getOnlinePeerIDs().indexOf(copayer) === -1) {
- // peer disconnected, remove his video
- delete $rootScope.videoInfo[copayer]
- return;
- }
-
- var encoded = vi.url;
- var url = decodeURI(encoded);
- var trusted = $sce.trustAsResourceUrl(url);
- return trusted;
- };
-
- $rootScope.getVideoMutedStatus = function(copayer) {
+ root.getVideoMutedStatus = function(copayer) {
var vi = $rootScope.videoInfo[copayer]
if (!vi) {
return;
@@ -30,17 +12,17 @@ angular.module('copay.controllerUtils')
return vi.muted;
};
- $rootScope.getWalletDisplay = function() {
- var w = $rootScope.wallet;
- return w && (w.name || w.id);
- };
-
root.logout = function() {
$rootScope.wallet = null;
delete $rootScope['wallet'];
- $rootScope.totalBalance = 0;
video.close();
- $rootScope.videoInfo = {};
+ // Clear rootScope
+ for (var i in $rootScope) {
+ if (i.charAt(0) != '$') {
+ delete $rootScope[i];
+ }
+ }
+
$location.path('signin');
};
@@ -73,18 +55,21 @@ angular.module('copay.controllerUtils')
};
});
w.on('ready', function(myPeerID) {
- video.setOwnPeer(myPeerID, w, handlePeerVideo);
$rootScope.wallet = w;
$location.path('addresses');
- $rootScope.$digest();
+ video.setOwnPeer(myPeerID, w, handlePeerVideo);
});
- w.on('refresh', function() {
- root.updateBalance();
+
+ w.on('publicKeyRingUpdated', function() {
+ root.setSocketHandlers();
+ root.updateAddressList();
$rootScope.$digest();
});
w.on('txProposalsUpdated', function() {
root.updateTxs();
- root.updateBalance();
+ root.updateBalance(function(){
+ $rootScope.$digest();
+ });
});
w.on('openError', root.onErrorDigest);
w.on('connect', function(peerID) {
@@ -100,25 +85,28 @@ angular.module('copay.controllerUtils')
w.netStart();
};
- root.updateBalance = function(cb) {
-
- console.log('Updating balance...');
- $rootScope.balanceByAddr = {};
+ root.updateAddressList = function() {
var w = $rootScope.wallet;
$rootScope.addrInfos = w.getAddressesInfo();
+ };
+
+ root.updateBalance = function(cb) {
+ console.log('Updating balance...');
+ root.updateAddressList();
+ var w = $rootScope.wallet;
if ($rootScope.addrInfos.length === 0) return;
- $rootScope.loading = true;
+
+ $rootScope.balanceByAddr = {};
+ $rootScope.updatingBalance = true;
w.getBalance(function(balance, balanceByAddr, safeBalance) {
- $rootScope.loading = false;
$rootScope.totalBalance = balance;
$rootScope.balanceByAddr = balanceByAddr;
$rootScope.selectedAddr = $rootScope.addrInfos[0].address.toString();
$rootScope.availableBalance = safeBalance;
- $rootScope.$digest();
+ $rootScope.updatingBalance = false;
console.log('Done updating balance.'); //TODO
if (cb) cb();
});
- root.setSocketHandlers();
};
root.updateTxs = function() {
@@ -163,23 +151,30 @@ angular.module('copay.controllerUtils')
$rootScope.pendingTxCount = pending;
w.removeListener('txProposalsUpdated',root.updateTxs)
w.once('txProposalsUpdated',root.updateTxs);
- $rootScope.loading = false;
};
root.setSocketHandlers = function() {
- // TODO: optimize this?
- Socket.removeAllListeners();
if (!$rootScope.wallet) return;
+ var currentAddrs= Socket.getListeners();
var addrs = $rootScope.wallet.getAddressesStr();
- for (var i = 0; i < addrs.length; i++) {
- console.log('### SUBSCRIBE TO', addrs[i]);
- Socket.emit('subscribe', addrs[i]);
+
+ var newAddrs=[];
+ for(var i in addrs){
+ var a=addrs[i];
+ if (!currentAddrs[a])
+ newAddrs.push(a);
}
- addrs.forEach(function(addr) {
+ for (var i = 0; i < newAddrs.length; i++) {
+ console.log('### SUBSCRIBE TO', newAddrs[i]);
+ Socket.emit('subscribe', newAddrs[i]);
+ }
+ newAddrs.forEach(function(addr) {
Socket.on(addr, function(txid) {
console.log('Received!', txid);
- root.updateBalance();
+ root.updateBalance(function(){
+ $rootScope.$digest();
+ });
});
});
};
diff --git a/js/services/socket.js b/js/services/socket.js
index bd59bde8e..f9ac7bb26 100644
--- a/js/services/socket.js
+++ b/js/services/socket.js
@@ -19,7 +19,6 @@ angular.module('copay.socket').factory('Socket',
};
socket.on(event, wrappedCallback);
-
if (event !== 'connect') {
listeners.push({
event: event,
@@ -27,6 +26,14 @@ angular.module('copay.socket').factory('Socket',
});
}
},
+ getListeners: function() {
+ var ret = {};
+ var addrList = listeners.map(function(i) {return i.event;});
+ for (var i in addrList) {
+ ret[addrList[i]] = 1;
+ }
+ return ret;
+ },
emit: function(event, data, callback) {
socket.emit(event, data, function() {
var args = arguments;