From 0b7e9be6117974981e2ffe3571990ad4f0035e03 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 8 Oct 2014 10:54:26 -0300 Subject: [PATCH] controllers refactor to handle identities --- css/src/main.css | 23 +++++- js/controllers/create.js | 4 +- js/controllers/createProfile.js | 6 +- js/controllers/home.js | 8 +- js/controllers/open.js | 64 ---------------- js/controllers/sidebar.js | 17 +---- js/models/Identity.js | 52 +++++++------ js/models/Wallet.js | 18 ++++- js/routes.js | 5 -- js/services/controllerUtils.js | 78 +++++++++++++------- test/models/Identity.js | 16 +--- views/home.html | 4 +- views/includes/sidebar.html | 125 +++++++++++++++----------------- views/includes/version.html | 1 - 14 files changed, 192 insertions(+), 229 deletions(-) delete mode 100644 js/controllers/open.js diff --git a/css/src/main.css b/css/src/main.css index df285847f..b016d3a47 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -112,6 +112,18 @@ header { padding: 15px 20px 5px; } + +header .wfooter { + font-size: 12px; +} + + +header .creation { + color: white; + background: red; + font-weight: bold; +} + .off-canvas-wrap, .inner-wrap{ height:100%; } @@ -211,6 +223,7 @@ a:hover { color: #fff; } + .button.small.side-bar { padding: 0rem 0.4rem; } @@ -1046,12 +1059,12 @@ input.ng-invalid-match, input.ng-invalid-match:focus { .copayers { width: 100%; background-color: #213140; - position: absolute; - bottom: 0; - left: 0; + /* position: absolute; */ + /* bottom: 0; */ + /* left: 0; */ padding: 20px; border-top: 1px solid #475065; - overflow-y: hidden; + /* overflow-y: hidden; */ } .copayers i { @@ -1246,4 +1259,6 @@ fieldset legend { } + + /*-----------------------------------------------------------------*/ diff --git a/js/controllers/create.js b/js/controllers/create.js index 0784facfe..16f8fffe1 100644 --- a/js/controllers/create.js +++ b/js/controllers/create.js @@ -45,8 +45,8 @@ angular.module('copayApp.controllers').controller('CreateController', }; $rootScope.iden.createWallet(opts, function(err, w) { $scope.loading = false; - $rootScope.wallet = w; - controllerUtils.bindWallet(w, $scope); + controllerUtils.installWalletHandlers($scope, w); + controllerUtils.setFocusedWallet(w); }); }; }); diff --git a/js/controllers/createProfile.js b/js/controllers/createProfile.js index 14d003a29..50e5d1a75 100644 --- a/js/controllers/createProfile.js +++ b/js/controllers/createProfile.js @@ -12,10 +12,8 @@ angular.module('copayApp.controllers').controller('CreateProfileController', fun networkName: config.networkName, walletDefaults: config.wallet, passphrase: config.passphrase, - }, function(err, iden ,w) { - $rootScope.iden = iden; - $rootScope.wallet = w; - controllerUtils.bindWallet(w, $scope); + }, function(err, iden , firstWallet) { + controllerUtils.bindProfile($scope, iden, firstWallet); }); } diff --git a/js/controllers/home.js b/js/controllers/home.js index 418119526..5d2f5c52b 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -12,15 +12,13 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc networkName: config.networkName, walletDefaults: config.wallet, passphrase: config.passphrase, - }, function(err, iden, w) { - if (err && !w) { + }, function(err, iden, firstWallet) { + if (err && !iden) { console.log('Error:' + err) controllerUtils.onErrorDigest( $scope, (err.toString()||'').match('PNOTFOUND') ? 'Profile not found' : 'Unknown error'); } else { - $rootScope.iden = iden; - $rootScope.wallet = w; - controllerUtils.bindWallet(w, $scope); + controllerUtils.bindProfile($scope, iden, firstWallet); } }); } diff --git a/js/controllers/open.js b/js/controllers/open.js deleted file mode 100644 index b9e88bd52..000000000 --- a/js/controllers/open.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -angular.module('copayApp.controllers').controller('OpenController', function($scope, $rootScope, $location, controllerUtils, Passphrase, notification) { - controllerUtils.redirIfLogged(); - - if ($rootScope.pendingPayment) { - notification.info('Login Required', 'Please open wallet to complete payment'); - } - - var cmp = function(o1, o2) { - var v1 = o1.show.toLowerCase(), - v2 = o2.show.toLowerCase(); - return v1 > v2 ? 1 : (v1 < v2) ? -1 : 0; - }; - $rootScope.fromSetup = false; - $scope.loading = false; - $scope.retreiving = true; - - identity.getWallets(function(err, wallets) { - - if (err || !wallets || !wallets.length) { - $location.path('/'); - } else { - $scope.retreiving = false; - $scope.wallets = wallets.sort(cmp); - var lastOpened = _.findWhere($scope.wallets, { - lastOpened: true - }); - $scope.selectedWalletId = lastOpened ? lastOpened.id : ($scope.wallets[0] && $scope.wallets[0].id); - - setTimeout(function() { - $rootScope.$digest(); - }, 0); - } - }); - - $scope.openPassword = ''; - $scope.isMobile = !!window.cordova; - - $scope.open = function(form) { - if (form && form.$invalid) { - notification.error('Error', 'Please enter the required fields'); - return; - } - - $scope.loading = true; - var password = form.openPassword.$modelValue; - - Passphrase.getBase64Async(password, function(passphrase) { - var w, errMsg; - identity.open($scope.selectedWalletId, passphrase, function(err, w) { - if (!w) { - $scope.loading = false; - notification.error('Error', err.errMsg || 'Wrong password'); - $rootScope.$digest(); - } else { - $rootScope.updatingBalance = true; - controllerUtils.startNetwork(w, $scope); - } - }); - }); - }; - -}); diff --git a/js/controllers/sidebar.js b/js/controllers/sidebar.js index 870ddbc82..20520aa9a 100644 --- a/js/controllers/sidebar.js +++ b/js/controllers/sidebar.js @@ -57,6 +57,8 @@ angular.module('copayApp.controllers').controller('SidebarController', function( return new Array(num); } + + if ($rootScope.wallet) { $scope.$on('$idleWarn', function(a, countdown) { if (!(countdown % 5)) @@ -72,18 +74,7 @@ angular.module('copayApp.controllers').controller('SidebarController', function( }); } - $scope.switchWallet = function(id) { - var iden = $rootScope.iden; - controllerUtils.unbindWallet($scope); - - iden.openWallet(id, null, function(err, w) { - if (err) { - notification.warning('Could not open wallet'); - } else { - $scope.loading = false; - $rootScope.wallet = w; - controllerUtils.bindWallet(w, $scope); - } - }); + $scope.switchWallet = function(wid) { + controllerUtils.setFocusedWallet(wid); }; }); diff --git a/js/models/Identity.js b/js/models/Identity.js index c7a314266..7698d8da6 100644 --- a/js/models/Identity.js +++ b/js/models/Identity.js @@ -173,20 +173,25 @@ Identity.open = function(email, password, opts, cb) { var wids = _.pluck(iden.listWallets(), 'id'); + if (!wids || !wids.length) + return new Error('Could not open any wallet from profile'); - while (1) { - var wid = wids.shift(); - if (!wid) - return new Error('Could not open any wallet from profile'); - - iden.openWallet(wid, password, function(err, w) { + // Open All wallets from profile + //This could be optional, or opts.onlyOpen = wid + var firstWallet; + _.each(wids, function(wid) { + iden.openWallet(wid, function(err, w) { if (err) - log.info('Cound not open wallet id:' + wid + '. Skipping') - else - return cb(err, iden, w); + log.error('Cound not open wallet id:' + wid + '. Skipping') + else { + log.info('Open wallet id:' + wid + ' opened'); + if (!firstWallet) + firstWallet = w; + } }) - } + }); + return cb(err, iden, firstWallet); }); }; @@ -288,10 +293,8 @@ Identity.prototype.importWallet = function(base64, password, skipFields, cb) { }; Identity.prototype.closeWallet = function(wid, cb) { - var w = _.findWhere(this.openWallets, function(w) { - w.id === wid; - }); - preconditions.checkState(w); + var w = this.getOpenWallet(wid); + preconditions.checkState(w, 'Wallet not found'); var self = this; w.close(function(err) { @@ -433,24 +436,21 @@ Identity.prototype._checkVersion = function(inVersion) { /** * @desc Retrieve a wallet from the storage * @param {string} walletId - the id of the wallet - * @param {string} password - the password to decode it * @param {function} callback (err, {Wallet}) * @return */ -Identity.prototype.openWallet = function(walletId, password, cb) { +Identity.prototype.openWallet = function(walletId, cb) { preconditions.checkArgument(cb); + preconditions.checkState(this.storage.hasPassphrase()); + var self = this; - - if (password && !this.storage.hasPassphrase()) - self.storage.setPassword(password); - // TODO // self.migrateWallet(walletId, password, function() { // Identity._walletRead(walletId, { - storage: self.storage, - networkOpts: this.networkOpts, + storage: self.storage, + networkOpts: this.networkOpts, blockchainOpts: this.blockchainOpts }, function(err, w) { if (err) return cb(err); @@ -466,6 +466,13 @@ Identity.prototype.openWallet = function(walletId, password, cb) { }; +Identity.prototype.getOpenWallet = function(id) { + return _.findWhere(this.openWallets, { + id: id, + }); +}; + + Identity.prototype.listWallets = function(a) { var ret = this.profile.listWallets(); return ret; @@ -564,7 +571,6 @@ Identity.prototype.joinWallet = function(opts, cb) { return cb('joinError'); }); -console.log('[Identity.js.566:joinOpts:]',joinOpts); //TODO joinNetwork.start(joinOpts, function() { joinNetwork.greet(decodedSecret.pubKey, joinOpts.secretNumber); diff --git a/js/models/Wallet.js b/js/models/Wallet.js index 229d5a1a5..0bd9b8d93 100644 --- a/js/models/Wallet.js +++ b/js/models/Wallet.js @@ -743,6 +743,16 @@ Wallet.prototype.getNetworkName = function() { return this.publicKeyRing.network.name; }; +/** + * @desc + * @return {bool} + */ +Wallet.prototype.isTestnet = function() { + return this.publicKeyRing.network.name === 'testnet'; +}; + + + /** * @desc Serialize options into an object * @return {Object} with keys id, spendUnconfirmed, @@ -855,6 +865,9 @@ Wallet.prototype._setBlockchainListeners = function() { this.blockchain.on('reconnect', function(attempts) { log.debug('Wallet:' + this.id +'blockchain reconnect event'); self.emit('insightReconnected'); + + // Subscription should persist? TODO + //self.subscribeToAddresses(); }); this.blockchain.on('disconnect', function() { @@ -928,6 +941,7 @@ Wallet.prototype.netStart = function() { net.start(startOpts, function() { log.debug('Wallet:' + self.id + ' Networking ready:', net.copayerId); self._setBlockchainListeners(); + self.subscribeToAddresses(); self.emit('ready', net.getPeer()); setTimeout(function() { self.emit('publicKeyRingUpdated', true); @@ -1048,9 +1062,11 @@ Wallet.prototype.toObj = function() { * @param {number} o.lastTimestamp - last time this wallet object was deserialized * @param {Object} o.txProposals - TxProposals to be deserialized by {@link TxProposals#fromObj} * @param {string} o.nickname - user's nickname + * * @param readOpts.storage * @param readOpts.network * @param readOpts.blockchain + * @param readOpts.isImported {boolean} - tag wallet as 'imported' (skip forced backup step) * @param readOpts.{string[]} skipFields - parameters to ignore when importing */ Wallet.fromObj = function(o, readOpts) { @@ -1120,9 +1136,9 @@ Wallet.fromObj = function(o, readOpts) { opts.lastTimestamp = o.lastTimestamp || 0; opts.storage = storage; - opts.isImported = true; opts.blockchainOpts = readOpts.blockchainOpts; opts.networkOpts = readOpts.networkOpts; + opts.isImported = readOpts.isImported || false; return new Wallet(opts); }; diff --git a/js/routes.js b/js/routes.js index 9428638e2..2f4ce3f49 100644 --- a/js/routes.js +++ b/js/routes.js @@ -94,11 +94,6 @@ angular $idle.unwatch(); $location.path('/'); } - - // In creation? - if ($rootScope.wallet && !$rootScope.wallet.isReady()) { - $location.path('/copayers'); - } } }); }) diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index 53779be3c..3ece396a5 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -6,8 +6,13 @@ angular.module('copayApp.services') var root = {}; root.redirIfLogged = function() { - if ($rootScope.wallet) { - $location.path('receive'); + var w = $rootScope.wallet; + if (w) { + if (!w.isReady()) { + $location.path('/copayers'); + } else { + $location.path('receive'); + } } }; @@ -45,7 +50,8 @@ angular.module('copayApp.services') return wid === $rootScope.wallet.getId(); }; - root.installWalletHandlers = function(w, $scope) { + root.installWalletHandlers = function($scope, w) { + w.removeAllListeners(); var wid = w.getId(); w.on('connectionError', function() { @@ -69,7 +75,7 @@ angular.module('copayApp.services') if ($rootScope.pendingPayment) { $location.path('send'); } else { - $location.path('receive'); + root.redirIfLogged(); } } }); @@ -163,41 +169,63 @@ angular.module('copayApp.services') }; - root.setupRootVariables = function() { + root.setupGlobalVariables = function(iden) { + notification.enableHtml5Mode(); // for chrome: if support, enable it uriHandler.register(); $rootScope.unitName = config.unitName; $rootScope.txAlertCount = 0; $rootScope.initialConnection = true; $rootScope.reconnecting = false; $rootScope.isCollapsed = true; - $rootScope.$watch('txAlertCount', function(txAlertCount) { - if (txAlertCount && txAlertCount > 0) { - notification.info('New Transaction', ($rootScope.txAlertCount == 1) ? 'You have a pending transaction proposal' : $filter('translate')('You have') + ' ' + $rootScope.txAlertCount + ' ' + $filter('translate')('pending transaction proposals'), txAlertCount); - } + $rootScope.iden = iden; + + // TODO + // $rootScope.$watch('txAlertCount', function(txAlertCount) { + // if (txAlertCount && txAlertCount > 0) { + // + // notification.info('New Transaction', ($rootScope.txAlertCount == 1) ? 'You have a pending transaction proposal' : $filter('translate')('You have') + ' ' + $rootScope.txAlertCount + ' ' + $filter('translate')('pending transaction proposals'), txAlertCount); + // } + // }); + }; + + + root.rebindWallets = function($scope, iden) { + _.each(iden.listWallets(), function(winfo) { + var w = iden.getOpenWallet(winfo.id); + preconditions.checkState(w); + root.installWalletHandlers($scope, w); }); }; + root.setFocusedWallet = function(w) { + if (!_.isObject(w) ) + w = $rootScope.iden.getOpenWallet(w); + preconditions.checkState(w && _.isObject(w)); - root.unbindWallet = function($scope) { - var w = $rootScope.wallet; - w.removeAllListeners(); - }; - - root.bindWallet = function(w, $scope) { - root.setupRootVariables(); - root.unbindWallet(w); - root.installWalletHandlers(w, $scope); + $rootScope.wallet = w; root.updateAddressList(); - notification.enableHtml5Mode(); // for chrome: if support, enable it + + root.redirIfLogged(); }; - // TODO movie this to wallet - root.updateAddressList = function() { - var w = $rootScope.wallet; - if (w && w.isReady()) { - w.subscribeToAddresses(); - $rootScope.addrInfos = w.getAddressesInfo(); + root.bindProfile = function($scope, iden, w) { + + root.setupGlobalVariables(iden); + root.rebindWallets($scope, iden); + root.setFocusedWallet(w); + }; + + + // On the focused wallet + root.updateAddressList = function(wid) { + + if (!wid || root.isFocusedWallet(wid)) { + var w = $rootScope.wallet; + + if (w && w.isReady()) { + $rootScope.addrInfos = w.getAddressesInfo(); + } } }; diff --git a/test/models/Identity.js b/test/models/Identity.js index e0293e25c..3544e8899 100644 --- a/test/models/Identity.js +++ b/test/models/Identity.js @@ -237,21 +237,9 @@ describe('Identity model', function() { Identity._walletRead = sinon.stub().callsArgWith(5, null, wallet); }); - it('should call setPassword', function(done) { - - var s1 = sinon.stub(); - s1.store = sinon.stub().yields(null); - - iden.openWallet('id123', 'xxx', function(err, w) { - iden.storage.setPassword.calledOnce.should.equal(true); - iden.storage.setPassword.getCall(0).args[0].should.equal('xxx'); - done(); - }); - }); - it('should return wallet and call .store, .setLastOpenedTs & .migrateWallet', function(done) { - iden.openWallet('dummy', 'xxx', function(err, w) { + iden.openWallet('dummy', function(err, w) { should.not.exist(err); w.store.calledOnce.should.equal(true); iden.profile.setLastOpenedTs.calledTwice.should.equal(true); @@ -279,7 +267,7 @@ describe('Identity model', function() { Identity._walletFromObj = sinon.stub().returns(wallet); iden.importWallet("encrypted object", "xxx", [], function(err) { - iden.openWallet('ID123', 'xxx', function(err, w) { + iden.openWallet('ID123', function(err, w) { should.not.exist(err); should.exist(w); done(); diff --git a/views/home.html b/views/home.html index 44ab7b0aa..10c72e0d2 100644 --- a/views/home.html +++ b/views/home.html @@ -17,9 +17,9 @@

Login

- + - +
diff --git a/views/includes/sidebar.html b/views/includes/sidebar.html index beb61d2af..d10c0cf10 100644 --- a/views/includes/sidebar.html +++ b/views/includes/sidebar.html @@ -1,85 +1,78 @@
+ -
- - -
- -
- {{'Balance'|translate}} - +
    + +
- +
+
+
+ + {{$root.wallet.requiredCopayers}} of {{$root.wallet.totalCopayers}} wallet + + in creation + + + +
+ + + + + + +
  • + {{'Close'|translate}} +
  • + + + + -
    diff --git a/views/includes/version.html b/views/includes/version.html index 740200174..82325c290 100644 --- a/views/includes/version.html +++ b/views/includes/version.html @@ -1,6 +1,5 @@
    v{{version}} #{{commitHash}} - [ {{networkName}} ]