diff --git a/i18n/po/template.pot b/i18n/po/template.pot index 66a2e7ca8..a23e5dbae 100644 --- a/i18n/po/template.pot +++ b/i18n/po/template.pot @@ -610,10 +610,14 @@ msgstr "" msgid "Connection reset by peer" msgstr "" -#: www/views/tab-send.html:45 +#: www/views/tab-send.html:85 msgid "Contacts" msgstr "" +#: www/views/tab-send.html:86 +msgid "Saved frequently used addresses" +msgstr "" + #: www/views/onboarding/notifications.html:9 msgid "Continue" msgstr "" @@ -814,7 +818,7 @@ msgstr "" #: www/views/onboarding/tour.html:51 #: www/views/tab-home.html:75 -#: www/views/tab-send.html:36 +#: www/views/tab-send.html:75 msgid "Create bitcoin wallet" msgstr "" @@ -2524,6 +2528,14 @@ msgstr "" msgid "Search or enter bitcoin address" msgstr "" +#: src/js/controllers/tab-send.js:28 +msgid "Clipboard" +msgstr "" + +#: src/js/controllers/tab-send.js:29 +msgid "Your Clipboard is empty" +msgstr "" + #: www/views/modals/search.html:16 msgid "Search transactions" msgstr "" @@ -2582,9 +2594,70 @@ msgid "Send by email" msgstr "" #: src/js/controllers/confirm.js:177 +#: src/js/controllers/tab-send.js:94 msgid "Send from" msgstr "" +#: src/js/controllers/tab-send.js:77 +msgid "Send to" +msgstr "" + +#: www/views/tab-send.html:20 +msgid "Paste Clipboard" +msgstr "" + +#: www/views/tab-send.html:21 +msgid "Paste Address" +msgstr "" + +#: www/views/tab-send.html:27 +msgid "Wallet to Wallet Transfer" +msgstr "" + +#: www/views/tab-send.html:35 +msgid "Scan QR Code" +msgstr "" + +#: www/views/tab-send.html:46 +msgid "Send Bitcoin faster!" +msgstr "" + +#: www/views/tab-send.html:46 +msgid "Send Bitcoin faster!" +msgstr "" + +#: www/views/tab-send.html:50 +msgid "Save frequently used addresses and send them Bitcoin in just one tap" +msgstr "" + +#: www/views/tab-send.html:55 +msgid "Add your first contact" +msgstr "" + +#: www/views/tab-send.html:65 +msgid "Your Bitcoin wallet is empty" +msgstr "" + +#: www/views/tab-send.html:69 +msgid "To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address." +msgstr "" + +#: www/views/tab-send.html:70 +msgid "You can receive bitcoin from any wallet or service." +msgstr "" + +#: www/views/tab-send.html:72 +msgid "To get started, you'll need to create a bitcoin wallet and get some bitcoin." +msgstr "" + +#: www/views/tab-send.html:74 +msgid "Buy Bitcoin now" +msgstr "" + +#: www/views/tab-send.html:76 +msgid "Show my address" +msgstr "" + #: www/views/includes/itemSelector.html:8 msgid "Send max amount" msgstr "" diff --git a/src/js/controllers/addressbookAdd.js b/src/js/controllers/addressbookAdd.js index dcdb43b9f..9529d943e 100644 --- a/src/js/controllers/addressbookAdd.js +++ b/src/js/controllers/addressbookAdd.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('addressbookAddController', function($scope, $state, $stateParams, $timeout, $ionicHistory, gettextCatalog, addressbookService, popupService, configService, bitcoinCashJsService) { +angular.module('copayApp.controllers').controller('addressbookAddController', function($scope, $state, $stateParams, $timeout, $ionicHistory, gettextCatalog, addressbookService, popupService, configService, bitcoinCashJsService, platformInfo) { var config = configService.getSync(); var defaults = configService.getDefaults(); diff --git a/src/js/controllers/amount.js b/src/js/controllers/amount.js index f10121ee6..52695e829 100644 --- a/src/js/controllers/amount.js +++ b/src/js/controllers/amount.js @@ -38,9 +38,11 @@ angular.module('copayApp.controllers').controller('amountController', function($ $scope.minShapeshiftAmount = parseFloat(data.stateParams.minShapeshiftAmount); $scope.maxShapeshiftAmount = parseFloat(data.stateParams.maxShapeshiftAmount); $scope.shapeshiftOrderId = data.stateParams.shapeshiftOrderId; - $scope.fromWalletId = data.stateParams.fromWalletId; } + // To get the wallet from with the new flow + $scope.fromWalletId = data.stateParams.fromWalletId; + if (data.stateParams.noPrefix) { $scope.showWarningMessage = data.stateParams.noPrefix != 0; if ($scope.showWarningMessage) { @@ -458,7 +460,8 @@ angular.module('copayApp.controllers').controller('amountController', function($ amount: $scope.useSendMax ? null : _amount, currency: unit.id.toUpperCase(), coin: coin, - useSendMax: $scope.useSendMax + useSendMax: $scope.useSendMax, + fromWalletId: $scope.fromWalletId }); } else { var amount = _amount; @@ -479,6 +482,7 @@ angular.module('copayApp.controllers').controller('amountController', function($ toColor: $scope.toColor, coin: coin, useSendMax: $scope.useSendMax, + fromWalletId: $scope.fromWalletId }; if ($scope.shapeshiftOrderId) { diff --git a/src/js/controllers/tab-send.js b/src/js/controllers/tab-send.js index 2282ab878..99265457d 100644 --- a/src/js/controllers/tab-send.js +++ b/src/js/controllers/tab-send.js @@ -1,32 +1,139 @@ 'use strict'; -angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicNavBarDelegate) { - +angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) { + var clipboardHasAddress = false; + var clipboardHasContent = false; var originalList; - var CONTACTS_SHOW_LIMIT; - var currentContactsPage; - $scope.isChromeApp = platformInfo.isChromeApp; - $scope.sectionDisplay = { - transferToWallet: false + $scope.displayBalanceAsFiat = true; + $scope.walletSelectorTitleForce = true; + + $scope.addContact = function() { + $state.go('tabs.send.addressbook'); + }; + + $scope.pasteClipboard = function() { + if ($scope.clipboardHasAddress || $scope.clipboardHasContent) { + clipboardService.readFromClipboard(function(text) { + $scope.$apply(function() { + $scope.formData.search = text; + $scope.findContact($scope.formData.search); + }); + }); + } else { + $ionicPopup.alert({ + title: gettextCatalog.getString('Clipboard'), + template: gettextCatalog.getString('Your Clipboard is empty') + }); + } + }; + + $scope.$on("$ionicView.enter", function(event, data) { + clipboardService.readFromClipboard(function(text) { + if (text.length > 200) { + text = text.substring(0, 200); + } + + $scope.clipboardHasAddress = false; + $scope.clipboardHasContent = false; + if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr + $scope.clipboardHasAddress = true; + } else if ((text[0] === "1" || text[0] === "3" || text.substring(0, 3) === "bc1") && text.length >= 26 && text.length <= 35) { // Legacy Addresses + $scope.clipboardHasAddress = true; + } else if (text.length > 1) { + $scope.clipboardHasContent = true; + } + }); + + $ionicNavBarDelegate.showBar(true); + if (!$scope.hasWallets) { + $scope.checkingBalance = false; + return; + } + updateHasFunds(); + updateContactsList(function() { + updateList(); + }); + }); + + var wallets; + var walletsBch; + var walletsBtc; + var walletToWalletFrom = false; + + $scope.onWalletSelect = function(wallet) { + if (!$scope.walletToWalletFrom) { + $scope.walletToWalletFrom = wallet; + if (wallet.coin === 'bch') { + $scope.showWalletsBch = true; + } else if (wallet.coin === 'btc') { + $scope.showWalletsBtc = true; + } + $scope.walletSelectorTitleTo = gettextCatalog.getString('Send to'); + } else { + $ionicLoading.show(); + walletService.getAddress(wallet, true, function(err, addr) { + $ionicLoading.hide(); + return $state.transitionTo('tabs.send.amount', { + displayAddress: $scope.walletToWalletFrom.coin === 'bch' ? bitcoinCashJsService.translateAddresses(addr).cashaddr : addr, + recipientType: 'wallet', + fromWalletId: $scope.walletToWalletFrom.id, + toAddress: addr, + coin: $scope.walletToWalletFrom.coin + }); + }); + + } + }; + + $scope.showWalletSelector = function() { + $scope.walletToWalletFrom = false; + $scope.walletSelectorTitleFrom = gettextCatalog.getString('Send from'); + $scope.showWallets = true; + }; + + $scope.findContact = function(search) { + + if (incomingData.redir(search)) { + return; + } + + if (!search || search.length < 1) { + $scope.list = originalList; + $timeout(function() { + $scope.$apply(); + }); + return; + } + + var result = lodash.filter(originalList, function(item) { + var val = item.name; + return lodash.startsWith(val.toLowerCase(), search.toLowerCase()); + }); + + $scope.list = result; }; var hasWallets = function() { + $scope.walletsWithFunds = profileService.getWallets({ + onlyComplete: true, + hasFunds: true + }); $scope.wallets = profileService.getWallets({ - onlyComplete: true + onlyComplete: true, + }); + $scope.walletsBch = profileService.getWallets({ + onlyComplete: true, + coin: 'bch' + }); + $scope.walletsBtc = profileService.getWallets({ + onlyComplete: true, + coin: 'btc' }); $scope.hasWallets = lodash.isEmpty($scope.wallets) ? false : true; }; - // THIS is ONLY to show the 'buy bitcoins' message - // does not has any other function. - var updateHasFunds = function() { - if ($rootScope.everHasFunds) { - $scope.hasFunds = true; - return; - } - $scope.hasFunds = false; var index = 0; lodash.each($scope.wallets, function(w) { @@ -41,10 +148,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function( $scope.hasFunds = true; } else if (status.availableBalanceSat > 0) { $scope.hasFunds = true; - $rootScope.everHasFunds = true; } - if (index == $scope.wallets.length) { + if (index === $scope.wallets.length) { $scope.checkingBalance = false; $timeout(function() { $scope.$apply(); @@ -54,52 +160,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function( }); }; - var updateWalletsList = function() { - var config = configService.getSync(); - var networkResult = lodash.countBy($scope.wallets, 'network'); - - $scope.showTransferCard = $scope.hasWallets && (networkResult.livenet > 1 || networkResult.testnet > 1); - - if ($scope.showTransferCard) { - var walletsToTransfer = $scope.wallets; - if (!(networkResult.livenet > 1)) { - walletsToTransfer = lodash.filter(walletsToTransfer, function(item) { - return item.network == 'testnet'; - }); - } - if (!(networkResult.testnet > 1)) { - walletsToTransfer = lodash.filter(walletsToTransfer, function(item) { - return item.network == 'livenet'; - }); - } - - var walletList = []; - lodash.each(walletsToTransfer, function(v) { - var displayBalanceAsFiat = - // BD got v.status as undefined here once during development, just - // after creating a new wallet. - v.status && - v.status.alternativeBalanceAvailable && - config.wallet.settings.priceDisplay === 'fiat'; - - walletList.push({ - color: v.color, - name: v.name, - recipientType: 'wallet', - coin: v.coin, - network: v.network, - balanceString: displayBalanceAsFiat ? - v.status.totalBalanceAlternative + ' ' + v.status.alternativeIsoCode : - v.cachedBalance, - getAddress: function(cb) { - walletService.getAddress(v, false, cb); - }, - }); - }); - originalList = originalList.concat(walletList); - } - } - var updateContactsList = function(cb) { var config = configService.getSync(); var defaults = configService.getDefaults(); @@ -118,16 +178,14 @@ angular.module('copayApp.controllers').controller('tabSendController', function( recipientType: 'contact', coin: v.coin, displayCoin: (v.coin == 'bch' - ? (config.bitcoinCashAlias || defaults.bitcoinCashAlias) - : (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase(), + ? (config.bitcoinCashAlias || defaults.bitcoinCashAlias) + : (config.bitcoinAlias || defaults.bitcoinAlias)).toUpperCase(), getAddress: function(cb) { return cb(null, k); }, }); }); - var contacts = completeContacts.slice(0, (currentContactsPage + 1) * CONTACTS_SHOW_LIMIT); - $scope.contactsShowMore = completeContacts.length > contacts.length; - originalList = originalList.concat(contacts); + originalList = completeContacts; return cb(); }); }; @@ -140,28 +198,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function( }, 10); }; - $scope.openScanner = function() { - var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP; - - if (!isWindowsPhoneApp) { - $state.go('tabs.scan'); - return; - } - - scannerService.useOldScanner(function(err, contents) { - if (err) { - popupService.showAlert(gettextCatalog.getString('Error'), err); - return; - } - incomingData.redir(contents); - }); - }; - - $scope.showMore = function() { - currentContactsPage++; - updateWalletsList(); - }; - $scope.searchInFocus = function() { $scope.searchFocus = true; }; @@ -172,28 +208,6 @@ angular.module('copayApp.controllers').controller('tabSendController', function( } }; - $scope.findContact = function(search) { - - if (incomingData.redir(search)) { - return; - } - - if (!search || search.length < 2) { - $scope.list = originalList; - $timeout(function() { - $scope.$apply(); - }); - return; - } - - var result = lodash.filter(originalList, function(item) { - var val = item.name; - return lodash.includes(val.toLowerCase(), search.toLowerCase()); - }); - - $scope.list = result; - }; - $scope.goToAmount = function(item) { $timeout(function() { item.getAddress(function(err, addr) { @@ -236,34 +250,19 @@ angular.module('copayApp.controllers').controller('tabSendController', function( }; $scope.$on("$ionicView.beforeEnter", function(event, data) { + $scope.isIOS = platformInfo.isIOS && platformInfo.isCordova; + $scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false; + $scope.checkingBalance = true; $scope.formData = { search: null }; originalList = []; - CONTACTS_SHOW_LIMIT = 10; - currentContactsPage = 0; hasWallets(); - }); - $scope.$on("$ionicView.enter", function(event, data) { - $ionicNavBarDelegate.showBar(true); - if (!$scope.hasWallets) { - $scope.checkingBalance = false; - return; - } - updateHasFunds(); - updateWalletsList(); - updateContactsList(function() { - updateList(); + configService.whenAvailable(function(_config) { + $scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat'; }); + }); - - $scope.toggle = function(section) { - $scope.sectionDisplay[section] = !$scope.sectionDisplay[section]; - $timeout(function() { - $ionicScrollDelegate.resize(); - $scope.$apply(); - }, 10); - }; }); diff --git a/src/js/directives/gravatar.js b/src/js/directives/gravatar.js index 5f7931798..c96a63cfe 100644 --- a/src/js/directives/gravatar.js +++ b/src/js/directives/gravatar.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.directives') - .directive('gravatar', function(md5) { + .directive('gravatar', function(md5, $http) { return { restrict: 'AE', replace: true, @@ -9,13 +9,24 @@ angular.module('copayApp.directives') name: '@', height: '@', width: '@', - email: '@' + email: '@', + url: '@' }, link: function(scope, el, attr) { if (typeof scope.email === "string") { scope.emailHash = md5.createHash(scope.email.toLowerCase() || ''); + var req = { + method: 'GET', + url: 'https://secure.gravatar.com/'+scope.emailHash+'.json', + }; + scope.url = 'img/contact-placeholder.svg'; + $http(req).then(function (response) { + scope.url = 'https://secure.gravatar.com/avatar/'+scope.emailHash+'.jpg?s='+scope.width+'&d=mm'; + }, function (error) { + scope.url = 'img/contact-placeholder.svg'; + }); } }, - template: '{{ name }}' + template: '{{ name }}' }; }); diff --git a/src/js/directives/walletSelector.js b/src/js/directives/walletSelector.js index 79053f812..8a96a0805 100644 --- a/src/js/directives/walletSelector.js +++ b/src/js/directives/walletSelector.js @@ -8,15 +8,21 @@ angular.module('copayApp.directives') transclude: true, scope: { title: '=walletSelectorTitle', + forceTitle: '=walletSelectorForceTitle', show: '=walletSelectorShow', wallets: '=walletSelectorWallets', selectedWallet: '=walletSelectorSelectedWallet', onSelect: '=walletSelectorOnSelect', + onHide: '=walletSelectorOnHide', displayBalanceAsFiat : '=walletSelectorDisplayBalanceAsFiat' }, link: function(scope, element, attrs) { + console.log(scope, element, attrs); scope.hide = function() { scope.show = false; + if (typeof scope.onHide === "function") { + scope.onHide() + } }; scope.selectWallet = function(wallet) { $timeout(function() { diff --git a/src/js/services/clipboardService.js b/src/js/services/clipboardService.js index e2e0e5fb3..ff28cd2e7 100644 --- a/src/js/services/clipboardService.js +++ b/src/js/services/clipboardService.js @@ -17,7 +17,27 @@ angular.module('copayApp.services').factory('clipboardService', function ($http, // No supported return; } + }; + root.readFromClipboard = function (cb) { + $log.debug("Read from clipboard"); + if (platformInfo.isCordova) { + cordova.plugins.clipboard.paste(function(text) { + cb(text); + }) + } else if (platformInfo.isNW) { + cb(nodeWebkitService.readFromClipboard()); + } else { + navigator.clipboard.readText() + .then(text => { + cb(text); + }) + .catch(err => { + $log.debug("Clipboard reading is not supported in browser.."); + }); + + return; + } }; return root; diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index a318e1157..1bb87b49c 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -228,10 +228,12 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat } else if (/^https?:\/\//.test(data)) { payproService.getPayProDetails(data, coin, function(err, details) { if (err) { - root.showMenu({ - data: data, - type: 'url' - }); + if ($state.includes('tabs.scan')) { + root.showMenu({ + data: data, + type: 'url' + }); + } return; } handlePayPro(details); diff --git a/src/sass/buttons.scss b/src/sass/buttons.scss index 348d6d378..a8512ae64 100644 --- a/src/sass/buttons.scss +++ b/src/sass/buttons.scss @@ -16,6 +16,8 @@ &.button-primary, &.button-secondary, &.button-light, + &.button-white, + &.button-green, &.button-assertive { &.button-standard { @extend %button-standard; @@ -33,6 +35,10 @@ } } +@mixin button-shadow() { + box-shadow: 0 2px 11px 0 #C1C1C1;; +} + .button { &.button-secondary { @include button-style($v-button-secondary-bg, $v-button-secondary-border, $v-button-secondary-active-bg, $v-button-secondary-active-border, $v-button-secondary-color); @@ -47,7 +53,24 @@ } .button { + border-radius: 6px; &.button-full { display: block; } + &-green { + @include button-style(#719561, #FFF, #606060, #FFF, #FFF); + @include button-clear(#FFF); + @include button-outline(#C1C1C1); + border: 0px; + @include button-shadow(); + } + &-white { + @include button-style(#FFF, #C1C1C1, #C1C1C1, #FFF, #606060); + @include button-clear(#FFF); + @include button-outline(#C1C1C1); + @include button-shadow(); + &.activated { + color: #FFF; + } + } } \ No newline at end of file diff --git a/src/sass/views/address-book.scss b/src/sass/views/address-book.scss index c0d0f99a8..8bbdbc6be 100644 --- a/src/sass/views/address-book.scss +++ b/src/sass/views/address-book.scss @@ -124,7 +124,6 @@ position: relative; height: 70px; border-color: $royal; - background-color: $royal; padding-top: 20px; margin-bottom: 50px; text-align: center; diff --git a/src/sass/views/tab-send.scss b/src/sass/views/tab-send.scss index a969faedf..a4025156f 100644 --- a/src/sass/views/tab-send.scss +++ b/src/sass/views/tab-send.scss @@ -1,12 +1,28 @@ #tab-send { @extend .deflash-blue; + + &-header{ + height: 300px; + width: 100%; + } + &-contacts { + height: calc(100vh - 300px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */ + &.ios { + height: calc(100vh - 300px - 50px - 44px - 18px); // Remove the notification-bar height on iOS + } + overflow: scroll; + } + .input { + width: 100%; input { width: 100%; - height: auto; - } - &.item { - height: 55px; + height: 57px; + background: #FFF; + border: 1px #D9D9D9 solid; + &::placeholder { + color: #DCDCDC; + } } i { &.left { @@ -19,45 +35,22 @@ } } } - .qr-scan-icon { - cursor: pointer; - cursor: hand; - border-left: 1px solid rgb(228, 228, 228); - padding-left: 10px; - } - .qr-icon { - line-height: 20px; - } - .zero-state-cta { - padding-bottom: 3vh; - left: 0; - } - .send-heading { - font-size: 14px; - font-weight: bold; - padding: 0 0 16px 0; - border: none; - } - .send-header-wrapper { - padding: 10px; - background-color: white; - box-shadow: 0px 5px 10px 0px #cccccc; - } - .search-wrapper { + + .send-wrapper { + &:after { + display: block; + position: relative; + height: 1px; + background: #DEDEDE; + bottom: 0; + content: ''; + margin: 10px 6px 0px; + } + padding: 18px 9px 9px 9px; background-color: #f2f2f2; border-radius: 3px; border: none; - .svg#Bitcoin_Symbol { - width: 14px; - .st0 { - fill: #cccccc; - } - } &.focus { - background: none; - .svg#Bitcoin_Symbol { - display: none; - } .search-input { padding-left: 30px; &:focus::-webkit-input-placeholder { @@ -65,57 +58,88 @@ } } } + .buttons { + margin: auto; + margin-top: 18px; + .button { + &-clipboard-paste { + margin-left: 0; + .address { + display: none; + } + .icon { + background: url(../img/icon-clipboard-paste.svg); + width: 15px; + height: 19px; + display: inline-block; + margin-bottom: 4px; + } + &.contains-address, &.contains-content { + .address { + display: none; + } + background: #FAB915; + color: #FFF !important; + border: 0; + @include button-shadow(); + .icon { + background: url(../img/icon-clipboard-paste-white.svg); + } + &.contains-address { + .address { + display: inline; + } + .non-address { + display: none; + } + } + } + } + span { + font-size: 14px; + } + img { + height: 16px; + width: auto; + margin: 2px 0 4px; + } + height: 60px; + line-height: 16px; + margin-right: 0px; + width: 95%; + max-width: none; + padding: 2px; + &-qr { + font-weight: bold; + max-width: none; + width: 100%; + height: 95px; + margin-top: 20px; + img { + vertical-align: middle; + margin-right: 12px; + width: 43px; + height: 43px; + } + span { + font-size: 19px; + } + } + } + } } - .abs-v-center { - position: absolute; - top: 50%; - transform: translateY(-50%); - } .search-input { background-color: transparent; padding-left: 30px; } - .separator-left { - border-left: 1px solid #d9d9df; - padding-left: 10px; - height: 70%; - } - .bitcoin-address { - border-top: none; - padding-bottom: .5rem; - @media(max-width: 480px) { - input { - font-size: 14px; - } - } - .icon { - line-height: 31px; - padding-top: 2px; - padding-bottom: 1px; - } - } - .show-more { - text-align: center; - padding: 20px; - font-size: 16px; - color: #387ef5; - font-weight: bold; - } .sendTip { + padding-top: 5vh; text-align: center; - & > .item-heading { - margin-top: 10px; - background: 0 none; - } - img { - content: $v-tab-send-selected-icon; - } .item { border-style: none; } & > .title { font-size: 20px; - font-weight: bold; color: $v-dark-gray; margin: 20px 10px; } @@ -123,34 +147,64 @@ font-size: 1rem; line-height: 1.5em; font-weight: 300; - color: $v-dark-gray; + color: #6F6F70; margin: 20px 1em 2.5em; } - .big-icon-svg{ - .bg.green{ + .big-icon-svg { + .bg.green { padding: 0 10px; box-shadow: none; } } + .buttons { + margin-top: 18px; + .button { + font-weight: bold; + font-size: 19px; + } + } + .button-first-contact img { + height: 19px; + width: 19px; + margin-right: 6px; + vertical-align: sub; + } + } + .item-heading { + line-height: 16px; + font-size: 14px; + font-weight: bold; + .subtitle { + color: #B5B2B2; + font-size: 12px; + font-weight: 300; + } } .list { .item { + font-weight: 600; + p { + font-weight: normal; + } + &.item-icon-left { + padding-left: 64px; + } color: #444; - border-top: none; - padding-top: 1.5rem; - padding-bottom: 1.5rem; + //border-top: none; + padding-top: 0.6rem; + padding-bottom: 0.6rem;; .big-icon-svg { - left:5px; - & > .bg{ - width:30px; - height:30px; - box-shadow: none; - } + left: 5px; + & > .bg { + width: 30px; + height: 30px; + box-shadow: none; + } } &:before { display: block; position: absolute; - width: 80%; + width: 100%; height: 1px; background: rgba(221, 221, 221, 0.3); top: 0; @@ -163,7 +217,7 @@ &.item-heading { &:before { top: 99%; - width:100%; + width: 100%; } } &:nth-child(2) { @@ -176,5 +230,40 @@ } } } - .scroll{height: 100%;} + .scroll { + height: 100%; + } + + .card.contacts { + margin: 4px 4px 16px 4px; + + border-radius: 6px; + box-shadow: 0px 2px 1px 0 #C1C1C1; + .gravatar { + border-radius: 30px; + height: 40px; + width: 40px; + } + } + + + ///* iPhone 5/SE and other small screen devices */ + @media only screen and (min-device-width : 320px) and (max-device-width : 568px) { + .send-wrapper .buttons .button-qr { + height: 60px; + span { + font-size: 16px; + } + } + #tab-send-header { + height: 270px; + } + #tab-send-contacts { + height: calc(100vh - 270px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */ + &.ios { + height: calc(100vh - 270px - 50px - 44px - 18px); // Remove the notification-bar height on iOS + } + } + } + } diff --git a/www/img/contact-placeholder.svg b/www/img/contact-placeholder.svg index f730da86b..54b0fcec2 100644 --- a/www/img/contact-placeholder.svg +++ b/www/img/contact-placeholder.svg @@ -1,12 +1,18 @@ - - - - - - + + + + Artboard + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/img/icon-clipboard-paste-white.svg b/www/img/icon-clipboard-paste-white.svg new file mode 100644 index 000000000..be0df78bc --- /dev/null +++ b/www/img/icon-clipboard-paste-white.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/www/img/icon-clipboard-paste.svg b/www/img/icon-clipboard-paste.svg new file mode 100644 index 000000000..a82edc11b --- /dev/null +++ b/www/img/icon-clipboard-paste.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/www/img/icon-contact-add.svg b/www/img/icon-contact-add.svg new file mode 100644 index 000000000..36d1f95bc --- /dev/null +++ b/www/img/icon-contact-add.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/www/img/icon-scan-qr.svg b/www/img/icon-scan-qr.svg new file mode 100644 index 000000000..bc4a2bc56 --- /dev/null +++ b/www/img/icon-scan-qr.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/img/icon-w2w.svg b/www/img/icon-w2w.svg new file mode 100644 index 000000000..082a0d8cc --- /dev/null +++ b/www/img/icon-w2w.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/www/views/includes/walletSelector.html b/www/views/includes/walletSelector.html index 136aa4694..97dfeb552 100644 --- a/www/views/includes/walletSelector.html +++ b/www/views/includes/walletSelector.html @@ -5,7 +5,7 @@ ng-init="wallet.coin == 'btc' ? walletsBtc.push(wallet) : walletsBch.push(wallet)"> -
{{title}}
+
{{title}}
Bitcoin Cash (BCH)
diff --git a/www/views/tab-send.html b/www/views/tab-send.html index ab40e7e42..8b39808db 100644 --- a/www/views/tab-send.html +++ b/www/views/tab-send.html @@ -3,15 +3,57 @@ {{'Send' | translate}} +
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+
-
-
-
Recipient
-
- -
- - +
+
+
+ Send Bitcoin faster! +
+
+
+

Save frequently used addresses and send them Bitcoin in just one tap

+
+
@@ -19,72 +61,75 @@
-
-
- - - -
- Start sending bitcoin + Your Bitcoin wallet is empty
- To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service. - To get started, you'll need to create a bitcoin wallet and get some bitcoin. -
- - - +
+

To get started, buy Bitcoin Cash (BCH) or Bitcoin Core (BTC), or share your address.

+

You can receive bitcoin from any wallet or service.

+
+
To get started, you'll need to create a bitcoin wallet and get some bitcoin.
+
+ + +
- -
-
- Contacts - - - -
-
- - - - - - {{item.name}} -

- {{item.displayCoin}} -

- -
-
- Show more +
+
+
+
+
Contacts
+
Saved frequently used addresses
+ + + +
+
- -
-
- Transfer to Wallet - - -
- -
- + + + + + +