fix merge conflicts

This commit is contained in:
Marty Alcala 2016-10-11 19:14:13 -04:00
commit 6bfdec29b3
44 changed files with 28907 additions and 196 deletions

View file

@ -13,12 +13,12 @@
"gitHubRepoName": "bitpay-wallet", "gitHubRepoName": "bitpay-wallet",
"disclaimerUrl": "", "disclaimerUrl": "",
"url": "https://bitpay.com", "url": "https://bitpay.com",
"appDescription": "Secure Bitcoin Storage", "appDescription": "Secure Bitcoin Wallet",
"winAppName": "BitPayWallet", "winAppName": "BitPayWallet",
"wpPublisherId": "{}", "wpPublisherId": "{}",
"wpProductId": "{}", "wpProductId": "{}",
"pushSenderId": "1036948132229", "pushSenderId": "1036948132229",
"description": "Secure Bitcoin Storage", "description": "Secure Bitcoin Wallet",
"version": "0.14.0", "version": "0.14.0",
"androidVersion": "1", "androidVersion": "1",
"_extraCSS": null, "_extraCSS": null,

11968
public/css/copay.css Normal file

File diff suppressed because it is too large Load diff

16611
public/js/copay.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 KiB

After

Width:  |  Height:  |  Size: 526 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 KiB

After

Width:  |  Height:  |  Size: 550 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Before After
Before After

Binary file not shown.

View file

@ -116,7 +116,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}; };
popupService.showPrompt(null, message, opts, function(res) { popupService.showPrompt(null, message, opts, function(res) {
if (res) $scope.description = res; if (typeof res != 'undefined') $scope.description = res;
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 100); }, 100);

View file

@ -1,7 +1,8 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, popupService, gettextCatalog) { angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, $ionicConfig, popupService, gettextCatalog) {
$ionicConfig.views.swipeBackEnabled(false);
$scope.walletId = $stateParams.walletId; $scope.walletId = $stateParams.walletId;
$scope.openPopup = function() { $scope.openPopup = function() {
@ -18,7 +19,10 @@ angular.module('copayApp.controllers').controller('backupRequestController', fun
var cancelText = gettextCatalog.getString('Go back'); var cancelText = gettextCatalog.getString('Go back');
popupService.showConfirm(title, message, okText, cancelText, function(val) { popupService.showConfirm(title, message, okText, cancelText, function(val) {
if (val) { if (val) {
$state.go('onboarding.disclaimer', {walletId: $scope.walletId, backedUp: false}); $state.go('onboarding.disclaimer', {
walletId: $scope.walletId,
backedUp: false
});
} }
}); });
} }

View file

@ -2,6 +2,10 @@
angular.module('copayApp.controllers').controller('backupWarningController', function($scope, $state, $timeout, $stateParams, $ionicModal) { angular.module('copayApp.controllers').controller('backupWarningController', function($scope, $state, $timeout, $stateParams, $ionicModal) {
$scope.walletId = $stateParams.walletId;
$scope.fromState = $stateParams.from == 'onboarding' ? $stateParams.from + '.backupRequest' : $stateParams.from;
$scope.toState = $stateParams.from + '.backup';
$scope.openPopup = function() { $scope.openPopup = function() {
$ionicModal.fromTemplateUrl('views/includes/screenshotWarningModal.html', { $ionicModal.fromTemplateUrl('views/includes/screenshotWarningModal.html', {
scope: $scope, scope: $scope,
@ -15,24 +19,15 @@ angular.module('copayApp.controllers').controller('backupWarningController', fun
$scope.close = function() { $scope.close = function() {
$scope.warningModal.hide(); $scope.warningModal.hide();
$scope.warningModal.remove(); $scope.warningModal.remove();
$state.go($scope.toState, {
$timeout(function() { walletId: $scope.walletId
if ($stateParams.from == 'onboarding.backupRequest') {
$state.go('onboarding.backup', {
walletId: $stateParams.walletId
});
} else {
$state.go($stateParams.from + '.backup', {
walletId: $stateParams.walletId
});
}
}); });
}; };
} }
$scope.goBack = function() { $scope.goBack = function() {
$state.go($stateParams.from, { $state.go($scope.fromState, {
walletId: $stateParams.walletId walletId: $scope.walletId
}); });
}; };

View file

@ -1,7 +1,8 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('collectEmailController', function($scope, $state, $timeout, $stateParams, profileService, configService, walletService, platformInfo) { angular.module('copayApp.controllers').controller('collectEmailController', function($scope, $state, $timeout, $stateParams, $ionicConfig, profileService, configService, walletService, platformInfo) {
$ionicConfig.views.swipeBackEnabled(false);
var isCordova = platformInfo.isCordova; var isCordova = platformInfo.isCordova;
var isWP = platformInfo.isWP; var isWP = platformInfo.isWP;
var usePushNotifications = isCordova && !isWP; var usePushNotifications = isCordova && !isWP;

View file

@ -6,6 +6,7 @@ angular.module('copayApp.controllers').controller('disclaimerController', functi
$scope.terms = {}; $scope.terms = {};
$scope.accept1 = $scope.accept2 = $scope.accept3 = false; $scope.accept1 = $scope.accept2 = $scope.accept3 = false;
$scope.backedUp = $stateParams.backedUp; $scope.backedUp = $stateParams.backedUp;
$scope.resume = $stateParams.resume;
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 1); }, 1);
@ -35,8 +36,10 @@ angular.module('copayApp.controllers').controller('disclaimerController', functi
}); });
}; };
$scope.goBack = function(){ $scope.goBack = function() {
$state.go('onboarding.backupRequest', {walletId: $stateParams.walletId}); $state.go('onboarding.backupRequest', {
walletId: $stateParams.walletId
});
} }

View file

@ -1,10 +1,9 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('notificationsController', function($scope, $state, $timeout, $stateParams, profileService, configService) { angular.module('copayApp.controllers').controller('notificationsController', function($scope, $state, $timeout, $stateParams, $ionicConfig, profileService, configService) {
$scope.$on("$ionicView.enter", function(event, data) { $ionicConfig.views.swipeBackEnabled(false);
$scope.walletId = data.stateParams.walletId; $scope.walletId = $stateParams.walletId;
});
$scope.allowNotif = function() { $scope.allowNotif = function() {
$timeout(function() { $timeout(function() {

View file

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('tourController', angular.module('copayApp.controllers').controller('tourController',
function($scope, $state, $log, $timeout, $filter, ongoingProcess, platformInfo, profileService, rateService) { function($scope, $state, $log, $timeout, $filter, ongoingProcess, platformInfo, profileService, rateService, popupService, gettextCatalog) {
var isCordova = platformInfo.isCordova; var isCordova = platformInfo.isCordova;
var isWP = platformInfo.isWP; var isWP = platformInfo.isWP;
@ -37,6 +37,7 @@ angular.module('copayApp.controllers').controller('tourController',
}); });
}); });
var retryCount = 0;
$scope.createDefaultWallet = function() { $scope.createDefaultWallet = function() {
ongoingProcess.set('creatingWallet', true); ongoingProcess.set('creatingWallet', true);
profileService.createDefaultWallet(function(err, walletClient) { profileService.createDefaultWallet(function(err, walletClient) {
@ -44,9 +45,19 @@ angular.module('copayApp.controllers').controller('tourController',
$log.warn(err); $log.warn(err);
return $timeout(function() { return $timeout(function() {
$log.warn('Retrying to create default wallet......'); $log.warn('Retrying to create default wallet.....:' + ++retryCount);
return $scope.createDefaultWallet(); if (retryCount > 3) {
}, 3000); ongoingProcess.set('creatingWallet', false);
popupService.showAlert(
gettextCatalog.getString('Cannot Create Wallet'), err,
function() {
retryCount = 0;
return $scope.createDefaultWallet();
}, gettextCatalog.getString('Retry'));
} else {
return $scope.createDefaultWallet();
}
}, 2000);
}; };
ongoingProcess.set('creatingWallet', false); ongoingProcess.set('creatingWallet', false);
var wallet = walletClient; var wallet = walletClient;
@ -55,8 +66,7 @@ angular.module('copayApp.controllers').controller('tourController',
$state.go('onboarding.backupRequest', { $state.go('onboarding.backupRequest', {
walletId: walletId walletId: walletId
}); });
} } else {
else {
$state.go('onboarding.notifications', { $state.go('onboarding.notifications', {
walletId: walletId walletId: walletId
}); });

View file

@ -1,6 +1,8 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $log, profileService) { angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $ionicConfig, $log, profileService) {
$ionicConfig.views.swipeBackEnabled(false);
$scope.goImport = function(code) { $scope.goImport = function(code) {
$state.go('onboarding.import', { $state.go('onboarding.import', {

View file

@ -11,12 +11,13 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.version = $window.version; $scope.version = $window.version;
$scope.name = $window.appConfig.nameCase; $scope.name = $window.appConfig.nameCase;
$scope.homeTip = $stateParams.fromOnboarding; $scope.homeTip = $stateParams.fromOnboarding;
$scope.isCordova = platformInfo.isCordova;
if(!$scope.homeTip){ if (!$scope.homeTip) {
storageService.getHomeTipAccepted(function(error, value){ storageService.getHomeTipAccepted(function(error, value) {
$scope.homeTip = (value == 'false') ? false : true; $scope.homeTip = (value == 'false') ? false : true;
}); });
} }
$scope.openNotificationModal = function(n) { $scope.openNotificationModal = function(n) {
wallet = profileService.getWallet(n.walletId); wallet = profileService.getWallet(n.walletId);
@ -170,8 +171,11 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}; };
$scope.hideHomeTip = function() { $scope.hideHomeTip = function() {
storageService.setHomeTipAccepted(false, function(error, value){ storageService.setHomeTipAccepted(false, function(error, value) {
$scope.homeTip = false; $scope.homeTip = false;
$timeout(function() {
$scope.$apply();
})
}); });
}; };
@ -201,6 +205,11 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}); });
}; };
$scope.onRefresh = function() {
$scope.$broadcast('scroll.refreshComplete');
updateAllWallets();
};
$scope.$on("$ionicView.enter", function(event, data) { $scope.$on("$ionicView.enter", function(event, data) {
$scope.bitpayCard = null; $scope.bitpayCard = null;
nextStep(); nextStep();

View file

@ -6,6 +6,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
var CONTACTS_SHOW_LIMIT; var CONTACTS_SHOW_LIMIT;
var currentContactsPage; var currentContactsPage;
var updateList = function() { var updateList = function() {
CONTACTS_SHOW_LIMIT = 10; CONTACTS_SHOW_LIMIT = 10;
currentContactsPage = 0; currentContactsPage = 0;
@ -103,11 +104,56 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
}); });
}; };
var updateHasFunds = function() {
$scope.hasFunds = null;
var wallets = profileService.getWallets({
onlyComplete: true,
});
if (!wallets || !wallets.length) {
$scope.hasFunds = false;
}
var index = 0;
lodash.each(wallets, function(w) {
walletService.getStatus(w, {}, function(err, status) {
++index;
if (err || !status) {
$log.error(err);
return;
}
if (status.availableBalanceSat) {
$scope.hasFunds = true;
}
if (index == wallets.length) {
$scope.hasFunds = $scope.hasFunds || false;
}
});
});
};
$scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.formData = { $scope.formData = {
search: null search: null
}; };
updateList(); updateList();
updateHasFunds();
}); });
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.add.create-personal');
});
};
$scope.buyBitcoin = function() {
$state.go('tabs.home').then(function() {
$state.go('tabs.buyandsell.glidera');
});
};
}); });

View file

@ -8,6 +8,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.txps = []; $scope.txps = [];
$scope.completeTxHistory = []; $scope.completeTxHistory = [];
$scope.openTxpModal = txpModalService.open; $scope.openTxpModal = txpModalService.open;
$scope.isCordova = platformInfo.isCordova;
$scope.openExternalLink = function(url, target) { $scope.openExternalLink = function(url, target) {
externalLinkService.open(url, target); externalLinkService.open(url, target);
@ -159,6 +160,11 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}, 100); }, 100);
}; };
$scope.onRefresh = function() {
$scope.$broadcast('scroll.refreshComplete');
$scope.updateAll(true);
};
$scope.updateAll = function(force, cb)  { $scope.updateAll = function(force, cb)  {
updateStatus(force); updateStatus(force);
updateTxHistory(cb); updateTxHistory(cb);

View file

@ -689,7 +689,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
} }
}) })
.state('onboarding.disclaimer', { .state('onboarding.disclaimer', {
url: '/disclaimer/:walletId/:backedUp', url: '/disclaimer/:walletId/:backedUp/:resume',
views: { views: {
'onboarding': { 'onboarding': {
templateUrl: 'views/onboarding/disclaimer.html' templateUrl: 'views/onboarding/disclaimer.html'
@ -840,13 +840,13 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
} }
}) })
/* /*
* *
* BitPay Card * BitPay Card
* *
*/ */
.state('tabs.bitpayCard', { .state('tabs.bitpayCard', {
url: '/bitpay-card', url: '/bitpay-card',
views: { views: {
'tab-home@tabs': { 'tab-home@tabs': {
@ -912,30 +912,25 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
$ionicPlatform.registerBackButtonAction(function(e) { $ionicPlatform.registerBackButtonAction(function(e) {
//from root tabs view //from root tabs view
var fromWelcome = $ionicHistory.currentStateName().match(/welcome/) ? true : false; var matchHome = $ionicHistory.currentStateName() == 'tabs.home' ? true : false;
var matchHome = $ionicHistory.currentStateName().match(/home/) ? true : false; var matchReceive = $ionicHistory.currentStateName() == 'tabs.receive' ? true : false;
var matchReceive = $ionicHistory.currentStateName().match(/receive/) ? true : false; var matchScan = $ionicHistory.currentStateName() == 'tabs.scan' ? true : false;
var matchSend = $ionicHistory.currentStateName().match(/send/) ? true : false; var matchSend = $ionicHistory.currentStateName() == 'tabs.send' ? true : false;
var matchSettings = $ionicHistory.currentStateName().match(/settings/) ? true : false; var matchSettings = $ionicHistory.currentStateName() == 'tabs.settings' ? true : false;
var fromTabs = matchHome | matchReceive | matchSend | matchSettings; var fromTabs = matchHome | matchReceive | matchScan | matchSend | matchSettings;
//onboarding with no back views //onboarding with no back views
var matchCollectEmail = $ionicHistory.currentStateName().match(/collectEmail/) ? true : false; var matchWelcome = $ionicHistory.currentStateName() == 'onboarding.welcome' ? true : false;
var matchBackupRequest = $ionicHistory.currentStateName().match(/backupRequest/) ? true : false; var matchCollectEmail = $ionicHistory.currentStateName() == 'onboarding.collectEmail' ? true : false;
var matchDisclaimer = $ionicHistory.currentStateName().match(/disclaimer/) ? true : false; var matchBackupRequest = $ionicHistory.currentStateName() == 'onboarding.backupRequest' ? true : false;
var matchNotifications = $ionicHistory.currentStateName().match(/notifications/) ? true : false; var matchNotifications = $ionicHistory.currentStateName() == 'onboarding.notifications' ? true : false;
var fromOnboarding = matchCollectEmail | matchBackupRequest | matchDisclaimer | matchNotifications; var fromOnboarding = matchCollectEmail | matchBackupRequest | matchNotifications | matchWelcome;
if (fromOnboarding) { if ($ionicHistory.backView() && !fromTabs && !fromOnboarding) {
e.preventDefault();
return;
}
if ($ionicHistory.backView() && !fromTabs) {
$ionicHistory.goBack(); $ionicHistory.goBack();
} else } else
if ($rootScope.backButtonPressedOnceToExit || fromWelcome) { if ($rootScope.backButtonPressedOnceToExit) {
ionic.Platform.exitApp(); ionic.Platform.exitApp();
} else { } else {
$rootScope.backButtonPressedOnceToExit = true; $rootScope.backButtonPressedOnceToExit = true;
@ -973,21 +968,21 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
$log.debug('No profile... redirecting'); $log.debug('No profile... redirecting');
$state.go('onboarding.welcome'); $state.go('onboarding.welcome');
} else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) { } else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
$log.debug('Display disclaimer... redirecting'); if (lodash.isEmpty(profileService.getWallets())) {
storageService.getLastState(function(err, state) { $log.debug('No wallets and no disclaimer... redirecting');
if (err && !state) { $state.go('onboarding.welcome');
$log.error(err); }
$state.go('onboarding.disclaimer'); else {
} $log.debug('Display disclaimer... redirecting');
else { $state.go('onboarding.disclaimer', {
var state = JSON.parse(state); resume: true
$state.go(state.name, state.toParams); });
} }
})
} else { } else {
throw new Error(err); // TODO throw new Error(err); // TODO
} }
} else { }
else {
profileService.storeProfileIfDirty(); profileService.storeProfileIfDirty();
$log.debug('Profile loaded ... Starting UX.'); $log.debug('Profile loaded ... Starting UX.');
scannerService.gentleInitialize(); scannerService.gentleInitialize();
@ -1014,11 +1009,5 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
$log.debug('Route change from:', fromState.name || '-', ' to:', toState.name); $log.debug('Route change from:', fromState.name || '-', ' to:', toState.name);
$log.debug(' toParams:' + JSON.stringify(toParams || {})); $log.debug(' toParams:' + JSON.stringify(toParams || {}));
$log.debug(' fromParams:' + JSON.stringify(fromParams || {})); $log.debug(' fromParams:' + JSON.stringify(fromParams || {}));
if (!toState.name.match(/onboarding/)) return;
var state = {};
state.name = toState.name;
state.toParams = toParams;
if (state.name != 'starting') storageService.setLastState(JSON.stringify(state), function() {});
}); });
}); });

View file

@ -6,12 +6,13 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
/*************** Ionic ****************/ /*************** Ionic ****************/
var _ionicAlert = function(title, message, cb) { var _ionicAlert = function(title, message, cb, buttonName) {
if (!cb) cb = function() {}; if (!cb) cb = function() {};
$ionicPopup.alert({ $ionicPopup.alert({
title: title, title: title,
subTitle: message, subTitle: message,
okType: 'button-clear button-positive' okType: 'button-clear button-positive',
okText: buttonName || gettextCatalog.getString('OK'),
}).then(cb); }).then(cb);
}; };
@ -43,9 +44,9 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
/*************** Cordova ****************/ /*************** Cordova ****************/
var _cordovaAlert = function(title, message, cb) { var _cordovaAlert = function(title, message, cb, buttonName) {
if (!cb) cb = function() {}; if (!cb) cb = function() {};
navigator.notification.alert(message, cb, title); navigator.notification.alert(message, cb, title, buttonName);
}; };
var _cordovaConfirm = function(title, message, okText, cancelText, cb) { var _cordovaConfirm = function(title, message, okText, cancelText, cb) {
@ -74,14 +75,14 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
* @param {Callback} Function (optional) * @param {Callback} Function (optional)
*/ */
this.showAlert = function(title, msg, cb) { this.showAlert = function(title, msg, cb, buttonName) {
var message = (msg && msg.message) ? msg.message : msg; var message = (msg && msg.message) ? msg.message : msg;
$log.warn(title + ": " + message); $log.warn(title + ": " + message);
if (isCordova) if (isCordova)
_cordovaAlert(title, message, cb); _cordovaAlert(title, message, cb, buttonName);
else else
_ionicAlert(title, message, cb); _ionicAlert(title, message, cb, buttonName);
}; };
/** /**

View file

@ -199,9 +199,9 @@ angular.module('copayApp.services')
storage.get('homeTip', cb); storage.get('homeTip', cb);
}; };
root.setHomeTipAccepted = function(val, cb) { root.setHomeTipAccepted = function(val, cb) {
storage.set('homeTip', val, cb); storage.set('homeTip', val, cb);
}; };
root.setHideBalanceFlag = function(walletId, val, cb) { root.setHideBalanceFlag = function(walletId, val, cb) {
storage.set('hideBalance-' + walletId, val, cb); storage.set('hideBalance-' + walletId, val, cb);
@ -284,14 +284,6 @@ angular.module('copayApp.services')
storage.remove('nextStep-' + service, cb); storage.remove('nextStep-' + service, cb);
}; };
root.setLastState = function(state, toParams, cb) {
storage.set('lastState', state, toParams, cb);
};
root.getLastState = function(cb) {
storage.get('lastState', cb);
};
root.checkQuota = function() { root.checkQuota = function() {
var block = ''; var block = '';
// 50MB // 50MB

View file

@ -38,6 +38,9 @@ $button-secondary-active-border: transparent;
&.button-secondary { &.button-secondary {
&.button-standard { &.button-standard {
@extend %button-standard; @extend %button-standard;
& + .button-standard {
margin-top: 1rem;
}
} }
} }
} }

View file

@ -14,6 +14,19 @@
padding-left: 74px; padding-left: 74px;
} }
.icon-svg {
display: flex;
justify-content: center;
align-items: center;
> img {
background-repeat:no-repeat;
background-clip: padding-box;
background-size: contain;
height: 18px;
}
}
.big-icon-svg { .big-icon-svg {
padding: 0 7px; padding: 0 7px;
> .bg { > .bg {

View file

@ -27,3 +27,14 @@ ion-tabs.ion-tabs-transparent {
} }
} }
} }
// .placeholder-icon padding cannot be modified by a variable
$placeholder-icon-padding: 10px;
.placeholder-icon {
&:first-child {
padding-right: $placeholder-icon-padding;
}
&:last-child {
padding-left: $placeholder-icon-padding;
}
}

View file

@ -1,3 +0,0 @@
#backup-confirm-modal{
}

View file

@ -0,0 +1,12 @@
#backup-needed-modal{
.button.button-secondary {
font-size: 14px;
margin-top: 0;
}
.button {
display: block;
margin-right: auto;
margin-left: auto;
margin-top: 1rem;
}
}

View file

@ -73,5 +73,5 @@
background: rgba(0, 0, 0, .8); background: rgba(0, 0, 0, .8);
} }
@import "backup-confirm-modal"; @import "backup-needed-modal";
@import "screenshot-warning-model"; @import "screenshot-warning-model";

View file

@ -32,9 +32,6 @@
font-size: .8rem; font-size: .8rem;
i { i {
font-size: 1.3rem; font-size: 1.3rem;
&.ion-social-bitcoin-outline {
border-right: 1px solid rgb(228, 228, 228);
}
} }
} }
.bit-address { .bit-address {
@ -111,6 +108,10 @@
margin-bottom:1rem; margin-bottom:1rem;
} }
} }
.receive-tab-bitcoin-icon {
border-right: 1px solid rgb(228, 228, 228);
padding-right: 10px;
}
} }
@keyframes fadeIn { @keyframes fadeIn {

View file

@ -7,51 +7,13 @@ $scannerBackgroundColor: #060d2d;
.bar-header { .bar-header {
opacity: .9; opacity: .9;
} }
.zero-state-cta {
padding-bottom: 6vh;
}
&-has-problems, &-has-problems,
&-loading-camera { &-loading-camera {
background-color: $scannerBackgroundColor; background-color: $scannerBackgroundColor;
} }
&-has-problems {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.zero-state {
&-icon {
display: inline-block;
width: 50px;
height: 50px;
border-radius: 50%;
padding: 13px;
box-shadow: $subtle-box-shadow;
background-color: #fff;
}
&-heading {
font-size: 20px;
margin: 1rem;
}
&-description {
margin: 0 2rem 120px;
opacity: .6;
max-width: 300px;
}
&-tldr {
margin: 1rem auto;
}
&-description,
&-tldr {
max-width: 300px;
}
&-cta {
position: absolute;
bottom: 0;
width: 100%;
padding-bottom: 6vh;
}
}
}
&-loading-camera { &-loading-camera {
height: 100%; height: 100%;
width: 100% width: 100%

View file

@ -1,5 +1,15 @@
#tab-send { #tab-send {
.zero-state-cta {
padding-bottom: 3vh;
}
.send-heading {
font-size: 14px;
font-weight: bold;
padding-bottom: 0;
}
.bitcoin-address { .bitcoin-address {
border-top: none;
padding-bottom: .5rem;
@media(max-width: 480px) { @media(max-width: 480px) {
input { input {
font-size: 12px; font-size: 12px;

View file

@ -15,6 +15,7 @@
@import "address-book"; @import "address-book";
@import "wallet-backup-phrase"; @import "wallet-backup-phrase";
@import "address-book"; @import "address-book";
@import "zero-state";
@import "onboarding/onboarding"; @import "onboarding/onboarding";
@import "includes/walletActivity"; @import "includes/walletActivity";
@import "includes/wallets"; @import "includes/wallets";

View file

@ -0,0 +1,45 @@
.zero-state {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
&-icon {
display: inline-block;
width: 50px;
height: 50px;
border-radius: 50%;
padding: 13px;
box-shadow: $subtle-box-shadow;
background-color: #fff;
img {
height: 100%;
width: 100%;
}
}
&-heading {
font-size: 20px;
margin: 1rem;
}
&-description {
margin-top: 0;
margin-left: 2rem;
margin-right: 2rem;
margin-bottom: 120px;
opacity: .6;
max-width: 300px;
}
&-tldr {
margin: 1rem auto;
}
&-description,
&-tldr {
max-width: 300px;
}
&-cta {
position: absolute;
bottom: 0;
width: 100%;
}
}

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Bitcoin_Symbol" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 12 16" style="enable-background:new 0 0 12 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#5D5D5D;}
</style>
<path class="st0" d="M7.4,2.5l0-2.4L6,0.2l0,2.3c-0.4,0-0.8,0-1.2,0l0-2.3l-1.5,0l0,2.4c-0.3,0-0.6,0-0.9,0l-2,0l0,1.5
c0,0,1.1,0,1,0c0.6,0,0.8,0.3,0.8,0.6l0,6.5c0,0.2-0.2,0.5-0.6,0.5c0,0-1.1,0-1.1,0l-0.3,1.7l1.9,0c0.4,0,0.7,0,1,0l0,2.4l1.5,0
l0-2.4c0.4,0,0.8,0,1.2,0l0,2.3l1.5,0l0-2.4c2.5-0.1,4.2-0.7,4.4-3c0.2-1.8-0.7-2.6-2.1-3C10.5,7,11,6.2,10.9,5
C10.7,3.3,9.3,2.7,7.4,2.5z M8.8,10.1c0,1.8-3.1,1.6-4.1,1.6l0-3.2C5.7,8.5,8.8,8.2,8.8,10.1L8.8,10.1z M8.2,5.6
c0,1.6-2.6,1.4-3.4,1.4l0-2.9C5.6,4.2,8.2,3.9,8.2,5.6L8.2,5.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 939 B

View file

@ -3,25 +3,11 @@
<div class="popup-modal-header-img-warning popup-modal-header-img"></div> <div class="popup-modal-header-img-warning popup-modal-header-img"></div>
</div> </div>
<div class="popup-modal-content popup-modal-content-warning"> <div class="popup-modal-content popup-modal-content-warning">
<div class="text-center"> <div>
<h5 translate>Backup Needed</h5> <div class="popup-modal-heading" translate>Backup Needed</div>
<p translate>Now is a good time to backup your wallet. If this device is lost, it is impossible to access your funds without a backup.</p> <div class="popup-modal-message" translate>Now is a good time to backup your wallet. If this device is lost, it is impossible to access your funds without a backup.</div>
<div class="row"> <button class="button button-clear" ng-click="doBackup()" translate>Backup now</button>
<div class="col"> <button class="button button-secondary button-clear" ng-click="close()" translate>Remind me later</button>
<button
class="button button-clear expand"
ng-click="close()"
translate>Not now
</button>
</div>
<div class="col">
<button
class="button button-clear expand"
ng-click="doBackup()"
translate>Backup wallet now
</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -56,7 +56,7 @@
<div class="list"> <div class="list">
<div class="item item-icon-left" ng-show="btx.action == 'sent'"> <div class="item item-icon-left" ng-show="btx.action == 'sent'">
<i class="icon ion-social-bitcoin-outline"></i> <i class="icon icon-svg"><img src="img/icon-bitcoin-symbol.svg"></i>
<div ng-if="!btx.hasMultiplesOutputs && btx.addressTo && btx.addressTo != 'N/A'" copy-to-clipboard="btx.addressTo"> <div ng-if="!btx.hasMultiplesOutputs && btx.addressTo && btx.addressTo != 'N/A'" copy-to-clipboard="btx.addressTo">
<span ng-if="btx.merchant"> <span ng-if="btx.merchant">
<span ng-show="btx.merchant.pr.ca"><i class="fi-lock color-greeni"></i> {{btx.merchant.domain}}</span> <span ng-show="btx.merchant.pr.ca"><i class="fi-lock color-greeni"></i> {{btx.merchant.domain}}</span>
@ -90,7 +90,7 @@
</div> </div>
</div> </div>
<div class="item" ng-if="btx.action != 'received' && btx.feeLevel" copy-to-clipboard="btx.feeStr"> <div class="item" ng-if="btx.action != 'received' && btx.feeStr" copy-to-clipboard="btx.feeStr">
{{'Fee'|translate}}: {{btx.feeStr}} {{'Fee'|translate}}: {{btx.feeStr}}
<span class="item-note"> <span class="item-note">
<span class="text-warning" ng-show="!btx.confirmations || btx.confirmations == 0" translate> <span class="text-warning" ng-show="!btx.confirmations || btx.confirmations == 0" translate>
@ -102,7 +102,7 @@
<span class="label gray radius" ng-show="btx.safeConfirmed"> <span class="label gray radius" ng-show="btx.safeConfirmed">
{{btx.safeConfirmed}} {{btx.safeConfirmed}}
</span> </span>
<span translate>Confirmations</span> <span ng-show="btx.confirmations && btx.confirmations > 0" translate>Confirmations</span>
</span> </span>
</div> </div>

View file

@ -8,7 +8,7 @@
<div class="cta-buttons"> <div class="cta-buttons">
<i class="ion-ios-arrow-thin-down" id="arrow-down"></i> <i class="ion-ios-arrow-thin-down" id="arrow-down"></i>
<div class="onboarding-tldr" id="backup-tldr" translate>Your wallet is never saved to cloud storage or standard device backups.</div> <div class="onboarding-tldr" id="backup-tldr" translate>Your wallet is never saved to cloud storage or standard device backups.</div>
<button class="button button-standard button-primary" ui-sref="onboarding.backupWarning({from: 'onboarding.backupRequest', walletId: walletId})" translate>Backup wallet</button> <button class="button button-standard button-primary" ui-sref="onboarding.backupWarning({from: 'onboarding', walletId: walletId})" translate>Backup wallet</button>
<button class="button button-standard button-secondary button-clear" ng-click="openPopup()" translate>I'll backup my wallet later</button> <button class="button button-standard button-secondary button-clear" ng-click="openPopup()" translate>I'll backup my wallet later</button>
</div> </div>
</ion-content> </ion-content>

View file

@ -9,8 +9,9 @@
</ion-nav-bar> </ion-nav-bar>
<ion-content scroll="false" ng-class="{'has-header': backedUp == 'false'}"> <ion-content scroll="false" ng-class="{'has-header': backedUp == 'false'}">
<div id="onboarding-disclaimer-container"> <div id="onboarding-disclaimer-container">
<div class="onboarding-topic" id="disclaimer-topic">Almost done! Let's review.</div> <div ng-show="resume" class="onboarding-topic" id="disclaimer-topic" translate>Quick review!</div>
<div class="onboarding-description" id="disclaimer-description">Bitcoin is different &ndash; it cannot be safely held with a bank or web service.</div> <div ng-show="!resume" class="onboarding-topic" id="disclaimer-topic" translate>Almost done! Let's review.</div>
<div class="onboarding-description" id="disclaimer-description" translate>Bitcoin is different &ndash; it cannot be safely held with a bank or web service.</div>
<ion-list> <ion-list>
<ion-checkbox ng-model="accept1"> <ion-checkbox ng-model="accept1">
<span translate>I understand that my funds are held securely on this device, not by a company.</span> <span translate>I understand that my funds are held securely on this device, not by a company.</span>

View file

@ -5,11 +5,11 @@
</ion-nav-back-button> </ion-nav-back-button>
</ion-nav-bar> </ion-nav-bar>
<ion-content> <ion-content>
<button class="button button-block button-positive" copy-to-clipboard="prepare()"> <button class="button button-standard button-primary" style="margin-top: 1rem" copy-to-clipboard="prepare()">
<i class="icon ion-clipboard"></i> <i class="icon ion-clipboard"></i>
<span translate>Copy to clipboard</span> <span translate>Copy to clipboard</span>
</button> </button>
<button class="button button-block button-positive" ng-show="isCordova" ng-click="sendLogs()"> <button class="button button-standard button-secondary" ng-show="isCordova" ng-click="sendLogs()">
<i class="icon ion-ios-email-outline"></i> <i class="icon ion-ios-email-outline"></i>
<span translate>Send by email</span> <span translate>Send by email</span>
</button> </button>

View file

@ -4,6 +4,12 @@
</ion-nav-bar> </ion-nav-bar>
<ion-content class="padding"> <ion-content class="padding">
<ion-refresher
ng-if="isCordova"
pulling-icon="ion-ios-refresh"
spinner="ios-small"
on-refresh="onRefresh()">
</ion-refresher>
<div class="list card homeTip" ng-if="homeTip"> <div class="list card homeTip" ng-if="homeTip">
<div class="item item-icon-right item-heading"> <div class="item item-icon-right item-heading">
<a ng-click="hideHomeTip()"><i class="icon ion-ios-close-empty close-home-tip"></i></a> <a ng-click="hideHomeTip()"><i class="icon ion-ios-close-empty close-home-tip"></i></a>

View file

@ -1,11 +1,6 @@
<ion-view id="tab-receive"> <ion-view id="tab-receive">
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Receive' | translate}}</ion-nav-title> <ion-nav-title>{{'Receive' | translate}}</ion-nav-title>
<ion-nav-buttons side="secondary">
<button class="button button-clear" ng-click="checkTips(true)">
<i class="ion-help-circled"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content> <ion-content>
<div class="list card padding text-center" ng-if="!wallets[0]"> <div class="list card padding text-center" ng-if="!wallets[0]">
@ -23,7 +18,7 @@
<div class="row border-top"> <div class="row border-top">
<div class="col col-90 center-block bit-address text-center"> <div class="col col-90 center-block bit-address text-center">
<div class="item item-icon-left"> <div class="item item-icon-left">
<i class="icon ion-social-bitcoin-outline"></i> <i class="icon icon-svg receive-tab-bitcoin-icon"><img src="img/icon-bitcoin-symbol.svg"></i>
<span class="bit-address-gen-address">...</span> <span class="bit-address-gen-address">...</span>
</div> </div>
</div> </div>
@ -44,7 +39,7 @@
<div class="row border-top"> <div class="row border-top">
<div class="col col-90 center-block bit-address text-center"> <div class="col col-90 center-block bit-address text-center">
<div class="item item-icon-left"> <div class="item item-icon-left">
<i class="icon ion-social-bitcoin-outline"></i> <i class="icon icon-svg receive-tab-bitcoin-icon"><img src="img/icon-bitcoin-symbol.svg"></i>
<span class="bit-address-gen-address" ng-if="!generatingAddress" translate>address not yet available</span> <span class="bit-address-gen-address" ng-if="!generatingAddress" translate>address not yet available</span>
</div> </div>
</div> </div>
@ -81,7 +76,7 @@
<div class="row border-top"> <div class="row border-top">
<div class="col col-90 center-block bit-address text-center"> <div class="col col-90 center-block bit-address text-center">
<div class="item item-icon-left"> <div class="item item-icon-left">
<i class="icon ion-social-bitcoin-outline"></i> <i class="icon icon-svg receive-tab-bitcoin-icon"><img src="img/icon-bitcoin-symbol.svg"></i>
<span class="bit-address-gen-address" ng-if="generatingAddress">...</span> <span class="bit-address-gen-address" ng-if="generatingAddress">...</span>
<span class="bit-address-gen-address" ng-if="!generatingAddress" copy-to-clipboard="addr">{{addr}}</span> <span class="bit-address-gen-address" ng-if="!generatingAddress" copy-to-clipboard="addr">{{addr}}</span>
</div> </div>

View file

@ -8,7 +8,7 @@
</ion-nav-buttons> </ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content scroll="false"> <ion-content scroll="false">
<div class="ng-hide" id="tab-scan-has-problems" ng-show="currentState === scannerStates.unauthorized || currentState === scannerStates.denied || currentState === scannerStates.unavailable"> <div class="ng-hide zero-state" id="tab-scan-has-problems" ng-show="currentState === scannerStates.unauthorized || currentState === scannerStates.denied || currentState === scannerStates.unavailable">
<i class="icon zero-state-icon"> <i class="icon zero-state-icon">
<img src="img/tab-icons/ico-receive.svg"/> <img src="img/tab-icons/ico-receive.svg"/>
</i> </i>

View file

@ -2,25 +2,38 @@
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-title>{{'Send' | translate}}</ion-nav-title> <ion-nav-title>{{'Send' | translate}}</ion-nav-title>
</ion-nav-bar> </ion-nav-bar>
<ion-content scroll="false">
<ion-content> <div class="ng-hide zero-state" ng-show="!hasFunds">
<div class="item item-heading" translate>Recipient</div> <i class="icon zero-state-icon">
<img src="img/tab-icons/ico-send-selected.svg"/>
</i>
<div class="zero-state-heading" translate>Start sending bitcoin</div>
<div class="zero-state-description" ng-show="hasWallets" translate>To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service.</div>
<div class="zero-state-description" ng-show="!hasWallets" translate>To get started, you'll need to create a bitcoin wallet and get some bitcoin.</div>
<div class="zero-state-cta">
<button class="button button-standard button-primary" ng-click="buyBitcoin()" ng-show="hasWallets">Buy Bitcoin</button>
<button class="button button-standard button-primary" ng-click="createWallet()" ng-show="!hasWallets">Create bitcoin wallet</button>
<button class="button button-standard button-secondary" ui-sref="tabs.receive" ng-show="hasWallets">Show bitcoin address</button>
</div>
</div>
</ion-content>
<ion-content class="ng-hide has-funds" ng-show="hasFunds">
<div class="item item-heading send-heading" translate>Recipient</div>
<label class="item item-input bitcoin-address"> <label class="item item-input bitcoin-address">
<i class="icon ion-social-bitcoin placeholder-icon"></i> <i class="icon icon-svg placeholder-icon"><img src="img/icon-bitcoin-symbol.svg"></i>
<div class="qr-scan-icon" ng-style="{'width': '100%'}"> <div class="qr-scan-icon" ng-style="{'width': '100%'}">
<a ui-sref="tabs.scan" ng-style="{'top': '6px'}"><i class="icon ion-qr-scanner"></i></a> <a ui-sref="tabs.scan" ng-style="{'top': '6px'}">
<input type="text" <i class="icon ion-qr-scanner"></i>
placeholder="{{'Search or enter bitcoin address' | translate}}" </a>
ng-model="formData.search" <input type="text" placeholder="{{'Search or enter bitcoin address' | translate}}" ng-model="formData.search" ng-change="findContact(formData.search)" ng-model-onblur>
ng-change="findContact(formData.search)"
ng-model-onblur>
</div> </div>
</label> </label>
<div class="card"> <div class="card">
<div class="item item-icon-right item-heading"> <div class="item item-icon-right item-heading">
<span translate>Contacts</span> <span translate>Contacts</span>
<a ng-if="hasContacts" ui-sref="tabs.send.addressbook"><i class="icon ion-ios-plus-empty list-add-button"></i></a> <a ng-if="hasContacts" ui-sref="tabs.send.addressbook">
<i class="icon ion-ios-plus-empty list-add-button"></i>
</a>
</div> </div>
<div class="list"> <div class="list">
<a class="item item-icon-left item-icon-right" ng-if="!hasContacts" ui-sref="tabs.send.addressbook"> <a class="item item-icon-left item-icon-right" ng-if="!hasContacts" ui-sref="tabs.send.addressbook">

View file

@ -10,7 +10,13 @@
</ion-nav-buttons> </ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<ion-content delegate-handle="my-handle"> <ion-content has-bouncing="false">
<ion-refresher
ng-if="isCordova"
pulling-icon="ion-ios-refresh"
spinner="ios-small"
on-refresh="onRefresh()">
</ion-refresher>
<div class="oh pr" ng-show="wallet && wallet.isComplete()"> <div class="oh pr" ng-show="wallet && wallet.isComplete()">
<div ng-style="{'background-color':wallet.color}" class="amount"> <div ng-style="{'background-color':wallet.color}" class="amount">
<div ng-if="!notAuthorized && !updatingStatus"> <div ng-if="!notAuthorized && !updatingStatus">