diff --git a/public/views/includes/transaction.html b/public/views/includes/transaction.html index 95944e441..6f257221b 100644 --- a/public/views/includes/transaction.html +++ b/public/views/includes/transaction.html @@ -22,7 +22,7 @@ {{tx.merchant.domain}} - {{tx.toAddress}} + diff --git a/public/views/modals/destination-address.html b/public/views/modals/destination-address.html new file mode 100644 index 000000000..b59856bb4 --- /dev/null +++ b/public/views/modals/destination-address.html @@ -0,0 +1,130 @@ +
+ + + +
diff --git a/public/views/modals/tx-details.html b/public/views/modals/tx-details.html index 15c3eb468..01623efb1 100644 --- a/public/views/modals/tx-details.html +++ b/public/views/modals/tx-details.html @@ -34,7 +34,8 @@ {{btx.merchant.domain}} - {{btx.labelTo || btx.addressTo}} + {{btx.labelTo}} + diff --git a/public/views/modals/txp-details.html b/public/views/modals/txp-details.html index 6581c5fd4..3fb3d57fe 100644 --- a/public/views/modals/txp-details.html +++ b/public/views/modals/txp-details.html @@ -18,7 +18,7 @@ class="line-b p10 oh" ng-click="copyAddress(tx.toAddress)"> To: - {{tx.toAddress}} +
  • Total diff --git a/public/views/modals/wallets.html b/public/views/modals/wallets.html deleted file mode 100644 index 6b4689bec..000000000 --- a/public/views/modals/wallets.html +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/public/views/walletHome.html b/public/views/walletHome.html index 2042dfb9e..d35be98e0 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -320,8 +320,9 @@
    - - + + +
    @@ -490,7 +491,8 @@
    - {{btx.message || btx.addressTo}} +
    {{btx.message}}
    +
    diff --git a/src/css/main.css b/src/css/main.css index 7e4bd73c1..d18a619be 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -98,6 +98,50 @@ h4.title a { border-bottom: 1px solid #E9E9EC; } +.addressbook-input { + display: block; + margin-bottom: 1.5rem; + background-color: #E4E8EC; + padding-left: 0.5rem; + color: #2C3E50; + font-size: 13px; + height: 35px; + padding-top: 7px; +} + +ul.button-group { + margin-top: 9px; +} + +ul.button-group li:first-child { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border: 1px solid #DEDFE1; +} + +ul.button-group li:last-child { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; + border: 1px solid #DEDFE1; +} + +.button-group.even-2 li { + margin: 0 -3px; +} + +ul.button-group li { + color: #A5B2BF; + cursor: pointer; + text-transform: uppercase; + font-size: 0.7rem; + display: block; + padding: 3px 0; +} + +ul.button-group li.selected { + color: #fff; + background-color: #DEDFE1; +} body, html{ height:100%; diff --git a/src/css/mobile.css b/src/css/mobile.css index 1be6f3013..00e8e4ade 100644 --- a/src/css/mobile.css +++ b/src/css/mobile.css @@ -340,6 +340,21 @@ a.missing-copayers { padding: 1rem 0.7rem; } +.modal-content ul li a.removeAddressbook { + background-color: white; + color: red; + margin-right: -10px; + float: right; +} + +.modal-content ul li a.selectAddressbook { + float: left; + font-size: 18px; + padding: 13px 14px; + color: red; + margin-right: 10px; +} + .sidebar ul.off-canvas-list li a i { vertical-align: middle; opacity: 0.6; diff --git a/src/js/controllers/walletHome.js b/src/js/controllers/walletHome.js index 34025618c..f6ebe44a0 100644 --- a/src/js/controllers/walletHome.js +++ b/src/js/controllers/walletHome.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, feeService, bwsError, confirmDialog, txFormatService, animationService) { +angular.module('copayApp.controllers').controller('walletHomeController', function($scope, $rootScope, $timeout, $filter, $modal, $log, notification, txStatus, isCordova, profileService, lodash, configService, rateService, storageService, bitcore, isChromeApp, gettext, gettextCatalog, nodeWebkit, addressService, ledger, feeService, bwsError, confirmDialog, txFormatService, animationService, addressbookService) { var self = this; $rootScope.hideMenuBar = false; @@ -136,12 +136,71 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi }); }; - - $scope.openWalletsModal = function(wallets) { + $scope.openDestinationAddressModal = function(wallets, address, label) { $rootScope.modalOpened = true; + var fc = profileService.focusedClient; + self.resetForm(); var ModalInstanceCtrl = function($scope, $modalInstance) { $scope.wallets = wallets; + $scope.editAddressbook = false; + $scope.addAddressbookEntry = false; + $scope.selectedAddressbook = {}; + $scope.addressbook = { 'address' : address, 'label' : label}; + $scope.color = fc.backgroundColor; + + $scope.selectAddressbook = function(addr) { + $modalInstance.close(addr); + }; + + $scope.toggleEditAddressbook = function() { + $scope.editAddressbook = !$scope.editAddressbook; + $scope.selectedAddressbook = {}; + $scope.addAddressbookEntry = false; + }; + + $scope.toggleSelectAddressbook = function(addr) { + $scope.selectedAddressbook[addr] = $scope.selectedAddressbook[addr] ? false : true; + }; + + $scope.toggleAddAddressbookEntry = function() { + $scope.addAddressbookEntry = !$scope.addAddressbookEntry; + }; + + $scope.list = function() { + $scope.error = null; + addressbookService.list(function(err, ab) { + if (err) { + $scope.error = err; + return; + } + $scope.list = ab; + }); + }; + + $scope.add = function(addressbook) { + $scope.error = null; + addressbookService.add(addressbook, function(err, ab) { + if (err) { + $scope.error = err; + return; + } + $scope.list = ab; + $scope.editAddressbook = true; + $scope.toggleEditAddressbook(); + }); + }; + + $scope.remove = function(addr) { + $scope.error = null; + addressbookService.remove(addr, function(err, ab) { + if (err) { + $scope.error = err; + return; + } + $scope.list = ab; + }); + }; $scope.cancel = function() { $modalInstance.dismiss('cancel'); @@ -168,7 +227,7 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi }; var modalInstance = $modal.open({ - templateUrl: 'views/modals/wallets.html', + templateUrl: 'views/modals/destination-address.html', windowClass: animationService.modalAnimated.slideUp, controller: ModalInstanceCtrl, }); @@ -718,6 +777,9 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi }, set: function(newValue) { $scope.__address = self.onAddressChange(newValue); + if ($scope.sendForm && $scope.sendForm.address.$valid) { + self.lockAddress = true; + } }, enumerable: true, configurable: true diff --git a/src/js/directives/directives.js b/src/js/directives/directives.js index 3ac8f2c91..478bd618b 100644 --- a/src/js/directives/directives.js +++ b/src/js/directives/directives.js @@ -162,27 +162,25 @@ angular.module('copayApp.directives') } } }) - .directive('contact', function() { + .directive('contact', ['addressbookService', function(addressbookService) { return { restrict: 'E', link: function(scope, element, attrs) { - if (!scope.wallet) return; - - var address = attrs.address; - var contact = scope.wallet.addressBook[address]; - if (contact && !contact.hidden) { - element.append(contact.label); - element.attr('tooltip', attrs.address); - } else { - element.append(address); - } + var addr = attrs.address; + addressbookService.getLabel(addr, function(label) { + if (label) { + element.append(label); + } else { + element.append(addr); + } + }); element.bind('click', function() { selectText(element[0]); }); } }; - }) + }]) .directive('highlightOnChange', function() { return { restrict: 'A', diff --git a/src/js/services/addressbookService.js b/src/js/services/addressbookService.js new file mode 100644 index 000000000..5bba70b93 --- /dev/null +++ b/src/js/services/addressbookService.js @@ -0,0 +1,66 @@ +'use strict'; + +angular.module('copayApp.services').factory('addressbookService', function(storageService, profileService) { + var root = {}; + + root.getLabel = function(addr, cb) { + var fc = profileService.focusedClient; + storageService.getAddressbook(fc.credentials.network, function(err, ab) { + if (!ab) return cb(); + ab = JSON.parse(ab); + if (ab[addr]) return cb(ab[addr]); + else return cb(); + }); + }; + + root.list = function(cb) { + var fc = profileService.focusedClient; + storageService.getAddressbook(fc.credentials.network, function(err, ab) { + if (err) return cb('Could not get the Addressbook'); + if (ab) ab = JSON.parse(ab); + return cb(err, ab); + }); + }; + + root.add = function(entry, cb) { + var fc = profileService.focusedClient; + root.list(function(err, ab) { + if (err) return cb(err); + if (!ab) ab = {}; + if (ab[entry.address]) return cb('Entry already exist'); + ab[entry.address] = entry.label; + storageService.setAddressbook(fc.credentials.network, JSON.stringify(ab), function(err, ab) { + if (err) return cb('Error adding new entry'); + root.list(function(err, ab) { + return cb(err, ab); + }); + }); + }); + }; + + root.remove = function(addr, cb) { + var fc = profileService.focusedClient; + root.list(function(err, ab) { + if (err) return cb(err); + if (!ab) return; + if (!ab[addr]) return cb('Entry does not exist'); + delete ab[addr]; + storageService.setAddressbook(fc.credentials.network, JSON.stringify(ab), function(err) { + if (err) return cb('Error deleting entry'); + root.list(function(err, ab) { + return cb(err, ab); + }); + }); + }); + }; + + root.removeAll = function() { + var fc = profileService.focusedClient; + storageService.removeAddressbook(fc.credentials.network, function(err) { + if (err) return cb('Error deleting addressbook'); + return cb(); + }); + }; + + return root; +}); diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index bff7c9ec6..b19db8779 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -204,5 +204,17 @@ angular.module('copayApp.services') storage.remove('glideraToken-' + network, cb); }; + root.setAddressbook = function(network, addressbook, cb) { + storage.set('addressbook-' + network, addressbook, cb); + }; + + root.getAddressbook = function(network, cb) { + storage.get('addressbook-' + network, cb); + }; + + root.removeAddressbook = function(network, cb) { + storage.remove('addressbook-' + network, cb); + }; + return root; });