diff --git a/app-template/bitcoincom/appConfig.json b/app-template/bitcoincom/appConfig.json
index 28e24e9fb..fefcb9a4f 100644
--- a/app-template/bitcoincom/appConfig.json
+++ b/app-template/bitcoincom/appConfig.json
@@ -24,9 +24,9 @@
"windowsAppId": "804636ee-b017-4cad-8719-e58ac97ffa5c",
"pushSenderId": "1036948132229",
"description": "A Secure Bitcoin Wallet",
- "version": "4.12.2",
- "fullVersion": "4.12-rc3",
- "androidVersion": "412200",
+ "version": "4.13.0",
+ "fullVersion": "4.13-rc1",
+ "androidVersion": "413000",
"_extraCSS": "",
"_enabledExtensions": {
"coinbase": false,
diff --git a/i18n/po/template.pot b/i18n/po/template.pot
index 2ee53ec78..4bab9ff2e 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 ""
@@ -815,7 +819,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 ""
@@ -2525,6 +2529,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 ""
@@ -2583,9 +2595,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/buyBitcoindotcom.js b/src/js/controllers/buyBitcoindotcom.js
index 741898c34..64766eede 100644
--- a/src/js/controllers/buyBitcoindotcom.js
+++ b/src/js/controllers/buyBitcoindotcom.js
@@ -1,7 +1,9 @@
'use strict';
angular.module('copayApp.controllers').controller('buyBitcoindotcomController',
- function($scope, $timeout, $ionicModal, $log, $state, $ionicHistory, lodash, bitcoincomService, externalLinkService, popupService) {
+ function($scope, platformInfo, externalLinkService) {
+
+ $scope.os = platformInfo.isAndroid ? 'android' : platformInfo.isIOS ? 'ios' : 'desktop';
$scope.openExternalLink = function(url) {
externalLinkService.open(url);
diff --git a/src/js/controllers/feedback/rateApp.js b/src/js/controllers/feedback/rateApp.js
deleted file mode 100644
index 6ae485a3a..000000000
--- a/src/js/controllers/feedback/rateApp.js
+++ /dev/null
@@ -1,53 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('rateAppController', function($scope, $state, $stateParams, $window, lodash, externalLinkService, configService, platformInfo, feedbackService, ongoingProcess, popupService, appConfigService) {
- $scope.score = parseInt($stateParams.score);
- $scope.appName = appConfigService.nameCase;
- var isAndroid = platformInfo.isAndroid;
- var isIOS = platformInfo.isIOS;
-
- var config = configService.getSync();
-
- $scope.skip = function() {
- var dataSrc = {
- "Email": lodash.values(config.emailFor)[0] || ' ',
- "Feedback": ' ',
- "Score": $stateParams.score,
- "AppVersion": $window.version,
- "Platform": ionic.Platform.platform(),
- "DeviceVersion": ionic.Platform.version()
- };
- feedbackService.send(dataSrc, function(err) {
- if (err) {
- // try to send, but not essential, since the user didn't add a message
- $log.warn('Could not send feedback.');
- }
- });
- $state.go('tabs.rate.complete', {
- score: $stateParams.score,
- skipped: true
- });
- };
-
- $scope.sendFeedback = function() {
- $state.go('tabs.rate.send', {
- score: $scope.score
- });
- };
-
- $scope.goAppStore = function() {
- var defaults = configService.getDefaults();
- var url;
- if (isAndroid)
- url = defaults.rateApp.bitcoincom.android;
- if (isIOS)
- url = defaults.rateApp.bitcoincom.ios;
-
- externalLinkService.open(url);
- $state.go('tabs.rate.complete', {
- score: $stateParams.score,
- skipped: true,
- rated: true
- });
- };
-});
diff --git a/src/js/controllers/feedback/rateCard.js b/src/js/controllers/feedback/rateCard.js
deleted file mode 100644
index abc109796..000000000
--- a/src/js/controllers/feedback/rateCard.js
+++ /dev/null
@@ -1,60 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('rateCardController', function($scope, $state, $timeout, $log, gettextCatalog, platformInfo, storageService, appConfigService) {
-
- $scope.isCordova = platformInfo.isCordova;
- $scope.score = 0;
- $scope.appName = appConfigService.nameCase;
-
- $scope.goFeedbackFlow = function() {
- $scope.hideCard();
- if ($scope.isCordova && $scope.score == 5) {
- $state.go('tabs.rate.rateApp', {
- score: $scope.score
- });
- } else {
- $state.go('tabs.rate.send', {
- score: $scope.score
- });
- }
- };
-
- $scope.setScore = function(score) {
- $scope.score = score;
- switch ($scope.score) {
- case 1:
- $scope.button_title = gettextCatalog.getString("I think this app is terrible.");
- break;
- case 2:
- $scope.button_title = gettextCatalog.getString("I don't like it");
- break;
- case 3:
- $scope.button_title = gettextCatalog.getString("Meh - it's alright");
- break;
- case 4:
- $scope.button_title = gettextCatalog.getString("I like the app");
- break;
- case 5:
- $scope.button_title = gettextCatalog.getString("This app is fantastic!");
- break;
- }
- $timeout(function() {
- $scope.$apply();
- });
- };
-
- $scope.hideCard = function() {
- $log.debug('Feedback card dismissed.')
- storageService.getFeedbackInfo(function(error, info) {
- var feedbackInfo = JSON.parse(info);
- feedbackInfo.sent = true;
- storageService.setFeedbackInfo(JSON.stringify(feedbackInfo), function() {
- $scope.showRateCard.value = false;
- $timeout(function() {
- $scope.$apply();
- }, 100);
- });
- });
- }
-
-});
diff --git a/src/js/controllers/feedback/send.js b/src/js/controllers/feedback/send.js
deleted file mode 100644
index 23fb0ea59..000000000
--- a/src/js/controllers/feedback/send.js
+++ /dev/null
@@ -1,102 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('sendController', function($scope, $state, $log, $timeout, $stateParams, $ionicNavBarDelegate, $ionicHistory, $ionicConfig, $window, gettextCatalog, popupService, configService, lodash, feedbackService, ongoingProcess, platformInfo, appConfigService) {
-
- $scope.sendFeedback = function(feedback, goHome) {
-
- var config = configService.getSync();
-
- var dataSrc = {
- "Email": lodash.values(config.emailFor)[0] || ' ',
- "Feedback": goHome ? ' ' : feedback,
- "Score": $stateParams.score || ' ',
- "AppVersion": $window.version,
- "Platform": ionic.Platform.platform(),
- "DeviceVersion": ionic.Platform.version()
- };
-
- if (!goHome) ongoingProcess.set('sendingFeedback', true);
- feedbackService.send(dataSrc, function(err) {
- if (goHome) return;
- ongoingProcess.set('sendingFeedback', false);
- if (err) {
- popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Feedback could not be submitted. Please try again later.'));
- return;
- }
- if (!$stateParams.score) {
- popupService.showAlert(gettextCatalog.getString('Thank you!'), gettextCatalog.getString('A member of the team will review your feedback as soon as possible.'), function() {
- $scope.feedback.value = '';
- $ionicHistory.nextViewOptions({
- disableAnimate: false,
- historyRoot: true
- });
- $ionicHistory.goBack();
- }, gettextCatalog.getString('Finish'));
- return;
- }
- $state.go('tabs.rate.complete', {
- score: $stateParams.score
- });
- });
- if (goHome) $state.go('tabs.home');
- };
-
- $scope.$on("$ionicView.beforeLeave", function(event, data) {
- $ionicConfig.views.swipeBackEnabled(true);
- });
-
- $scope.$on("$ionicView.enter", function(event, data) {
- if ($scope.score)
- $ionicConfig.views.swipeBackEnabled(false);
- });
-
- $scope.$on("$ionicView.beforeEnter", function(event, data) {
- $scope.isCordova = platformInfo.isCordova;
- $scope.score = (data.stateParams && data.stateParams.score) ? parseInt(data.stateParams.score) : null;
- $scope.feedback = {};
-
- switch ($scope.score) {
- case 1:
- $scope.reaction = "Ouch!";
- $scope.comment = gettextCatalog.getString("There's obviously something we're doing wrong.") + ' ' + gettextCatalog.getString("How could we improve your experience?");
- break;
- case 2:
- $scope.reaction = gettextCatalog.getString("Oh no!");
- $scope.comment = gettextCatalog.getString("There's obviously something we're doing wrong.") + ' ' + gettextCatalog.getString("How could we improve your experience?");
- break;
- case 3:
- $scope.reaction = "Hmm...";
- $scope.comment = gettextCatalog.getString("We'd love to do better.") + ' ' + gettextCatalog.getString("How could we improve your experience?");
- break;
- case 4:
- $scope.reaction = gettextCatalog.getString("Thanks!");
- $scope.comment = gettextCatalog.getString("That's exciting to hear. We'd love to earn that fifth star from you – how could we improve your experience?");
- break;
- case 5:
- $scope.reaction = gettextCatalog.getString("Thank you!");
- $scope.comment = gettextCatalog.getString("We're always looking for ways to improve {{appName}}.", {
- appName: appConfigService.nameCase
- }) + ' ' + gettextCatalog.getString("Is there anything we could do better?");
- break;
- default:
- $scope.justFeedback = true;
- $scope.comment = gettextCatalog.getString("We're always looking for ways to improve {{appName}}. How could we improve your experience?", {
- appName: appConfigService.nameCase
- });
- break;
- }
- });
-
- $scope.$on("$ionicView.afterEnter", function() {
- $scope.showForm = true;
- });
-
- $scope.goBack = function() {
- $ionicHistory.nextViewOptions({
- disableAnimate: false,
- historyRoot: true
- });
- $ionicHistory.goBack();
- };
-
-});
diff --git a/src/js/controllers/feedback/complete.js b/src/js/controllers/shareApp.js
similarity index 77%
rename from src/js/controllers/feedback/complete.js
rename to src/js/controllers/shareApp.js
index 905880901..ba3fdedff 100644
--- a/src/js/controllers/feedback/complete.js
+++ b/src/js/controllers/shareApp.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('completeController', function($scope, $stateParams, $timeout, $log, $ionicHistory, $state, $ionicNavBarDelegate, $ionicConfig, platformInfo, configService, storageService, lodash, appConfigService, gettextCatalog) {
+angular.module('copayApp.controllers').controller('shareAppController', function($scope, $stateParams, $timeout, $log, $ionicHistory, $state, $ionicNavBarDelegate, $ionicConfig, platformInfo, configService, storageService, lodash, appConfigService, gettextCatalog) {
$scope.isCordova = platformInfo.isCordova;
$scope.title = gettextCatalog.getString("Share {{appName}}", {
appName: appConfigService.nameCase
@@ -57,28 +57,8 @@ angular.module('copayApp.controllers').controller('completeController', function
$ionicConfig.views.swipeBackEnabled(true);
});
- $scope.$on("$ionicView.enter", function() {
- if (!$scope.fromSettings)
- $ionicConfig.views.swipeBackEnabled(false);
- });
-
$scope.$on("$ionicView.beforeEnter", function(event, data) {
- $scope.score = (data.stateParams && data.stateParams.score) ? parseInt(data.stateParams.score) : null;
- $scope.skipped = (data.stateParams && data.stateParams.skipped) ? true : false;
- $scope.rated = (data.stateParams && data.stateParams.rated) ? true : false;
- $scope.fromSettings = (data.stateParams && data.stateParams.fromSettings) ? true : false;
-
- if (!$scope.fromSettings) {
- $ionicNavBarDelegate.showBackButton(false);
- } else {
- $ionicNavBarDelegate.showBackButton(true);
- }
-
- storageService.getFeedbackInfo(function(error, info) {
- var feedbackInfo = lodash.isString(info) ? JSON.parse(info) : null;
- feedbackInfo.sent = true;
- storageService.setFeedbackInfo(JSON.stringify(feedbackInfo), function() {});
- });
+ $ionicNavBarDelegate.showBackButton(true);
if (!$scope.isCordova) return;
$scope.animate = true;
@@ -133,13 +113,4 @@ angular.module('copayApp.controllers').controller('completeController', function
}
}, 100);
});
-
- $scope.close = function() {
- $ionicHistory.nextViewOptions({
- disableAnimate: false,
- historyRoot: true
- });
- if ($scope.score == 5) $ionicHistory.goBack(-3);
- else $ionicHistory.goBack(-2);
- };
});
diff --git a/src/js/controllers/tab-home.js b/src/js/controllers/tab-home.js
index 3a56e6d5c..a04820ebd 100644
--- a/src/js/controllers/tab-home.js
+++ b/src/js/controllers/tab-home.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('tabHomeController',
- function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, feedbackService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
+ function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
var wallet;
var listeners = [];
var notifications = [];
@@ -14,7 +14,6 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.isAndroid = platformInfo.isAndroid;
$scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
$scope.isNW = platformInfo.isNW;
- $scope.showRateCard = {};
$scope.showServices = false;
$scope.bannerIsLoading = true;
$scope.bannerImageUrl = '';
@@ -52,43 +51,6 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
});
}
-
- storageService.getFeedbackInfo(function(error, info) {
-
- if ($scope.isWindowsPhoneApp) {
- $scope.showRateCard.value = false;
- return;
- }
- if (!info) {
- initFeedBackInfo();
- } else {
- var feedbackInfo = JSON.parse(info);
- //Check if current version is greater than saved version
- var currentVersion = $scope.version;
- var savedVersion = feedbackInfo.version;
- var isVersionUpdated = feedbackService.isVersionUpdated(currentVersion, savedVersion);
- if (!isVersionUpdated) {
- initFeedBackInfo();
- return;
- }
- var now = moment().unix();
- var timeExceeded = (now - feedbackInfo.time) >= 24 * 7 * 60 * 60;
- $scope.showRateCard.value = timeExceeded && !feedbackInfo.sent;
- $timeout(function() {
- $scope.$apply();
- });
- }
- });
-
- function initFeedBackInfo() {
- var feedbackInfo = {};
- feedbackInfo.time = moment().unix();
- feedbackInfo.version = $scope.version;
- feedbackInfo.sent = false;
- storageService.setFeedbackInfo(JSON.stringify(feedbackInfo), function() {
- $scope.showRateCard.value = false;
- });
- };
});
$scope.$on("$ionicView.enter", function(event, data) {
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/controllers/tab-settings.js b/src/js/controllers/tab-settings.js
index 6cfc80def..4d0636d53 100644
--- a/src/js/controllers/tab-settings.js
+++ b/src/js/controllers/tab-settings.js
@@ -45,6 +45,18 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
});
};
+ $scope.sendFeedback = function() {
+ var mailToLink = 'mailto:wallet@bitcoin.com?subject=Feedback%20for%20Bitcoin.com%20Wallet';
+ if (platformInfo.isNW) {
+ nw.Shell.openExternal(mailToLink);
+ } else if (platformInfo.isCordova) {
+ var mailWindow = window.open(mailToLink, '_system');
+ mailWindow.close(); // XX SP: bugfix for some browsers in cordova to change the view entirely
+ } else {
+ window.location.href = mailToLink;
+ }
+ };
+
$scope.openExternalLink = function() {
var appName = appConfigService.name;
var url = appName == 'copay' ? 'https://github.com/bitcoin-com/wallet/issues' : 'https://www.bitcoin.com/wallet-support';
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: '
'
+ template: ''
};
});
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/routes.js b/src/js/routes.js
index 63b436a85..8277314e5 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -795,63 +795,15 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
fromOnboarding: null
},
})
-
- /*
- *
- * Feedback
- *
- */
-
- .state('tabs.feedback', {
- url: '/feedback',
- views: {
- 'tab-settings@tabs': {
- templateUrl: 'views/feedback/send.html',
- controller: 'sendController'
- }
- }
- })
.state('tabs.shareApp', {
- url: '/shareApp/:score/:skipped/:fromSettings',
+ url: '/shareApp',
views: {
'tab-settings@tabs': {
- controller: 'completeController',
- templateUrl: 'views/feedback/complete.html'
+ controller: 'shareAppController',
+ templateUrl: 'views/shareApp.html'
}
}
})
- .state('tabs.rate', {
- url: '/rate',
- abstract: true
- })
- .state('tabs.rate.send', {
- url: '/send/:score',
- views: {
- 'tab-home@tabs': {
- templateUrl: 'views/feedback/send.html',
- controller: 'sendController'
- }
- }
- })
- .state('tabs.rate.complete', {
- url: '/complete/:score/:skipped',
- views: {
- 'tab-home@tabs': {
- controller: 'completeController',
- templateUrl: 'views/feedback/complete.html'
- }
- }
- })
- .state('tabs.rate.rateApp', {
- url: '/rateApp/:score',
- views: {
- 'tab-home@tabs': {
- controller: 'rateAppController',
- templateUrl: 'views/feedback/rateApp.html'
- }
- }
- })
-
/*
*
* Buy or Sell Bitcoin
diff --git a/src/js/services/bitcoincomService.js b/src/js/services/bitcoincomService.js
index 681ed8f4d..051123111 100644
--- a/src/js/services/bitcoincomService.js
+++ b/src/js/services/bitcoincomService.js
@@ -1,12 +1,13 @@
'use strict';
-angular.module('copayApp.services').factory('bitcoincomService', function($http, $log, lodash, moment, storageService, configService, platformInfo, nextStepsService, homeIntegrationsService) {
+angular.module('copayApp.services').factory('bitcoincomService', function(platformInfo, nextStepsService) {
var root = {};
var credentials = {};
/*
* Development: 'testnet'
* Production: 'livenet'
- */
+ */
+ var os = platformInfo.isAndroid ? 'android' : platformInfo.isIOS ? 'ios' : 'desktop';
credentials.NETWORK = 'livenet';
//credentials.NETWORK = 'testnet';
@@ -20,28 +21,28 @@ angular.module('copayApp.services').factory('bitcoincomService', function($http,
name: 'games',
title: 'Bitcoin Cash Games',
icon: 'icon-games',
- href: 'http://cashgames.bitcoin.com'
+ href: 'https://cashgames.bitcoin.com'
};
var newsItem = {
name: 'news',
title: 'News',
icon: 'icon-news',
- href: 'http://news.bitcoin.com'
+ href: 'https://news.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=News'
};
var poolItem = {
name: 'pool',
title: 'Mining Pool',
icon: 'icon-mining',
- href: 'http://pool.bitcoin.com'
+ href: 'https://pool.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Pool'
};
var toolsItem = {
name: 'tools',
title: 'Tools',
icon: 'icon-tools',
- href: 'http://tools.bitcoin.com'
+ href: 'https://tools.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Tools'
};
var priceChartItem = {
@@ -55,7 +56,7 @@ angular.module('copayApp.services').factory('bitcoincomService', function($http,
name: 'faucet',
title: 'Free Bitcoin Cash',
icon: 'icon-faucet',
- href: 'https://free.bitcoin.com/'
+ href: 'https://free.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Faucet'
};
var _getBitPay = function(endpoint) {
diff --git a/src/js/services/clipboardService.js b/src/js/services/clipboardService.js
index 8712e234b..075cb749a 100644
--- a/src/js/services/clipboardService.js
+++ b/src/js/services/clipboardService.js
@@ -22,7 +22,27 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
// Not 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(function (text) {
+ cb(text);
+ })
+ .catch(function (err) {
+ $log.debug("Clipboard reading is not supported in browser..");
+ });
+
+ return;
+ }
};
return root;
diff --git a/src/js/services/feedbackService.js b/src/js/services/feedbackService.js
deleted file mode 100644
index ae4711d27..000000000
--- a/src/js/services/feedbackService.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict';
-angular.module('copayApp.services').factory('feedbackService', function($http, $log, $httpParamSerializer, configService) {
- var root = {};
-// var URL = "https://script.google.com/macros/s/1pWGRxVSUX9CxPqNAKZTppWHtDvyVtZv9HteY_TRQbWc/exec";
- var URL = "https://wallet-data.bitcoin.com/feedback.php";
-
- root.send = function(dataSrc, cb) {
- $http(_post(dataSrc)).then(function() {
- $log.info("SUCCESS: Feedback sent");
- return cb();
- }, function(err) {
- $log.info("ERROR: Feedback sent anyway.");
- return cb(err);
- });
- };
-
- var _post = function(dataSrc) {
- return {
- method: 'POST',
- url: URL,
- headers: {
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
- },
- data: $httpParamSerializer(dataSrc)
- };
- };
-
- root.isVersionUpdated = function(currentVersion, savedVersion) {
-
- if (!verifyTagFormat(currentVersion))
- return 'Cannot verify the format of version tag: ' + currentVersion;
- if (!verifyTagFormat(savedVersion))
- return 'Cannot verify the format of the saved version tag: ' + savedVersion;
-
- var current = formatTagNumber(currentVersion);
- var saved = formatTagNumber(savedVersion);
- if (saved.major > current.major || (saved.major == current.major && saved.minor > current.minor))
- return false;
-
- return true;
-
- function verifyTagFormat(tag) {
- var regex = /^v?\d+\.\d+\.\d+$/i;
- return regex.exec(tag);
- };
-
- function formatTagNumber(tag) {
- var formattedNumber = tag.replace(/^v/i, '').split('.');
- return {
- major: +formattedNumber[0],
- minor: +formattedNumber[1],
- patch: +formattedNumber[2]
- };
- };
-
- };
-
- 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/js/services/storageService.js b/src/js/services/storageService.js
index 10f0cdd76..c979098ee 100644
--- a/src/js/services/storageService.js
+++ b/src/js/services/storageService.js
@@ -217,14 +217,6 @@ angular.module('copayApp.services')
});
};
- root.setFeedbackInfo = function(feedbackValues, cb) {
- storage.set('feedback', feedbackValues, cb);
- };
-
- root.getFeedbackInfo = function(cb) {
- storage.get('feedback', cb);
- };
-
root.storeFocusedWalletId = function(id, cb) {
storage.set('focusedWalletId', id || '', cb);
};
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/feedback/rateApp.scss b/src/sass/views/feedback/rateApp.scss
deleted file mode 100644
index 8a4cd2b8e..000000000
--- a/src/sass/views/feedback/rateApp.scss
+++ /dev/null
@@ -1,38 +0,0 @@
-#rate-app {
- background-color: #ffffff;
- text-align: center;
- .skip-rating {
- color: $v-dark-gray;
- position: absolute;
- top: 5px;
- right: 10px;
- padding: 15px;
- }
- .icon-svg > img {
- width: 80px;
- height: 80px;
- margin-top: 15px;
- }
- .feedback-title {
- font-size: 20px;
- font-weight: bold;
- color: $v-dark-gray;
- margin: 80px 50px 10px;
- text-align: center;
- }
- .share-the-love-illustration {
- width: 5rem;
- margin: 1rem;
- }
- .subtitle {
- padding: 10px 30px 20px 40px;
- color: $v-mid-gray;
- }
- .rate-buttons {
- bottom: 0;
- width: 100%;
- position: absolute;
- background-color: $v-subtle-gray;
- padding: 30px 0 15px;
- }
-}
diff --git a/src/sass/views/feedback/rateCard.scss b/src/sass/views/feedback/rateCard.scss
deleted file mode 100644
index 9d57643d6..000000000
--- a/src/sass/views/feedback/rateCard.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-#rate-card {
- .item-heading {
- font-weight: 700;
- }
- .row {
- border: none;
- }
- .item-icon-right {
- margin: 0;
- }
- .feedback-flow-button {
- margin-bottom: 20px;
- }
- .icon-svg > img {
- height: 1.8rem;
- margin-bottom: 5px;
- }
-}
diff --git a/src/sass/views/feedback/send.scss b/src/sass/views/feedback/send.scss
deleted file mode 100644
index 807c4f8c5..000000000
--- a/src/sass/views/feedback/send.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-#send-feedback {
- @extend .deflash-blue;
- background-color: #ffffff;
- .row {
- border: none;
- }
- .skip {
- color: rgba(255, 255, 255, 0.3);
- }
- .feedback-heading {
- padding-top: 20px
- }
- .feedback-title {
- padding-left: 10px;
- font-size: 20px;
- font-weight: bold;
- color: $v-dark-gray;
- }
- .rating {
- text-align: right;
- padding-right: 15px;
- }
- .comment {
- padding: 0 20px 20px;
- font-size: 1rem;
- line-height: 1.5em;
- font-weight: 300;
- color: $v-dark-gray;
- }
- .user-feedback {
- border-top: 1px solid $v-subtle-gray;
- border-bottom: 1px solid $v-subtle-gray;
- padding: 20px;
- width: 100%;
- margin-bottom: 20px;
- -webkit-appearance: none;
- }
- .send-feedback-star {
- height: 1rem;
- margin-left: 5px;
- }
- .form-fade-in {
- opacity: 0;
- animation-name: fadeIn;
- animation-duration: .5s;
- animation-fill-mode: forwards;
- animation-timing-function: ease-in;
- }
-}
-
-@keyframes fadeIn {
- from { opacity: 0; }
- to { opacity: 1; }
-}
diff --git a/src/sass/views/feedback/complete.scss b/src/sass/views/shareApp.scss
similarity index 86%
rename from src/sass/views/feedback/complete.scss
rename to src/sass/views/shareApp.scss
index bb2e75ea6..9a0ed0698 100644
--- a/src/sass/views/feedback/complete.scss
+++ b/src/sass/views/shareApp.scss
@@ -1,6 +1,6 @@
-#complete {
+#share-app {
background-color: #fff;
- .complete-layout {
+ .share-app-layout {
display: flex;
flex-direction: column;
height: 100%;
@@ -22,17 +22,6 @@
width: 5rem;
margin: 1rem;
}
- .send-feedback-illustration {
- height: 16rem;
- margin: 1rem;
- }
- .feedback-title {
- font-size: 20px;
- font-weight: bold;
- color: $v-dark-gray;
- margin: 20px 10px;
- text-align: center;
- }
.subtitle {
padding: 10px 30px 20px;
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/src/sass/views/views.scss b/src/sass/views/views.scss
index 37754970f..d4ed735ed 100644
--- a/src/sass/views/views.scss
+++ b/src/sass/views/views.scss
@@ -22,10 +22,7 @@
@import "wallet-backup-phrase";
@import "zero-state";
@import "onboarding/onboarding";
-@import "feedback/rateCard";
-@import "feedback/send";
-@import "feedback/complete";
-@import "feedback/rateApp";
+@import "shareApp";
@import "includes/actionSheet";
@import "export";
@import "import";
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 @@
-
-
-
+
+
\ 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/buyBitcoindotcom.html b/www/views/buyBitcoindotcom.html
index 2c8ef36f1..f0f8e27e3 100644
--- a/www/views/buyBitcoindotcom.html
+++ b/www/views/buyBitcoindotcom.html
@@ -15,7 +15,7 @@