Merge branch 'ref/design' of https://github.com/bitpay/bitpay-wallet into feature/home_views_polish

This commit is contained in:
Jamal Jackson 2016-09-30 11:22:03 -04:00
commit 9980e2e11f
44 changed files with 314 additions and 228 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -20,7 +20,7 @@
<ion-spinner class="spinner-dark" icon="lines"></ion-spinner> <ion-spinner class="spinner-dark" icon="lines"></ion-spinner>
</div> </div>
</div> </div>
<div class="secret" ng-show="!isCordova"> <div class="secret">
{{secret || ('Loading...'|translate)}} {{secret || ('Loading...'|translate)}}
</div> </div>
</div> </div>
@ -29,11 +29,11 @@
<div ng-show="secret"> <div ng-show="secret">
<div class="text-center m10t" ng-if="isCordova"> <div class="text-center m10t" ng-if="isCordova">
<span class="button outline round dark-gray tiny m0" <button class="button button-outline button-positive"
ng-click="shareSecret()"> ng-click="shareSecret()">
<i class="fi-share"></i> <i class="icon ion-ios-upload-outline"></i>
<span translate>Share invitation</span> <span translate>Share invitation</span>
</span> </button>
</div> </div>
<div class="m30v line-t"> <div class="m30v line-t">

View File

@ -1,5 +1,5 @@
<ion-modal-view id="txp-details" ng-controller="txpDetailsController" ng-init="init()"> <ion-modal-view id="txp-details" ng-controller="txpDetailsController" ng-init="init()">
<ion-header-bar align-title="center" class="bar-royal"> <ion-header-bar align-title="center" class="bar-royal" ng-style="{'background-color': wallet.color}">
<button class="button button-clear" ng-click="close()"> <button class="button button-clear" ng-click="close()">
Close Close
</button> </button>

View File

@ -1,9 +1,17 @@
<ion-view id="onboarding-disclaimer" class="onboarding"> <ion-view id="onboarding-disclaimer" class="onboarding" ng-controller="disclaimerController" ng-init=init()>
<ion-content ng-controller="disclaimerController" ng-init=init() scroll="false"> <ion-nav-bar class="bar-stable" ng-if="backedUp == 'false'">
<ion-nav-title></ion-nav-title>
<ion-nav-buttons side="primary">
<button class="button back-button button-clear" ng-click="goBack()">
<i class="icon ion-ios-arrow-thin-left"></i>
</button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-content scroll="false" ng-class="{'has-header': backedUp == 'false'}">
<div class="row text-center"> <div class="row text-center">
<h3 translate class="col-75 col">Almost done! Let's review</h3> <h3 translate class="col-75 col">Almost done! Let's review</h3>
</div> </div>
<div class="row text-center"> <div class="row text-center tag">
<p translate class="col col-75"> <p translate class="col col-75">
Bitcoin is different - it cannot be safely held with a bank or web service Bitcoin is different - it cannot be safely held with a bank or web service
</p> </p>
@ -12,7 +20,7 @@
<ion-checkbox ng-model="accept1"><span translate>I understand my funds are held securely on this device, not by a company.</span></ion-checkbox> <ion-checkbox ng-model="accept1"><span translate>I understand my funds are held securely on this device, not by a company.</span></ion-checkbox>
<ion-checkbox ng-model="accept2"><span translate>I understand if this app moved to another device or deleted, my bitcoin can only be recovered with the backup phrase</span></ion-checkbox> <ion-checkbox ng-model="accept2"><span translate>I understand if this app moved to another device or deleted, my bitcoin can only be recovered with the backup phrase</span></ion-checkbox>
</ion-list> </ion-list>
<div id="agree-to-terms" ng-if="accept1 && accept2"> <div id="agree-to-terms" ng-if="accept1 && accept2" ng-class="{'header-present': backedUp == 'false'}">
<div id="agree-to-terms-content" class="center-block"> <div id="agree-to-terms-content" class="center-block">
<ion-checkbox ng-model="terms.accept3"></ion-checkbox> <ion-checkbox ng-model="terms.accept3"></ion-checkbox>
<p translate>I have read, understood, and agree with the <a ng-click="openTermsModal()" translate>Terms of use</a>.</p> <p translate>I have read, understood, and agree with the <a ng-click="openTermsModal()" translate>Terms of use</a>.</p>

View File

@ -69,10 +69,11 @@
<span ng-if="!wallet.isComplete()" class="assertive" translate> <span ng-if="!wallet.isComplete()" class="assertive" translate>
Incomplete Incomplete
</span> </span>
<div ng-if="wallet.isComplete()"> <span ng-if="wallet.isComplete()">
<span ng-if="!wallet.balanceHidden">{{wallet.status.availableBalanceStr}}</span> <span ng-if="!wallet.balanceHidden">{{wallet.status.availableBalanceStr}}</span>
<span ng-if="wallet.balanceHidden" translate>[Balance Hidden]</span> <span ng-if="wallet.balanceHidden" translate>[Balance Hidden]</span>
</div> </span>
&nbsp;
</p> </p>
<i class="icon nav-item-arrow-right"></i> <i class="icon nav-item-arrow-right"></i>
</a> </a>
@ -115,35 +116,36 @@
</div> </div>
<div class="list card" <div class="list card"
ng-if="(!externalServices.AmazonGiftCards || !externalServices.BitpayCard || !externalServices.BuyAndSell || !wallets[0]) && nextStepEnabled"> ng-show="(!externalServices.AmazonGiftCards || !externalServices.BitpayCard || !externalServices.BuyAndSell ||
!wallets[0]) && nextStepEnabled">
<div class="item item-icon-right item-heading" ng-click="shouldHideNextSteps()" translate> <div class="item item-icon-right item-heading" ng-click="shouldHideNextSteps()" translate>
Next steps Next steps
<i class="icon nav-item-arrow-down" ng-if="!hideNextSteps"></i> <i class="icon nav-item-arrow-down" ng-show="!hideNextSteps"></i>
<i class="icon nav-item-arrow-up" ng-if="hideNextSteps"></i> <i class="icon nav-item-arrow-up" ng-show="hideNextSteps"></i>
</div> </div>
<div ng-if="!hideNextSteps"> <div ng-show="!hideNextSteps">
<a ng-if="!wallets[0]" ui-sref="tabs.add" class="item item-icon-left item-big-icon-left item-icon-right next-step"> <a ng-show="!wallets[0]" ui-sref="tabs.add" class="item item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg"> <i class="icon big-icon-svg">
<div class="bg icon-create-wallet"></div> <div class="bg icon-create-wallet"></div>
</i> </i>
<span translate>Create a bitcoin wallet</span> <span translate>Create a bitcoin wallet</span>
<i class="icon nav-item-arrow-right"></i> <i class="icon nav-item-arrow-right"></i>
</a> </a>
<a ui-sref="bitpayCard.main" ng-if="!externalServices.BitpayCard && bitpayCardEnabled" class="item item-icon-left item-big-icon-left item-icon-right next-step"> <a ui-sref="bitpayCard.main" ng-show="!externalServices.BitpayCard && bitpayCardEnabled" class="item item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg"> <i class="icon big-icon-svg">
<div class="bg icon-bitpay-card"></div> <div class="bg icon-bitpay-card"></div>
</i> </i>
<span translate>Add BitPay Card</span> <span translate>Add BitPay Card</span>
<i class="icon nav-item-arrow-right"></i> <i class="icon nav-item-arrow-right"></i>
</a> </a>
<a ng-if="!externalServices.BuyAndSell && (coinbaseEnabled || glideraEnabled)" ui-sref="tabs.buyandsell" class="item item-icon-left item-big-icon-left item-icon-right next-step"> <a ng-show="!externalServices.BuyAndSell && (coinbaseEnabled || glideraEnabled)" ui-sref="tabs.buyandsell" class="item item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg"> <i class="icon big-icon-svg">
<div class="bg icon-buy-bitcoin"></div> <div class="bg icon-buy-bitcoin"></div>
</i> </i>
<span translate>Buy or Sell Bitcoin</span> <span translate>Buy or Sell Bitcoin</span>
<i class="icon nav-item-arrow-right"></i> <i class="icon nav-item-arrow-right"></i>
</a> </a>
<a ui-sref="tabs.giftcards.amazon" ng-if="!externalServices.AmazonGiftCards && amazonEnabled" class="item item-icon-left item-big-icon-left item-icon-right next-step"> <a ui-sref="tabs.giftcards.amazon" ng-show="!externalServices.AmazonGiftCards && amazonEnabled" class="item item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg"> <i class="icon big-icon-svg">
<div class="bg icon-gift"></div> <div class="bg icon-gift"></div>
</i> </i>

View File

@ -9,7 +9,7 @@
</ion-nav-bar> </ion-nav-bar>
<ion-content> <ion-content>
<div id="address"> <div id="address">
<article class="text-center" ng-if="!wallet.isComplete()"> <article class="text-center" ng-if="wallet && !wallet.isComplete()">
<div class="incomplete"> <div class="incomplete">
<div class="title"> <div class="title">
<span translate>Incomplete wallet</span> <span translate>Incomplete wallet</span>
@ -30,7 +30,7 @@
</div> </div>
</div> </div>
</article> </article>
<article ng-if="wallet.isComplete()"> <article ng-if="wallet && wallet.isComplete()">
<div class="row backup" ng-show="!wallet.showBackupNeededModal && wallet.needsBackup" ng-click="goToBackupFlow()"> <div class="row backup" ng-show="!wallet.showBackupNeededModal && wallet.needsBackup" ng-click="goToBackupFlow()">
<div class="m15t text-center col center-block"> <div class="m15t text-center col center-block">
<i class="icon ion-alert"></i><span translate>Wallet not backed up</span><i class="icon ion-ios-arrow-thin-right"></i> <i class="icon ion-alert"></i><span translate>Wallet not backed up</span><i class="icon ion-ios-arrow-thin-right"></i>

View File

@ -1,6 +1,6 @@
<ion-view id="walletDetails"> <ion-view id="walletDetails">
<ion-nav-bar ng-style="{'background-color': walletDetailsColor}"> <ion-nav-bar ng-style="{'background-color': wallet.color}">
<ion-nav-title>{{walletDetailsName}}</ion-nav-title> <ion-nav-title>{{wallet.name}}</ion-nav-title>
<ion-nav-back-button> <ion-nav-back-button>
</ion-nav-back-button> </ion-nav-back-button>
<ion-nav-buttons side="secondary"> <ion-nav-buttons side="secondary">
@ -14,14 +14,13 @@
<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">
<div class="m20t" ng-show="updateStatusError" ng-click='update()'> <div ng-show="updateStatusError">
<span class="size-12 db m10b">{{updateStatusError|translate}}</span> <a class="button button-outline button-light button-small" ng-click='update()' translate>Tap to retry</a>
<button class="outline white tiny round" translate>Tap to retry</button>
</div> </div>
<div class="m20t" ng-show="walletNotRegistered" ng-click='recreate()'> <div ng-show="walletNotRegistered">
<span class="size-12 db m10b" translate>This wallet is not registered at the given Bitcore Wallet Service (BWS). You can recreate it from the local information.</span> <span class="size-12 db m10b" translate>This wallet is not registered at the given Bitcore Wallet Service (BWS). You can recreate it from the local information.</span>
<button class="outline white tiny round" translate>Recreate</button> <a class="button button-outline button-light button-small" ng-click='recreate()' translate>Recreate</a>
</div> </div>
<div ng-show="wallet.walletScanStatus == 'error'" ng-click='retryScan()'> <div ng-show="wallet.walletScanStatus == 'error'" ng-click='retryScan()'>
@ -30,7 +29,7 @@
</div> </div>
<div ng-click='updateAll()' ng-show="!updateStatusError && wallet.walletScanStatus != 'error' && !wallet.balanceHidden" on-hold="hideToggle()"> <div ng-click='updateAll(true)' ng-show="!updateStatusError && wallet.walletScanStatus != 'error' && !wallet.balanceHidden" on-hold="hideToggle()">
<strong class="size-36">{{status.totalBalanceStr}}</strong> <strong class="size-36">{{status.totalBalanceStr}}</strong>
<div class="size-14 amount-alternative" ng-if="status.totalBalanceAlternative">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</div> <div class="size-14 amount-alternative" ng-if="status.totalBalanceAlternative">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</div>
<div class="size-14" ng-if="status.pendingAmount"> <div class="size-14" ng-if="status.pendingAmount">
@ -108,8 +107,8 @@
<!-- Transactions --> <!-- Transactions -->
<div class="oh pr m20t text-gray size-12 text-center" <div class="oh pr m20t text-gray size-12 text-center"
ng-show="!txHistory[0] && !updatingTxHistory && !txHistoryError && !updateStatusError && !notAuthorized" ng-show="!txHistory[0] && !updatingTxHistory && !txHistoryError && !updateStatusError && !notAuthorized" translate>
translate>No transactions yet {{status.totalBalanceStr}} No transactions yet
</div> </div>
<div ng-show="updatingTxHistory && updatingTxHistoryProgress>5" class="updatingHistory"> <div ng-show="updatingTxHistory && updatingTxHistoryProgress>5" class="updatingHistory">
@ -124,20 +123,6 @@
</div> </div>
</div> </div>
<div ng-if="txHistory[0] && updatingTxHistory && newTx" class="row collapse last-transactions-content animated fadeInDown">
<div class="large-6 medium-6 small-6 columns size-14">
<div class="m10r left">
<img src="img/icon-new.svg" width="40">
</div>
<div class="m10t" style="background:#eee; width: 8em; margin-left: 52px; line-height:0.6em">
<span>&nbsp;</span>
</div>
<div style="margin-top:5px; background:#eee; width: 6em; margin-left: 52px; line-height:0.6em">
<span>&nbsp;</span>
</div>
</div>
</div>
<div class="card list" ng-show="txHistory[0]"> <div class="card list" ng-show="txHistory[0]">
<div class="item" ng-repeat="btx in txHistory track by btx.txid" ng-click="openTxModal(btx)"> <div class="item" ng-repeat="btx in txHistory track by btx.txid" ng-click="openTxModal(btx)">
<span class="item-note text-right"> <span class="item-note text-right">

View File

@ -1,30 +0,0 @@
@font-face {
font-family: 'roboto-regular';
font-style: normal;
font-weight: 400;
src: local('Roboto Regular'),
local('Roboto-Regular'),
url(../roboto-font/Roboto-Regular.ttf) format('truetype'),
url(../roboto-font/Roboto-Regular.woff) format('woff'),
url(../roboto-font/Roboto-Regular.woff2) format('woff2');
}
@font-face {
font-family: 'roboto-bold';
font-style: normal;
font-weight: 700;
src: local('Roboto Bold'),
local('Roboto-Bold'),
url(../roboto-font/Roboto-Bold.ttf) format('truetype'),
url(../roboto-font/Roboto-Bold.woff) format('woff'),
url(../roboto-font/Roboto-Bold.woff2) format('woff2');
}
@font-face {
font-family: 'roboto-italic';
font-style: italic;
font-weight: 400;
src: local('Roboto Italic'),
local('Roboto-Italic'),
url(../roboto-font/Roboto-Italic.ttf) format('truetype'),
url(../roboto-font/Roboto-Italic.woff) format('woff'),
url(../roboto-font/Roboto-Italic.woff2) format('woff2');
}

View File

@ -91,7 +91,7 @@ angular.module('copayApp.controllers').controller('backupController',
$ionicHistory.removeBackView(); $ionicHistory.removeBackView();
$state.go('tabs.home'); $state.go('tabs.home');
} }
else $state.go('onboarding.disclaimer'); else $state.go('onboarding.disclaimer', {walletId: $stateParams.walletId, backedUp: true});
}); });
}; };

View File

@ -18,7 +18,7 @@ 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'); $state.go('onboarding.disclaimer', {walletId: $scope.walletId, backedUp: false});
} }
}); });
} }

View File

@ -1,11 +1,11 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('disclaimerController', function($scope, $timeout, $state, $log, $ionicModal, profileService, uxLanguage, externalLinkService) { angular.module('copayApp.controllers').controller('disclaimerController', function($scope, $timeout, $state, $log, $ionicModal, profileService, uxLanguage, externalLinkService, storageService, $stateParams) {
$scope.init = function() { $scope.init = function() {
$scope.lang = uxLanguage.currentLanguage; $scope.lang = uxLanguage.currentLanguage;
$scope.terms = {}; $scope.terms = {};
$scope.accept1 = $scope.accept2 = $scope.accept3 = false; $scope.accept1 = $scope.accept2 = $scope.accept3 = false;
$scope.backedUp = $stateParams.backedUp;
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 1); }, 1);
@ -34,4 +34,10 @@ angular.module('copayApp.controllers').controller('disclaimerController', functi
$scope.termsModal.show(); $scope.termsModal.show();
}); });
}; };
$scope.goBack = function(){
$state.go('onboarding.backupRequest', {walletId: $stateParams.walletId});
}
}); });

View File

@ -3,6 +3,7 @@
angular.module('copayApp.controllers').controller('tabHomeController', angular.module('copayApp.controllers').controller('tabHomeController',
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, gettextCatalog, lodash, popupService, ongoingProcess, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, $window, bitpayCardService) { function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, gettextCatalog, lodash, popupService, ongoingProcess, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, $window, bitpayCardService) {
var wallet; var wallet;
var listeners = [];
$scope.externalServices = {}; $scope.externalServices = {};
$scope.bitpayCardEnabled = true; // TODO $scope.bitpayCardEnabled = true; // TODO
$scope.openTxpModal = txpModalService.open; $scope.openTxpModal = txpModalService.open;
@ -81,7 +82,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}); });
}; };
function updateTxps() { var updateTxps = function() {
profileService.getTxps({ profileService.getTxps({
limit: 3 limit: 3
}, function(err, txps, n) { }, function(err, txps, n) {
@ -90,12 +91,11 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.txpsN = n; $scope.txpsN = n;
$timeout(function() { $timeout(function() {
$ionicScrollDelegate.resize(); $ionicScrollDelegate.resize();
$scope.$apply(); }, 100);
}, 10);
}) })
}; };
$scope.updateAllWallets = function() { var updateAllWallets = function() {
$scope.wallets = profileService.getWallets(); $scope.wallets = profileService.getWallets();
if (lodash.isEmpty($scope.wallets)) return; if (lodash.isEmpty($scope.wallets)) return;
@ -123,7 +123,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
limit: 3 limit: 3
}, function(err, n) { }, function(err, n) {
if (err) { if (err) {
console.log('[tab-home.js.35:err:]', $log.error(err)); //TODO $log.error(err);
return; return;
} }
$scope.fetchingNotifications = false; $scope.fetchingNotifications = false;
@ -132,16 +132,16 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$timeout(function() { $timeout(function() {
$ionicScrollDelegate.resize(); $ionicScrollDelegate.resize();
$scope.$apply(); $scope.$apply();
}, 10); }, 100);
}) })
}; };
$scope.updateWallet = function(wallet) { var updateWallet = function(wallet) {
$log.debug('Updating wallet:' + wallet.name) $log.debug('Updating wallet:' + wallet.name)
walletService.getStatus(wallet, {}, function(err, status) { walletService.getStatus(wallet, {}, function(err, status) {
if (err) { if (err) {
$log.error(err); //TODO $log.error(err);
return; return;
} }
wallet.status = status; wallet.status = status;
@ -155,11 +155,11 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}, function(err, notifications) { }, function(err, notifications) {
$scope.fetchingNotifications = false; $scope.fetchingNotifications = false;
if (err) { if (err) {
console.log('[tab-home.js.35:err:]', $log.error(err)); //TODO $log.error(err);
return; return;
} }
$scope.notifications = notifications; $scope.notifications = notifications;
}) });
}); });
}; };
@ -172,7 +172,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}); });
}; };
$scope.nextStep = function() { var nextStep = function() {
lodash.each(['AmazonGiftCards', 'BitpayCard', 'BuyAndSell'], function(service) { lodash.each(['AmazonGiftCards', 'BitpayCard', 'BuyAndSell'], function(service) {
storageService.getNextStep(service, function(err, value) { storageService.getNextStep(service, function(err, value) {
$scope.externalServices[service] = value ? true : false; $scope.externalServices[service] = value ? true : false;
@ -187,27 +187,10 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.hideNextSteps = !$scope.hideNextSteps; $scope.hideNextSteps = !$scope.hideNextSteps;
$timeout(function() { $timeout(function() {
$ionicScrollDelegate.resize(); $ionicScrollDelegate.resize();
}, 10); $scope.$apply();
}, 100);
}; };
var listeners = [
$rootScope.$on('bwsEvent', function(e, walletId, type, n) {
var wallet = profileService.getWallet(walletId);
$scope.updateWallet(wallet);
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
$log.debug('Got action for wallet ' + walletId);
var wallet = profileService.getWallet(walletId);
$scope.updateWallet(wallet);
}),
];
$scope.$on('$destroy', function() {
lodash.each(listeners, function(x) {
x();
});
});
var bitpayCardCache = function() { var bitpayCardCache = function() {
bitpayCardService.getCacheData(function(err, data) { bitpayCardService.getCacheData(function(err, data) {
if (err ||  lodash.isEmpty(data)) return; if (err ||  lodash.isEmpty(data)) return;
@ -217,10 +200,24 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.$on("$ionicView.enter", function(event, data) { $scope.$on("$ionicView.enter", function(event, data) {
$scope.bitpayCard = null; $scope.bitpayCard = null;
nextStep();
updateAllWallets();
listeners = [
$rootScope.$on('bwsEvent', function(e, walletId, type, n) {
var wallet = profileService.getWallet(walletId);
updateWallet(wallet);
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
$log.debug('Got action for wallet ' + walletId);
var wallet = profileService.getWallet(walletId);
updateWallet(wallet);
})
];
configService.whenAvailable(function() { configService.whenAvailable(function() {
var config = configService.getSync(); var config = configService.getSync();
var isWindowsPhoneApp = platformInfo.isWP && platformInfo.isCordova; var isWindowsPhoneApp = platformInfo.isWP && platformInfo.isCordova;
$scope.hideNextSteps = false;
$scope.glideraEnabled = config.glidera.enabled && !isWindowsPhoneApp; $scope.glideraEnabled = config.glidera.enabled && !isWindowsPhoneApp;
$scope.coinbaseEnabled = config.coinbase.enabled && !isWindowsPhoneApp; $scope.coinbaseEnabled = config.coinbase.enabled && !isWindowsPhoneApp;
$scope.amazonEnabled = config.amazon.enabled; $scope.amazonEnabled = config.amazon.enabled;
@ -230,7 +227,12 @@ angular.module('copayApp.controllers').controller('tabHomeController',
if ($scope.bitpayCardEnabled) bitpayCardCache(); if ($scope.bitpayCardEnabled) bitpayCardCache();
}); });
$scope.nextStep(); });
$scope.updateAllWallets();
$scope.$on("$ionicView.leave", function(event, data) {
lodash.each(listeners, function(x) {
x();
}); });
}); });
});

View File

@ -33,32 +33,14 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.addr = null; $scope.addr = null;
$scope.generatingAddress = true; $scope.generatingAddress = true;
$timeout(function() {
walletService.getAddress($scope.wallet, forceNew, function(err, addr) { walletService.getAddress($scope.wallet, forceNew, function(err, addr) {
$scope.generatingAddress = false; $scope.generatingAddress = false;
if (err) popupService.showAlert(gettextCatalog.getString('Error'), err); if (err) popupService.showAlert(gettextCatalog.getString('Error'), err);
$scope.addr = addr; $scope.addr = addr;
if ($scope.wallet.showBackupNeededModal) $scope.openBackupNeededModal(); if ($scope.wallet.showBackupNeededModal) $scope.openBackupNeededModal();
$scope.$apply();
}); });
}, 100);
}; };
$scope.$on("$ionicView.beforeEnter", function(event, data) {
if (!$scope.isCordova) $scope.checkTips();
$scope.wallets = profileService.getWallets();
$scope.$on('Wallet/Changed', function(event, wallet) {
if (!wallet) {
$log.debug('No wallet provided');
return;
}
$scope.wallet = wallet;
$log.debug('Wallet changed: ' + wallet.name);
$scope.setAddress();
});
});
$scope.goCopayers = function() { $scope.goCopayers = function() {
$ionicHistory.removeBackView(); $ionicHistory.removeBackView();
$ionicHistory.nextViewOptions({ $ionicHistory.nextViewOptions({
@ -99,5 +81,23 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
from: 'tabs.receive', from: 'tabs.receive',
walletId: $scope.wallet.credentials.walletId walletId: $scope.wallet.credentials.walletId
}); });
};
if (!$scope.isCordova) $scope.checkTips();
$scope.$on('Wallet/Changed', function(event, wallet) {
if (!wallet) {
$log.debug('No wallet provided');
return;
} }
$scope.wallet = wallet;
$log.debug('Wallet changed: ' + wallet.name);
$scope.setAddress();
$timeout(function() {
$scope.$apply();
}, 100);
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.wallets = profileService.getWallets();
});
}); });

View File

@ -1,15 +1,13 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, profileService, lodash, configService, gettextCatalog, platformInfo, walletService, txpModalService, externalLinkService, popupService) { angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, profileService, lodash, configService, gettextCatalog, platformInfo, walletService, txpModalService, externalLinkService, popupService) {
var isCordova = platformInfo.isCordova;
var isWP = platformInfo.isWP;
var isAndroid = platformInfo.isAndroid;
var isChromeApp = platformInfo.isChromeApp;
var HISTORY_SHOW_LIMIT = 10; var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage; var currentTxHistoryPage = 0;
var wallet; var listeners = [];
$scope.txps = []; $scope.txps = [];
$scope.completeTxHistory = [];
$scope.openTxpModal = txpModalService.open;
$scope.openExternalLink = function(url, target) { $scope.openExternalLink = function(url, target) {
externalLinkService.open(url, target); externalLinkService.open(url, target);
@ -24,7 +22,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
// fee: 1000, // fee: 1000,
// createdOn: new Date() / 1000, // createdOn: new Date() / 1000,
// outputs: [], // outputs: [],
// wallet: wallet // wallet: $scope.wallet
// }; // };
// //
// function addOutput(n) { // function addOutput(n) {
@ -44,13 +42,12 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.txps = lodash.sortBy(txps, 'createdOn').reverse(); $scope.txps = lodash.sortBy(txps, 'createdOn').reverse();
}; };
var updateStatus = function(force) {
$scope.updateStatus = function(force) {
$scope.updatingStatus = true; $scope.updatingStatus = true;
$scope.updateStatusError = false; $scope.updateStatusError = false;
$scope.walletNotRegistered = false; $scope.walletNotRegistered = false;
walletService.getStatus(wallet, { walletService.getStatus($scope.wallet, {
force: !!force, force: !!force,
}, function(err, status) { }, function(err, status) {
$scope.updatingStatus = false; $scope.updatingStatus = false;
@ -74,29 +71,8 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}); });
}; };
$scope.openTxpModal = txpModalService.open;
var listeners = [
$rootScope.$on('bwsEvent', function(e, walletId) {
if (walletId == wallet.id)
$scope.updateStatus();
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
if (walletId == wallet.id)
$scope.updateStatus();
}),
];
$scope.$on('$destroy', function() {
lodash.each(listeners, function(x) {
x();
});
});
$scope.openSearchModal = function() { $scope.openSearchModal = function() {
$scope.color = wallet.color; $scope.color = $scope.wallet.color;
$ionicModal.fromTemplateUrl('views/modals/search.html', { $ionicModal.fromTemplateUrl('views/modals/search.html', {
scope: $scope, scope: $scope,
@ -113,7 +89,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.openTxModal = function(btx) { $scope.openTxModal = function(btx) {
$scope.btx = lodash.cloneDeep(btx); $scope.btx = lodash.cloneDeep(btx);
$scope.walletId = wallet.id; $scope.walletId = $scope.wallet.id;
$ionicModal.fromTemplateUrl('views/modals/tx-details.html', { $ionicModal.fromTemplateUrl('views/modals/tx-details.html', {
scope: $scope scope: $scope
}).then(function(modal) { }).then(function(modal) {
@ -123,24 +99,24 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}; };
$scope.recreate = function() { $scope.recreate = function() {
walletService.recreate(wallet, function(err) { walletService.recreate($scope.wallet, function(err) {
$scope.init(); $scope.init();
if (err) return; if (err) return;
$timeout(function() { $timeout(function() {
walletService.startScan(wallet, function() { walletService.startScan($scope.wallet, function() {
$scope.$apply(); $scope.$apply();
}); });
}); });
}); });
}; };
$scope.updateTxHistory = function(cb) { var updateTxHistory = function(cb) {
if (!cb) cb = function() {}; if (!cb) cb = function() {};
if ($scope.updatingTxHistory) return; if ($scope.updatingTxHistory) return;
$scope.updatingTxHistory = true; $scope.updatingTxHistory = true;
$scope.updateTxHistoryError = false; $scope.updateTxHistoryError = false;
$scope.updatingTxHistoryProgress = null; $scope.updatingTxHistoryProgress = 0;
var progressFn = function(txs) { var progressFn = function(txs) {
$scope.updatingTxHistoryProgress = txs ? txs.length : 0; $scope.updatingTxHistoryProgress = txs ? txs.length : 0;
@ -148,11 +124,11 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.showHistory(); $scope.showHistory();
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 1); });
}; };
$timeout(function() { $timeout(function() {
walletService.getTxHistory(wallet, { walletService.getTxHistory($scope.wallet, {
progressFn: progressFn, progressFn: progressFn,
}, function(err, txHistory) { }, function(err, txHistory) {
$scope.updatingTxHistory = false; $scope.updatingTxHistory = false;
@ -162,12 +138,10 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
return; return;
} }
$scope.completeTxHistory = txHistory; $scope.completeTxHistory = txHistory;
$scope.showHistory(); $scope.showHistory();
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}, 1); });
return cb(); return cb();
}); });
}); });
@ -186,51 +160,39 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.$broadcast('scroll.infiniteScrollComplete'); $scope.$broadcast('scroll.infiniteScrollComplete');
}; };
$scope.updateAll = function(cb)  { $scope.updateAll = function(force, cb)  {
$scope.updateStatus(false); updateStatus(force);
$scope.updateTxHistory(cb); updateTxHistory(cb);
}; };
$scope.hideToggle = function() { $scope.hideToggle = function() {
profileService.toggleHideBalanceFlag(wallet.credentials.walletId, function(err) { profileService.toggleHideBalanceFlag($scope.wallet.credentials.walletId, function(err) {
if (err) $log.error(err); if (err) $log.error(err);
}); });
}; };
$scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.$on("$ionicView.beforeEnter", function(event, data) {
currentTxHistoryPage = 0;
$scope.completeTxHistory = [];
wallet = profileService.getWallet($stateParams.walletId); $scope.wallet = profileService.getWallet(data.stateParams.walletId);
$scope.requiresMultipleSignatures = $scope.wallet.credentials.m > 1;
/* Set color for header bar */ $scope.updateAll();
$scope.walletDetailsColor = wallet.color;
$scope.walletDetailsName = wallet.name;
$scope.wallet = wallet;
$scope.requiresMultipleSignatures = wallet.credentials.m > 1; listeners = [
$scope.newTx = false; $rootScope.$on('bwsEvent', function(e, walletId) {
if (walletId == $scope.wallet.id)
updateStatus();
}),
$rootScope.$on('Local/TxAction', function(e, walletId) {
if (walletId == $scope.wallet.id)
updateStatus();
}),
];
});
$scope.updateAll(function() { $scope.$on("$ionicView.leave", function(event, data) {
if ($stateParams.txid) { lodash.each(listeners, function(x) {
var tx = lodash.find($scope.completeTxHistory, { x();
txid: $stateParams.txid
});
if (tx) {
$scope.openTxModal(tx);
} else {
popupService.showAlert(null, gettextCatalog.getString('TX not available'));
}
} else if ($stateParams.txpId) {
var txp = lodash.find($scope.txps, {
id: $stateParams.txpId
});
if (txp) {
$scope.openTxpModal(txp);
} else {
popupService.showAlert(null, gettextCatalog.getString('Proposal not longer available'));
}
}
}); });
}); });
}); });

View File

@ -157,11 +157,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
controller: 'walletDetailsController', controller: 'walletDetailsController',
templateUrl: 'views/walletDetails.html' templateUrl: 'views/walletDetails.html'
} }
}, }
params: {
txid: null,
txpId: null,
},
}) })
.state('tabs.activity', { .state('tabs.activity', {
url: '/activity', url: '/activity',
@ -685,7 +681,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
} }
}) })
.state('onboarding.disclaimer', { .state('onboarding.disclaimer', {
url: '/disclaimer', url: '/disclaimer/:walletId/:backedUp',
views: { views: {
'onboarding': { 'onboarding': {
templateUrl: 'views/onboarding/disclaimer.html' templateUrl: 'views/onboarding/disclaimer.html'

View File

@ -927,9 +927,9 @@ angular.module('copayApp.services')
if (x.pendingTxps) if (x.pendingTxps)
txps = txps.concat(x.pendingTxps); txps = txps.concat(x.pendingTxps);
}); });
txps = lodash.sortBy(txps, 'pendingForUs', 'createdOn');
txps = lodash.compact(lodash.flatten(txps)).slice(0, MAX);
var n = txps.length; var n = txps.length;
txps = lodash.sortBy(txps, 'pendingForUs', 'createdOn');
txps = lodash.compact(lodash.flatten(txps)).slice(0, opts.limit || MAX);
return cb(null, txps, n); return cb(null, txps, n);
}; };

View File

@ -421,8 +421,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null; var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null;
var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null; var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null;
// First update // First update
progressFn(txsFromLocal);
wallet.completeHistory = txsFromLocal; wallet.completeHistory = txsFromLocal;
function getNewTxs(newTxs, skip, cb) { function getNewTxs(newTxs, skip, cb) {
@ -431,7 +431,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res))); newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res)));
progressFn(newTxs); progressFn(newTxs.concat(txsFromLocal));
skip = skip + requestLimit; skip = skip + requestLimit;

140
src/sass/fonts.scss Normal file
View File

@ -0,0 +1,140 @@
@font-face {
font-family: 'Roboto-Black';
src: url('../roboto-font/roboto-black-webfont.woff2') format('woff2'),
url('roboto-black-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Black-Italic';
src: url('../roboto-font/roboto-blackitalic-webfont.woff2') format('woff2'),
url('roboto-blackitalic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Bold';
src: url('../roboto-font/roboto-bold-webfont.woff2') format('woff2'),
url('roboto-bold-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Bold-Italic';
src: url('../roboto-font/roboto-bolditalic-webfont.woff2') format('woff2'),
url('roboto-bolditalic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Italic';
src: url('../roboto-font/roboto-italic-webfont.woff2') format('woff2'),
url('roboto-italic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Light';
src: url('../roboto-font/roboto-light-webfont.woff2') format('woff2'),
url('roboto-light-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Light-Italic';
src: url('../roboto-font/roboto-lightitalic-webfont.woff2') format('woff2'),
url('roboto-lightitalic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Medium';
src: url('../roboto-font/roboto-medium-webfont.woff2') format('woff2'),
url('roboto-medium-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Medium-Italic';
src: url('../roboto-font/roboto-mediumitalic-webfont.woff2') format('woff2'),
url('roboto-mediumitalic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../roboto-font/roboto-regular-webfont.woff2') format('woff2'),
url('roboto-regular-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Thin';
src: url('../roboto-font/roboto-thin-webfont.woff2') format('woff2'),
url('roboto-thin-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto-Thin-Italic';
src: url('../roboto-font/roboto-thinitalic-webfont.woff2') format('woff2'),
url('roboto-thinitalic-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}

View File

@ -983,6 +983,7 @@ input[type=number] {
} }
} }
@import "fonts";
@import "ionic"; @import "ionic";
@import "common"; @import "common";
@import "forms"; @import "forms";

View File

@ -3,6 +3,9 @@
height: 100%; height: 100%;
ion-content{ ion-content{
height: 100%; height: 100%;
&.has-header{
top:40px !important;
}
.scroll{ .scroll{
height: 100%; height: 100%;
} }
@ -10,9 +13,17 @@
margin-top:1.5rem; margin-top:1.5rem;
} }
} }
.tag{
padding-bottom: 0;
}
.list{ .list{
max-width: 600px; max-width: 600px;
@include center-block(); @include center-block();
.item{
&:first-child{
padding-top: 0;
}
}
} }
.item { .item {
background: transparent; background: transparent;
@ -59,6 +70,9 @@
position: absolute; position: absolute;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
&.header-present{
bottom:16px;
}
&-content{ &-content{
max-width: 600px; max-width: 600px;
@include center-block(); @include center-block();

View File

@ -17,7 +17,7 @@
text-align: center; text-align: center;
padding: 2rem 1rem 1.5rem 1rem; padding: 2rem 1rem 1.5rem 1rem;
color: #fff; color: #fff;
min-height: 115px; height: 140px;
margin-bottom: 10px; margin-bottom: 10px;
&-alternative { &-alternative {