-
-
-
- ...
+
+
+
+
-
+ Incomplete wallet
-
- Before receiving funds, you must backup your wallet. If this device is lost, it is impossible to access your funds without a backup.
+
-
+ All signing devices must be added to this multisig wallet before bitcoin addresses can be created.
+
+
+ Open wallet
-
-
-
- Share
+
+
-
+
+
+ address not yet available
+
-
-
- Next Address
+
+
+
-
+
-
+ Wallet not backed up
-
-
-
- ...
- {{addr}}
+
-
+
+
-
+
+
+ ...
+
+
+
+
+
+
+ Share
+
+
+
+
+
+ Next Address
+
+
+
+
+
+
+
+
+ ...
+ {{addr}}
+
+
No Wallet
diff --git a/public/views/tab-send.html b/public/views/tab-send.html
index 29af3f48b..3ab5f5f6a 100644
--- a/public/views/tab-send.html
+++ b/public/views/tab-send.html
@@ -4,42 +4,47 @@
-
-
+
- Recipient
-
+
diff --git a/public/views/tab-settings.html b/public/views/tab-settings.html
index 6c5add5f2..0231d8d99 100644
--- a/public/views/tab-settings.html
+++ b/public/views/tab-settings.html
@@ -14,6 +14,12 @@
- Enable Glidera Service
-
-
-
-
-
-
- Use Unconfirmed Funds
-
-
- directive will have its own
navigation history that also transitions its views in and out.
-->
-
+
-
+
-
+
@@ -21,7 +21,7 @@ navigation history that also transitions its views in and out.
-
+
diff --git a/src/js/controllers/advancedSettings.js b/src/js/controllers/advancedSettings.js
new file mode 100644
index 000000000..928b64a93
--- /dev/null
+++ b/src/js/controllers/advancedSettings.js
@@ -0,0 +1,113 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('advancedSettingsController', function($scope, $rootScope, $log, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {
+
+ var updateConfig = function() {
+
+ var config = configService.getSync();
+
+ $scope.spendUnconfirmed = {
+ value: config.wallet.spendUnconfirmed
+ };
+ $scope.bitpayCardEnabled = {
+ value: config.bitpayCard.enabled
+ };
+ $scope.amazonEnabled = {
+ value: config.amazon.enabled
+ };
+ $scope.glideraEnabled = {
+ value: config.glidera.enabled
+ };
+ $scope.coinbaseEnabled = {
+ value: config.coinbase.enabled
+ };
+ $scope.recentTransactionsEnabled = {
+ value: config.recentTransactions.enabled
+ };
+ $scope.frequentlyUsedEnabled = {
+ value: config.frequentlyUsed.enabled
+ };
+ };
+
+ $scope.spendUnconfirmedChange = function() {
+ var opts = {
+ wallet: {
+ spendUnconfirmed: $scope.spendUnconfirmed.value
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.bitpayCardChange = function() {
+ var opts = {
+ bitpayCard: {
+ enabled: $scope.bitpayCardEnabled.value
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.amazonChange = function() {
+ var opts = {
+ amazon: {
+ enabled: $scope.amazonEnabled.value
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.glideraChange = function() {
+ var opts = {
+ glidera: {
+ enabled: $scope.glideraEnabled.value
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.coinbaseChange = function() {
+ var opts = {
+ coinbase: {
+ enabled: $scope.coinbaseEnabled
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.recentTransactionsChange = function() {
+ var opts = {
+ recentTransactions: {
+ enabled: $scope.recentTransactionsEnabled
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.frequentlyUsedChange = function() {
+ var opts = {
+ frequentlyUsed: {
+ enabled: $scope.frequentlyUsedEnabled
+ }
+ };
+ configService.set(opts, function(err) {
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.$on("$ionicView.enter", function(event, data) {
+ updateConfig();
+ });
+
+});
diff --git a/src/js/controllers/amount.js b/src/js/controllers/amount.js
index 590fa55d4..e4b157408 100644
--- a/src/js/controllers/amount.js
+++ b/src/js/controllers/amount.js
@@ -15,11 +15,11 @@ angular.module('copayApp.controllers').controller('amountController', function($
$scope.toName = $stateParams.toName;
$scope.toEmail = $stateParams.toEmail;
- $scope.$on('$ionicView.beforeLeave', function() {
+ $scope.$on('$ionicView.leave', function() {
angular.element($window).off('keydown');
});
- $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ $scope.$on("$ionicView.enter", function(event, data) {
if (!$stateParams.toAddress) {
$log.error('Bad params at amount')
@@ -60,6 +60,8 @@ angular.module('copayApp.controllers').controller('amountController', function($
satToBtc = 1 / 100000000;
unitDecimals = config.unitDecimals;
+ $scope.resetAmount();
+
// in SAT ALWAYS
if ($stateParams.toAmount) {
$scope.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals);
diff --git a/src/js/controllers/backup.js b/src/js/controllers/backup.js
index ea28fdaad..01eeae6ec 100644
--- a/src/js/controllers/backup.js
+++ b/src/js/controllers/backup.js
@@ -49,15 +49,6 @@ angular.module('copayApp.controllers').controller('backupController',
}, 10);
};
- $scope.goBack = function() {
- if ($scope.step == 1) {
- if ($stateParams.fromOnboarding) $state.go('onboarding.backupRequest');
- else $state.go('wallet.preferences');
- } else {
- $scope.goToStep($scope.step - 1);
- }
- };
-
var backupError = function(err) {
ongoingProcess.set('validatingWords', false);
$log.debug('Failed to verify backup: ', err);
@@ -93,13 +84,15 @@ angular.module('copayApp.controllers').controller('backupController',
$scope.closeBackupResultModal = function() {
$scope.confirmBackupModal.hide();
+ $scope.confirmBackupModal.remove();
- if ($stateParams.fromOnboarding) {
- $state.go('onboarding.disclaimer');
- } else {
- $ionicHistory.removeBackView();
- $state.go('tabs.home');
- }
+ profileService.isDisclaimerAccepted(function(val) {
+ if (val) {
+ $ionicHistory.removeBackView();
+ $state.go('tabs.home');
+ }
+ else $state.go('onboarding.disclaimer');
+ });
};
var confirm = function(cb) {
@@ -193,16 +186,6 @@ angular.module('copayApp.controllers').controller('backupController',
$scope.selectComplete = false;
};
- $scope.backupGoBack = function() {
- if ($stateParams.fromOnboarding) $state.go('onboarding.backupWarning', {
- walletId: $stateParams.walletId,
- fromOnboarding: true
- });
- else $state.go('tabs.preferences', {
- walletId: $stateParams.walletId
- });
- };
-
$scope.$on("$ionicView.enter", function(event, data) {
$scope.deleted = isDeletedSeed();
if ($scope.deleted) {
diff --git a/src/js/controllers/confirm.js b/src/js/controllers/confirm.js
index 4f0a595bd..0b6654842 100644
--- a/src/js/controllers/confirm.js
+++ b/src/js/controllers/confirm.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, $ionicPopup, gettext, txFormatService, ongoingProcess, $ionicModal, $ionicHistory, popupService) {
+angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, gettext, txFormatService, ongoingProcess, $ionicModal, popupService) {
var cachedTxp = {};
var isChromeApp = platformInfo.isChromeApp;
diff --git a/src/js/controllers/copayers.js b/src/js/controllers/copayers.js
index 186c23ae1..765db7d52 100644
--- a/src/js/controllers/copayers.js
+++ b/src/js/controllers/copayers.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('copayersController',
- function($scope, $log, $ionicNavBarDelegate, $timeout, $stateParams, $state, $rootScope, $ionicHistory, lodash, profileService, walletService, popupService, platformInfo, gettextCatalog, ongoingProcess) {
+ function($scope, $log, $timeout, $stateParams, $state, $rootScope, $ionicHistory, lodash, profileService, walletService, popupService, platformInfo, gettextCatalog, ongoingProcess) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
init();
diff --git a/src/js/controllers/import.js b/src/js/controllers/import.js
index 388360787..bdc97e984 100644
--- a/src/js/controllers/import.js
+++ b/src/js/controllers/import.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('importController',
- function($scope, $timeout, $log, $state, $stateParams, profileService, configService, sjcl, ledger, trezor, derivationPathHelper, platformInfo, bwcService, ongoingProcess, walletService, popupService, gettextCatalog) {
+ function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, profileService, configService, sjcl, ledger, trezor, derivationPathHelper, platformInfo, bwcService, ongoingProcess, walletService, popupService, gettextCatalog) {
var isChromeApp = platformInfo.isChromeApp;
var isDevel = platformInfo.isDevel;
diff --git a/src/js/controllers/join.js b/src/js/controllers/join.js
index f983e25c5..83150713a 100644
--- a/src/js/controllers/join.js
+++ b/src/js/controllers/join.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('joinController',
- function($scope, $rootScope, $timeout, $state, profileService, configService, storageService, applicationService, gettext, gettextCatalog, lodash, ledger, trezor, platformInfo, derivationPathHelper, ongoingProcess, walletService, $log, $stateParams, popupService) {
+ function($scope, $rootScope, $timeout, $state, $ionicHistory, profileService, configService, storageService, applicationService, gettext, gettextCatalog, lodash, ledger, trezor, platformInfo, derivationPathHelper, ongoingProcess, walletService, $log, $stateParams, popupService) {
var isChromeApp = platformInfo.isChromeApp;
var isDevel = platformInfo.isDevel;
@@ -146,7 +146,19 @@ angular.module('copayApp.controllers').controller('joinController',
$log.debug('Remote preferences saved for:' + client.credentials.walletId)
});
$ionicHistory.removeBackView();
- $state.go('tabs.home');
+
+ if (!client.isComplete()) {
+ $ionicHistory.nextViewOptions({
+ disableAnimate: true
+ });
+ $state.go('tabs.home');
+ $timeout(function() {
+ $state.transitionTo('tabs.copayers', {
+ walletId: client.credentials.walletId
+ });
+ }, 100);
+ }
+ else $state.go('tabs.home')
});
}, 100);
};
diff --git a/src/js/controllers/modals/txDetails.js b/src/js/controllers/modals/txDetails.js
index b4e45dae1..37f6718fa 100644
--- a/src/js/controllers/modals/txDetails.js
+++ b/src/js/controllers/modals/txDetails.js
@@ -73,6 +73,8 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
time: $scope.btx.time,
description: actionDescriptions['broadcasted'],
});
+
+ $scope.actionList.reverse();
};
$scope.showCommentPopup = function() {
@@ -126,6 +128,9 @@ angular.module('copayApp.controllers').controller('txDetailsController', functio
$scope.rateDate = res.fetchedOn;
$scope.rateStr = res.rate + ' ' + $scope.alternativeIsoCode;
$scope.alternativeAmountStr = $filter('formatFiatAmount')(alternativeAmountBtc * res.rate) + ' ' + $scope.alternativeIsoCode;
+ $timeout(function() {
+ $scope.$apply();
+ });
}
});
};
diff --git a/src/js/controllers/modals/txStatus.js b/src/js/controllers/modals/txStatus.js
index d8383c5eb..9b9cdd7e4 100644
--- a/src/js/controllers/modals/txStatus.js
+++ b/src/js/controllers/modals/txStatus.js
@@ -3,13 +3,16 @@
angular.module('copayApp.controllers').controller('txStatusController', function($scope, $timeout, $state, $ionicHistory, $log, addressbookService) {
if ($scope.cb) $timeout($scope.cb, 100);
- $scope.fromSendTab = $ionicHistory.viewHistory().backView.stateName === "tabs.send.amount" || "tabs.send";
+ $scope.fromSendTab = $ionicHistory.viewHistory().backView && $ionicHistory.viewHistory().backView.stateName === "tabs.send.amount" || "tabs.send";
$scope.cancel = function() {
$scope.txStatusModal.hide();
if ($scope.fromSendTab) {
$ionicHistory.removeBackView();
- $state.go('tabs.home');
+ $state.go('tabs.send');
+ $timeout(function() {
+ $state.transitionTo('tabs.home');
+ }, 100);
}
};
diff --git a/src/js/controllers/modals/txpDetails.js b/src/js/controllers/modals/txpDetails.js
index 75c4a3120..8f76d7f4d 100644
--- a/src/js/controllers/modals/txpDetails.js
+++ b/src/js/controllers/modals/txpDetails.js
@@ -7,6 +7,7 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
var isGlidera = $scope.isGlidera;
var GLIDERA_LOCK_TIME = 6 * 60 * 60;
var now = Math.floor(Date.now() / 1000);
+ var countDown;
$scope.init = function() {
$scope.loading = null;
@@ -18,6 +19,7 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
$scope.data = {};
initActionList();
+ checkPaypro();
}
function initActionList() {
@@ -47,14 +49,14 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
by: action.copayerName
});
});
+
+ $scope.actionList.reverse();
};
$scope.$on('accepted', function(event) {
$scope.sign();
});
- checkPaypro();
-
// ToDo: use tx.customData instead of tx.message
if (tx.message === 'Glidera transaction' && isGlidera) {
tx.isGlidera = true;
@@ -154,7 +156,7 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
$scope.paymentExpired = false;
setExpirationTime();
- self.countDown = $interval(function() {
+ countDown = $interval(function() {
setExpirationTime();
}, 1000);
@@ -162,7 +164,7 @@ angular.module('copayApp.controllers').controller('txpDetailsController', functi
var now = Math.floor(Date.now() / 1000);
if (now > expirationTime) {
$scope.paymentExpired = true;
- if (self.countDown) $interval.cancel(self.countDown);
+ if (countDown) $interval.cancel(countDown);
return;
}
var totalSecs = expirationTime - now;
diff --git a/src/js/controllers/onboarding/backupRequest.js b/src/js/controllers/onboarding/backupRequest.js
index 1ff5e6271..abf63c661 100644
--- a/src/js/controllers/onboarding/backupRequest.js
+++ b/src/js/controllers/onboarding/backupRequest.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, $ionicPopup, popupService, gettextCatalog) {
+angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, popupService, gettextCatalog) {
$scope.walletId = $stateParams.walletId;
diff --git a/src/js/controllers/onboarding/backupWarning.js b/src/js/controllers/onboarding/backupWarning.js
index 6b83ee964..795ce1d33 100644
--- a/src/js/controllers/onboarding/backupWarning.js
+++ b/src/js/controllers/onboarding/backupWarning.js
@@ -1,24 +1,35 @@
'use strict';
-angular.module('copayApp.controllers').controller('backupWarningController', function($scope, $state, $timeout, $stateParams, $ionicPopup, profileService, $ionicModal) {
+angular.module('copayApp.controllers').controller('backupWarningController', function($scope, $state, $timeout, $stateParams, profileService, $ionicModal) {
$scope.walletId = $stateParams.walletId;
$scope.openPopup = function() {
$ionicModal.fromTemplateUrl('views/includes/screenshotWarningModal.html', {
- scope: $scope,
- backdropClickToClose: false,
- hardwareBackButtonClose: false
- }).then(function(modal) {
- $scope.warningModal = modal;
- $scope.warningModal.show();
- });
+ scope: $scope,
+ backdropClickToClose: false,
+ hardwareBackButtonClose: false
+ }).then(function(modal) {
+ $scope.warningModal = modal;
+ $scope.warningModal.show();
+ });
$scope.close = function() {
$scope.warningModal.hide();
- $state.go('onboarding.backup', {
- walletId: $stateParams.walletId,
- fromOnboarding: true
- });
+ if ($stateParams.from == 'onboarding.backupRequest')
+ $state.go('onboarding.backup', {
+ walletId: $stateParams.walletId
+ });
+ else
+ $state.go($stateParams.from + '.backup', {
+ walletId: $stateParams.walletId
+ });
};
}
+
+ $scope.goBack = function() {
+ $state.go($stateParams.from, {
+ walletId: $stateParams.walletId
+ });
+ };
+
});
diff --git a/src/js/controllers/onboarding/welcomeController.js b/src/js/controllers/onboarding/welcomeController.js
index bb74b9206..aca36409b 100644
--- a/src/js/controllers/onboarding/welcomeController.js
+++ b/src/js/controllers/onboarding/welcomeController.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $log, $ionicPopup, profileService) {
+angular.module('copayApp.controllers').controller('welcomeController', function($scope, $state, $timeout, $log, profileService) {
$scope.goImport = function(code) {
$state.go('onboarding.import', {
diff --git a/src/js/controllers/preferencesAbout.js b/src/js/controllers/preferencesAbout.js
index 79bc23cdf..64f10de54 100644
--- a/src/js/controllers/preferencesAbout.js
+++ b/src/js/controllers/preferencesAbout.js
@@ -1,11 +1,9 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesAbout',
- function($scope, $window, $ionicNavBarDelegate, gettextCatalog, externalLinkService) {
- $scope.$on("$ionicView.beforeEnter", function(event, data){
- $ionicNavBarDelegate.title(gettextCatalog.getString('About') + ' ' + $window.appConfig.nameCase);
- });
+ function($scope, $window, gettextCatalog, externalLinkService) {
+ $scope.title = gettextCatalog.getString('About') + ' ' + $window.appConfig.nameCase;
$scope.version = $window.version;
$scope.commitHash = $window.commitHash;
$scope.name = $window.appConfig.gitHubRepoName;
diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js
index d75fed717..60c1a4c2d 100644
--- a/src/js/controllers/preferencesDelete.js
+++ b/src/js/controllers/preferencesDelete.js
@@ -4,7 +4,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro
function($scope, $stateParams, $ionicHistory, gettextCatalog, lodash, profileService, $state, ongoingProcess, popupService) {
var wallet = profileService.getWallet($stateParams.walletId);
$scope.alias = lodash.isEqual(wallet.name, wallet.credentials.walletName) ? null : wallet.name + ' ';
- $scope.walletName = '[' + wallet.credentials.walletName + ']';
+ $scope.walletName = wallet.credentials.walletName;
$scope.showDeletePopup = function() {
var title = gettextCatalog.getString('Warning!');
diff --git a/src/js/controllers/preferencesNotifications.js b/src/js/controllers/preferencesNotifications.js
new file mode 100644
index 000000000..8d947dde8
--- /dev/null
+++ b/src/js/controllers/preferencesNotifications.js
@@ -0,0 +1,52 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('preferencesNotificationsController',
+ function($scope, $rootScope, $log, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {
+
+ var updateConfig = function() {
+
+ var config = configService.getSync();
+ var isCordova = platformInfo.isCordova;
+ var isIOS = platformInfo.isIOS;
+
+ $scope.PNEnabledByUser = true;
+ $scope.isIOSApp = isIOS && isCordova;
+ if ($scope.isIOSApp) {
+ cordova.plugins.diagnostic.isRemoteNotificationsEnabled(function(isEnabled) {
+ $scope.PNEnabledByUser = isEnabled;
+ $scope.$digest();
+ });
+ }
+
+ $scope.pushNotifications = {
+ value: config.pushNotifications.enabled
+ };
+ };
+
+ $scope.openSettings = function() {
+ cordova.plugins.diagnostic.switchToSettings(function() {
+ $log.debug('switched to settings');
+ }, function(err) {
+ $log.debug(err);
+ });
+ };
+
+ $scope.pushNotificationsChange = function() {
+ var opts = {
+ pushNotifications: {
+ enabled: $scope.pushNotifications.value
+ }
+ };
+ configService.set(opts, function(err) {
+ if (opts.pushNotifications.enabled)
+ pushNotificationsService.enableNotifications(profileService.walletClients);
+ else
+ pushNotificationsService.disableNotifications(profileService.walletClients);
+ if (err) $log.debug(err);
+ });
+ };
+
+ $scope.$on("$ionicView.enter", function(event, data) {
+ updateConfig();
+ });
+ });
diff --git a/src/js/controllers/tab-home.js b/src/js/controllers/tab-home.js
index 67f93c1fe..fbaa561f4 100644
--- a/src/js/controllers/tab-home.js
+++ b/src/js/controllers/tab-home.js
@@ -180,6 +180,11 @@ angular.module('copayApp.controllers').controller('tabHomeController',
});
};
+ $scope.shouldHideNextSteps = function() {
+ $scope.hideNextSteps = !$scope.hideNextSteps;
+ $ionicScrollDelegate.resize();
+ };
+
var listeners = [
$rootScope.$on('bwsEvent', function(e, walletId, type, n) {
var wallet = profileService.getWallet(walletId);
@@ -204,6 +209,10 @@ angular.module('copayApp.controllers').controller('tabHomeController',
var isWindowsPhoneApp = platformInfo.isWP && platformInfo.isCordova;
$scope.glideraEnabled = config.glidera.enabled && !isWindowsPhoneApp;
$scope.coinbaseEnabled = config.coinbase.enabled && !isWindowsPhoneApp;
+ $scope.amazonEnabled = config.amazon.enabled;
+ $scope.bitpayCardEnabled = config.bitpayCard.enabled;
+ $scope.nextStepEnabled = $scope.glideraEnabled || $scope.coinbaseEnabled || $scope.amazonEnabled || $scope.bitpayCardEnabled;
+ $scope.recentTransactionsEnabled = config.recentTransactions.enabled;
});
$scope.nextStep();
$scope.updateAllWallets();
diff --git a/src/js/controllers/tab-receive.js b/src/js/controllers/tab-receive.js
index 7a1886832..9b7b2c672 100644
--- a/src/js/controllers/tab-receive.js
+++ b/src/js/controllers/tab-receive.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabReceiveController', function($scope, $timeout, $log, $ionicModal, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService) {
+angular.module('copayApp.controllers').controller('tabReceiveController', function($scope, $timeout, $log, $ionicModal, $state, $ionicHistory, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService) {
$scope.isCordova = platformInfo.isCordova;
$scope.isNW = platformInfo.isNW;
@@ -29,29 +29,25 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
};
$scope.setAddress = function(forceNew) {
- if ($scope.generatingAddress) return;
+ if ($scope.generatingAddress || !$scope.wallet.isComplete()) return;
$scope.addr = null;
$scope.generatingAddress = true;
-
$timeout(function() {
walletService.getAddress($scope.wallet, forceNew, function(err, addr) {
$scope.generatingAddress = false;
- if (err || lodash.isEmpty(addr)) {
- popupService.showAlert(gettextCatalog.getString('Error'), err || gettextCatalog.getString('Address is empty'));
- return;
- }
+ if (err) popupService.showAlert(gettextCatalog.getString('Error'), err);
$scope.addr = addr;
+ if ($scope.wallet.showBackupNeededModal) $scope.openBackupNeededModal();
$scope.$apply();
});
- }, 1);
+ }, 100);
+
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
if (!$scope.isCordova) $scope.checkTips();
- $scope.wallets = profileService.getWallets({
- onlyComplete: true
- });
+ $scope.wallets = profileService.getWallets();
$scope.$on('Wallet/Changed', function(event, wallet) {
if (!wallet) {
$log.debug('No wallet provided');
@@ -62,4 +58,46 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.setAddress();
});
});
+
+ $scope.goCopayers = function() {
+ $ionicHistory.removeBackView();
+ $ionicHistory.nextViewOptions({
+ disableAnimate: true
+ });
+ $state.go('tabs.home');
+ $timeout(function() {
+ $state.transitionTo('tabs.copayers', {
+ walletId: $scope.wallet.credentials.walletId
+ });
+ }, 100);
+ };
+
+ $scope.openBackupNeededModal = function() {
+ $ionicModal.fromTemplateUrl('views/includes/backupNeededPopup.html', {
+ scope: $scope,
+ backdropClickToClose: false,
+ hardwareBackButtonClose: false
+ }).then(function(modal) {
+ $scope.BackupNeededModal = modal;
+ $scope.BackupNeededModal.show();
+ });
+ };
+
+ $scope.close = function() {
+ $scope.BackupNeededModal.hide();
+ $scope.BackupNeededModal.remove();
+ profileService.setBackupNeededModalFlag($scope.wallet.credentials.walletId);
+ };
+
+ $scope.doBackup = function() {
+ $scope.close();
+ $scope.goToBackupFlow();
+ };
+
+ $scope.goToBackupFlow = function() {
+ $state.go('tabs.receive.backupWarning', {
+ from: 'tabs.receive',
+ walletId: $scope.wallet.credentials.walletId
+ });
+ }
});
diff --git a/src/js/controllers/tab-send.js b/src/js/controllers/tab-send.js
index ce2fb7bd6..c3583249a 100644
--- a/src/js/controllers/tab-send.js
+++ b/src/js/controllers/tab-send.js
@@ -1,8 +1,10 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabSendController', function($scope, $log, $timeout, addressbookService, profileService, lodash, $state, walletService, incomingData) {
+angular.module('copayApp.controllers').controller('tabSendController', function($scope, $log, $timeout, $ionicScrollDelegate, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService) {
var originalList;
+ var CONTACTS_SHOW_LIMIT = 10;
+ var currentContactsPage = 0;
var updateList = function() {
originalList = [];
@@ -11,6 +13,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
onlyComplete: true
});
$scope.hasWallets = lodash.isEmpty(wallets) ? false : true;
+ $scope.oneWallet = wallets.length == 1;
lodash.each(wallets, function(v) {
originalList.push({
@@ -27,9 +30,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
if (err) $log.error(err);
$scope.hasContacts = lodash.isEmpty(ab) ? false : true;
- var contacts = [];
+ var completeContacts = [];
lodash.each(ab, function(v, k) {
- contacts.push({
+ completeContacts.push({
name: lodash.isObject(v) ? v.name : v,
address: k,
email: lodash.isObject(v) ? v.email : null,
@@ -39,15 +42,23 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
});
});
+ var contacts = completeContacts.slice(0, (currentContactsPage + 1) * CONTACTS_SHOW_LIMIT);
+ $scope.contactsShowMore = completeContacts.length > contacts.length;
originalList = originalList.concat(contacts);
$scope.list = lodash.clone(originalList);
$timeout(function() {
+ $ionicScrollDelegate.resize();
$scope.$apply();
- }, 1);
+ }, 10);
});
};
+ $scope.showMore = function() {
+ currentContactsPage++;
+ updateList();
+ };
+
$scope.findContact = function(search) {
if (incomingData.redir(search)) {
@@ -86,8 +97,16 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
});
};
- $scope.$on("$ionicView.beforeEnter", function(event, data){
- $scope.formData = { search: null };
+ $scope.onQrCodeScanned = function(data) {
+ if (!incomingData.redir(data)) {
+ popupService.showAlert(null, gettextCatalog.getString('Invalid data'));
+ }
+ };
+
+ $scope.$on("$ionicView.beforeEnter", function(event, data) {
+ $scope.formData = {
+ search: null
+ };
updateList();
});
diff --git a/src/js/controllers/tab-settings.js b/src/js/controllers/tab-settings.js
index f8f13202c..ec1492ef9 100644
--- a/src/js/controllers/tab-settings.js
+++ b/src/js/controllers/tab-settings.js
@@ -9,6 +9,8 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
var isWP = platformInfo.isWP;
var isIOS = platformInfo.isIOS;
+ $scope.usePushNotifications = isCordova && !isWP;
+
$scope.appName = $window.appConfig.nameCase;
$scope.unitName = config.wallet.settings.unitName;
@@ -19,87 +21,13 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
};
$scope.feeOpts = feeService.feeOpts;
$scope.currentFeeLevel = feeService.getCurrentFeeLevel();
- $scope.usePushNotifications = isCordova && !isWP;
- $scope.PNEnabledByUser = true;
- $scope.isIOSApp = isIOS && isCordova;
- if ($scope.isIOSApp) {
- cordova.plugins.diagnostic.isRemoteNotificationsEnabled(function(isEnabled) {
- $scope.PNEnabledByUser = isEnabled;
- $scope.$digest();
- });
- }
- $scope.spendUnconfirmed = {
- value: config.wallet.spendUnconfirmed
- };
- $scope.glideraEnabled = {
- value: config.glidera.enabled
- };
- $scope.coinbaseEnabled = config.coinbase.enabled;
- $scope.pushNotifications = {
- value: config.pushNotifications.enabled
- };
+
$scope.otherWallets = lodash.filter(profileService.getWallets(self.network), function(w) {
return w.id != self.walletId;
});
$scope.wallets = profileService.getWallets();
};
- $scope.openSettings = function() {
- cordova.plugins.diagnostic.switchToSettings(function() {
- $log.debug('switched to settings');
- }, function(err) {
- $log.debug(err);
- });
- };
-
- $scope.spendUnconfirmedChange = function() {
- var opts = {
- wallet: {
- spendUnconfirmed: $scope.spendUnconfirmed.value
- }
- };
- configService.set(opts, function(err) {
- if (err) $log.debug(err);
- });
- };
-
- $scope.pushNotificationsChange = function() {
- var opts = {
- pushNotifications: {
- enabled: $scope.pushNotifications.value
- }
- };
- configService.set(opts, function(err) {
- if (opts.pushNotifications.enabled)
- pushNotificationsService.enableNotifications(profileService.walletClients);
- else
- pushNotificationsService.disableNotifications(profileService.walletClients);
- if (err) $log.debug(err);
- });
- };
-
- $scope.glideraChange = function() {
- var opts = {
- glidera: {
- enabled: $scope.glideraEnabled.value
- }
- };
- configService.set(opts, function(err) {
- if (err) $log.debug(err);
- });
- };
-
- $scope.coinbaseChange = function() {
- var opts = {
- coinbase: {
- enabled: $scope.coinbaseEnabled
- }
- };
- configService.set(opts, function(err) {
- if (err) $log.debug(err);
- });
- };
-
$scope.$on("$ionicView.enter", function(event, data) {
updateConfig();
});
diff --git a/src/js/controllers/tabsController.js b/src/js/controllers/tabsController.js
index ccd1b1e88..bfb12da45 100644
--- a/src/js/controllers/tabsController.js
+++ b/src/js/controllers/tabsController.js
@@ -1,12 +1,10 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabsController', function($log, $scope, $stateParams, $ionicModal, $timeout, incomingData) {
+angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, incomingData, lodash, popupService) {
$scope.onScan = function(data) {
if (!incomingData.redir(data)) {
- $ionicPopup.alert({
- title: 'Invalid data',
- });
+ popupService.showAlert(null, gettextCatalog.getString('Invalid data'));
}
}
@@ -22,6 +20,32 @@ angular.module('copayApp.controllers').controller('tabsController', function($lo
$timeout(function() {
$scope.$apply();
}, 1);
- }
+ };
+
+ var hideTabsViews = [
+ 'tabs.send.amount',
+ 'tabs.send.confirm',
+ 'tabs.send.addressbook',
+ 'tabs.addressbook',
+ 'tabs.addressbook.add',
+ 'tabs.addressbook.view',
+ 'tabs.preferences.backupWarning',
+ 'tabs.preferences.backup',
+ 'tabs.receive.backupWarning',
+ 'tabs.receive.backup',
+ ];
+
+ $rootScope.$on('$ionicView.beforeEnter', function() {
+
+ $rootScope.hideTabs = false;
+
+ var currentState = $state.current.name;
+
+ lodash.each(hideTabsViews, function(view) {
+ if (currentState === view) {
+ $rootScope.hideTabs = true;
+ }
+ });
+ });
});
diff --git a/src/js/controllers/walletDetails.js b/src/js/controllers/walletDetails.js
index b6a51f331..dbb357ca4 100644
--- a/src/js/controllers/walletDetails.js
+++ b/src/js/controllers/walletDetails.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $ionicNavBarDelegate, $state, $stateParams, profileService, lodash, configService, gettext, gettextCatalog, platformInfo, walletService, $ionicPopup, txpModalService, externalLinkService) {
+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;
@@ -204,15 +204,13 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
wallet = profileService.getWallet($stateParams.walletId);
/* Set color for header bar */
- $rootScope.walletDetailsColor = wallet.color;
- $rootScope.walletDetailsName = wallet.name;
+ $scope.walletDetailsColor = wallet.color;
+ $scope.walletDetailsName = wallet.name;
$scope.wallet = wallet;
$scope.requiresMultipleSignatures = wallet.credentials.m > 1;
$scope.newTx = false;
- $ionicNavBarDelegate.title(wallet.name);
-
$scope.updateAll(function() {
if ($stateParams.txid) {
var tx = lodash.find($scope.completeTxHistory, {
@@ -221,9 +219,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
if (tx) {
$scope.openTxModal(tx);
} else {
- $ionicPopup.alert({
- title: gettext('TX not available'),
- });
+ popupService.showAlert(null, gettextCatalog.getString('TX not available'));
}
} else if ($stateParams.txpId) {
var txp = lodash.find($scope.txps, {
@@ -232,9 +228,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
if (txp) {
$scope.openTxpModal(txp);
} else {
- $ionicPopup.alert({
- title: gettext('Proposal not longer available'),
- });
+ popupService.showAlert(null, gettextCatalog.getString('Proposal not longer available'));
}
}
});
diff --git a/src/js/routes.js b/src/js/routes.js
index dea85a6e8..ba828213c 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -191,6 +191,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
.state('tabs', {
url: '/tabs',
abstract: true,
+ controller: 'tabsController',
templateUrl: 'views/tabs.html'
})
.state('tabs.home', {
@@ -236,7 +237,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*
*/
- .state('tabs.send.amount', {
+ .state('tabs.send.amount', {
url: '/amount/:isWallet/:toAddress/:toName/:toEmail',
views: {
'tab-send@tabs': {
@@ -317,7 +318,16 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*
*/
- .state('tabs.language', {
+ .state('tabs.notifications', {
+ url: '/notifications',
+ views: {
+ 'tab-settings@tabs': {
+ controller: 'preferencesNotificationsController',
+ templateUrl: 'views/preferencesNotifications.html'
+ }
+ }
+ })
+ .state('tabs.language', {
url: '/language',
views: {
'tab-settings@tabs': {
@@ -389,6 +399,15 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
+ .state('tabs.advanced', {
+ url: '/advanced',
+ views: {
+ 'tab-settings@tabs': {
+ controller: 'advancedSettingsController',
+ templateUrl: 'views/advancedSettings.html'
+ }
+ }
+ })
/*
*
@@ -432,6 +451,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
}
})
+ .state('tabs.preferences.backupWarning', {
+ url: '/backupWarning/:from',
+ views: {
+ 'tab-settings@tabs': {
+ templateUrl: 'views/backupWarning.html'
+ }
+ }
+ })
.state('tabs.preferences.backup', {
url: '/backup',
views: {
@@ -551,7 +578,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
/*
*
- *TO DO
+ * Copayers
*
*/
@@ -565,6 +592,30 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
+ /*
+ *
+ * Back flow from receive
+ *
+ */
+
+ .state('tabs.receive.backupWarning', {
+ url: '/backupWarning/:from/:walletId',
+ views: {
+ 'tab-receive@tabs': {
+ templateUrl: 'views/backupWarning.html'
+ }
+ }
+ })
+ .state('tabs.receive.backup', {
+ url: '/backup/:walletId',
+ views: {
+ 'tab-receive@tabs': {
+ controller: 'backupController',
+ templateUrl: 'views/backup.html'
+ }
+ }
+ })
+
/*
*
* Onboarding
@@ -617,15 +668,15 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('onboarding.backupWarning', {
- url: '/backupWarning/:walletId',
+ url: '/backupWarning/:from/:walletId',
views: {
'onboarding': {
- templateUrl: 'views/onboarding/backupWarning.html'
+ templateUrl: 'views/backupWarning.html'
}
}
})
.state('onboarding.backup', {
- url: '/backup/:walletId/:fromOnboarding',
+ url: '/backup/:walletId',
views: {
'onboarding': {
templateUrl: 'views/backup.html',
@@ -944,6 +995,8 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
$log.debug('Route change from:', fromState.name || '-', ' to:', toState.name);
$log.debug(' toParams:' + JSON.stringify(toParams || {}));
$log.debug(' fromParams:' + JSON.stringify(fromParams || {}));
+
+ if (!toState.name.match(/onboarding/)) return;
var state = {};
state.name = toState.name;
state.toParams = toParams;
diff --git a/src/js/services/configService.js b/src/js/services/configService.js
index 9ef2fdf23..f7728c6c5 100644
--- a/src/js/services/configService.js
+++ b/src/js/services/configService.js
@@ -39,10 +39,28 @@ angular.module('copayApp.services').factory('configService', function(storageSer
},
coinbase: {
- enabled: true,
+ enabled: false, //disable coinbase for this release
testnet: false
},
+ bitpayCard: {
+ enabled: true
+ },
+
+ amazon: {
+ enabled: true
+ },
+
+ //Experimental Features
+
+ recentTransactions: {
+ enabled: true
+ },
+
+ frequentlyUsed: {
+ enabled: true
+ },
+
rates: {
url: 'https://insight.bitpay.com:443/api/rates',
},
@@ -111,6 +129,18 @@ angular.module('copayApp.services').factory('configService', function(storageSer
if (!configCache.coinbase) {
configCache.coinbase = defaultConfig.coinbase;
}
+ if (!configCache.amazon) {
+ configCache.amazon = defaultConfig.amazon;
+ }
+ if (!configCache.bitpayCard) {
+ configCache.bitpayCard = defaultConfig.bitpayCard;
+ }
+ if (!configCache.recentTransactions) {
+ configCache.recentTransactions = defaultConfig.recentTransactions;
+ }
+ if (!configCache.frequentlyUsed) {
+ configCache.frequentlyUsed = defaultConfig.frequentlyUsed;
+ }
if (!configCache.pushNotifications) {
configCache.pushNotifications = defaultConfig.pushNotifications;
}
diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js
index c6bc0d3d0..0dea73fb0 100644
--- a/src/js/services/profileService.js
+++ b/src/js/services/profileService.js
@@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services')
- .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, pushNotificationsService, gettext, gettextCatalog, bwcError, uxLanguage, platformInfo, $ionicHistory, txFormatService, $state) {
+ .factory('profileService', function profileServiceFactory($rootScope, $timeout, $filter, $log, sjcl, lodash, storageService, bwcService, configService, pushNotificationsService, gettext, gettextCatalog, bwcError, uxLanguage, platformInfo, txFormatService, $state) {
var isChromeApp = platformInfo.isChromeApp;
@@ -38,6 +38,22 @@ angular.module('copayApp.services')
});
}
+ root.setBackupNeededModalFlag = function(walletId) {
+ storageService.setBackupNeededModalFlag(walletId, true, function(err) {
+ if (err) $log.error(err);
+ $log.debug('Backup warning modal flag stored');
+ root.wallet[walletId].showBackupNeededModal = false;
+ });
+ };
+
+ function _showBackupNeededModal(wallet, cb) {
+ storageService.getBackupNeededModalFlag(wallet.credentials.walletId, function(err, val) {
+ if (err) $log.error(err);
+ if (val) return cb(false);
+ return cb(true);
+ });
+ };
+
root.setBackupFlag = function(walletId) {
storageService.setBackupFlag(walletId, function(err) {
if (err) $log.error(err);
@@ -101,6 +117,11 @@ angular.module('copayApp.services')
wallet.balanceHidden = val;
});
+ _showBackupNeededModal(wallet, function(val) {
+ if (wallet.needsBackup) wallet.showBackupNeededModal = val;
+ else wallet.showBackupNeededModal = false;
+ });
+
wallet.removeAllListeners();
wallet.on('report', function(n) {
@@ -759,21 +780,11 @@ angular.module('copayApp.services')
var TIME_STAMP = 60 * 60 * 24 * 7;
var MAX = 100;
- var typeFilter1 = {
- 'NewBlock': 1,
- 'BalanceUpdated': 1,
- 'NewOutgoingTxByThirdParty': 1,
- 'NewAddress': 1,
- 'TxProposalFinallyAccepted': 1,
- 'TxProposalFinallyRejected': 1,
+ var typeFilter = {
+ 'NewOutgoingTx': 1,
+ 'NewIncomingTx': 1
};
- var typeFilter2 = {
- 'TxProposalAcceptedBy': 1,
- 'TxProposalRejectedBy': 1,
- 'NewTxProposal': 1,
- }
-
var w = root.getWallets();
if (lodash.isEmpty(w)) return cb();
@@ -874,15 +885,9 @@ angular.module('copayApp.services')
var n;
n = lodash.filter(wallet.cachedActivity.n, function(x) {
- return !typeFilter1[x.type];
+ return typeFilter[x.type];
});
- if (wallet.m == 1) {
- n = lodash.filter(n, function(x) {
- return !typeFilter2[x.type];
- });
- }
-
var idToName = {};
if (wallet.cachedStatus) {
lodash.each(wallet.cachedStatus.wallet.copayers, function(c) {
diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js
index 4df36dab1..a1daeb36e 100644
--- a/src/js/services/storageService.js
+++ b/src/js/services/storageService.js
@@ -365,6 +365,14 @@ angular.module('copayApp.services')
storage.get('receiveTips', cb);
};
+ root.setBackupNeededModalFlag = function(walletId, val, cb) {
+ storage.set('showBackupNeededModal-' + walletId, val, cb);
+ };
+
+ root.getBackupNeededModalFlag = function(walletId, cb) {
+ storage.get('showBackupNeededModal-' + walletId, cb);
+ };
+
root.setAmazonGiftCards = function(network, gcs, cb) {
storage.set('amazonGiftCards-' + network, gcs, cb);
};
diff --git a/src/js/services/swipe.js b/src/js/services/swipe.js
deleted file mode 100644
index 57a210c4c..000000000
--- a/src/js/services/swipe.js
+++ /dev/null
@@ -1,150 +0,0 @@
-'use strict';
-
-/*
- * This is a modification from https://github.com/angular/angular.js/blob/master/src/ngTouch/swipe.js
- */
-
-
-angular.module('copayApp.services')
- .factory('$swipe', [
- function() {
- // The total distance in any direction before we make the call on swipe vs. scroll.
- var MOVE_BUFFER_RADIUS = 10;
-
- var POINTER_EVENTS = {
- 'touch': {
- start: 'touchstart',
- move: 'touchmove',
- end: 'touchend',
- cancel: 'touchcancel'
- }
- };
-
- function getCoordinates(event) {
- var originalEvent = event.originalEvent || event;
- var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
- var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
-
- return {
- x: e.clientX,
- y: e.clientY
- };
- }
-
- function getEvents(pointerTypes, eventType) {
- var res = [];
- angular.forEach(pointerTypes, function(pointerType) {
- var eventName = POINTER_EVENTS[pointerType][eventType];
- if (eventName) {
- res.push(eventName);
- }
- });
- return res.join(' ');
- }
-
- return {
- /**
- * @ngdoc method
- * @name $swipe#bind
- *
- * @description
- * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
- * object containing event handlers.
- * The pointer types that should be used can be specified via the optional
- * third argument, which is an array of strings `'mouse'` and `'touch'`. By default,
- * `$swipe` will listen for `mouse` and `touch` events.
- *
- * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
- * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
- *
- * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is
- * watching for `touchmove` or `mousemove` events. These events are ignored until the total
- * distance moved in either dimension exceeds a small threshold.
- *
- * Once this threshold is exceeded, either the horizontal or vertical delta is greater.
- * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
- * - If the vertical distance is greater, this is a scroll, and we let the browser take over.
- * A `cancel` event is sent.
- *
- * `move` is called on `mousemove` and `touchmove` after the above logic has determined that
- * a swipe is in progress.
- *
- * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`.
- *
- * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling
- * as described above.
- *
- */
- bind: function(element, eventHandlers, pointerTypes) {
- // Absolute total movement, used to control swipe vs. scroll.
- var totalX, totalY;
- // Coordinates of the start position.
- var startCoords;
- // Last event's position.
- var lastPos;
- // Whether a swipe is active.
- var active = false;
-
- pointerTypes = pointerTypes || ['touch'];
- element.on(getEvents(pointerTypes, 'start'), function(event) {
- startCoords = getCoordinates(event);
- active = true;
- totalX = 0;
- totalY = 0;
- lastPos = startCoords;
- eventHandlers['start'] && eventHandlers['start'](startCoords, event);
- });
- var events = getEvents(pointerTypes, 'cancel');
- if (events) {
- element.on(events, function(event) {
- active = false;
- eventHandlers['cancel'] && eventHandlers['cancel'](event);
- });
- }
-
- element.on(getEvents(pointerTypes, 'move'), function(event) {
- if (!active) return;
-
- // Android will send a touchcancel if it thinks we're starting to scroll.
- // So when the total distance (+ or - or both) exceeds 10px in either direction,
- // we either:
- // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
- // - On totalY > totalX, we let the browser handle it as a scroll.
-
- if (!startCoords) return;
- var coords = getCoordinates(event);
-
- totalX += Math.abs(coords.x - lastPos.x);
- totalY += Math.abs(coords.y - lastPos.y);
-
- lastPos = coords;
-
- if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
- return;
- }
-
- // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
- if (totalY > totalX) {
- // Allow native scrolling to take over.
- active = false;
- eventHandlers['cancel'] && eventHandlers['cancel'](event);
- return;
- } else {
-
- // Prevent the browser from scrolling.
- event.preventDefault();
- eventHandlers['move'] && eventHandlers['move'](coords, event);
- }
- });
-
- element.on(getEvents(pointerTypes, 'end'), function(event) {
- if (!active) return;
- active = false;
- eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
- });
- }
- };
- }
-]);
-
-
diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js
index 483924dd5..a34b210d3 100644
--- a/src/js/services/walletService.js
+++ b/src/js/services/walletService.js
@@ -792,29 +792,16 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
root.getAddress = function(wallet, forceNew, cb) {
- var firstStep;
- if (forceNew) {
- firstStep = storageService.clearLastAddress;
- } else {
- firstStep = function(walletId, cb) {
- return cb();
- };
- }
-
- firstStep(wallet.id, function(err) {
+ storageService.getLastAddress(wallet.id, function(err, addr) {
if (err) return cb(err);
- storageService.getLastAddress(wallet.id, function(err, addr) {
- if (err) return cb(err);
+ if (!forceNew && addr) return cb(null, addr);
- if (addr) return cb(null, addr);
-
- createAddress(wallet, function(err, addr) {
+ createAddress(wallet, function(err, _addr) {
+ if (err) return cb(err, addr);
+ storageService.storeLastAddress(wallet.id, _addr, function() {
if (err) return cb(err);
- storageService.storeLastAddress(wallet.id, addr, function() {
- if (err) return cb(err);
- return cb(null, addr);
- });
+ return cb(null, _addr);
});
});
});
@@ -833,32 +820,12 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
// An alert dialog
var askPassword = function(name, title, cb) {
- var scope = $rootScope.$new(true);
- scope.data = [];
- var pass = $ionicPopup.show({
- template: '',
- title: title,
- subTitle: name,
- scope: scope,
- buttons: [{
- text: 'Cancel'
- }, {
- text: 'OK',
- type: 'button-positive',
- onTap: function(e) {
- if (!scope.data.pass) {
- //don't allow the user to close unless he enters wifi password
- e.preventDefault();
- return;
-
- }
-
- return scope.data.pass;
- }
- }]
- });
- pass.then(function(res) {
- return cb(res);
+ var opts = {
+ inputType: 'password'
+ };
+ popupService.showPrompt(title, name, opts, function(res) {
+ if (!res) return cb();
+ if (res) return cb(res)
});
};
diff --git a/src/sass/common.scss b/src/sass/common.scss
index 40eb910a0..5be328775 100644
--- a/src/sass/common.scss
+++ b/src/sass/common.scss
@@ -4,6 +4,18 @@
@extend .ion-ios-arrow-right;
}
+.icon.nav-item-arrow-down {
+ color: #666;
+ font-size: 26px;
+ @extend .ion-ios-arrow-down;
+}
+
+.icon.nav-item-arrow-up {
+ color: #666;
+ font-size: 26px;
+ @extend .ion-ios-arrow-up;
+}
+
.item.item-heading {
font-weight: bold;
}
@@ -45,6 +57,11 @@
}
}
}
+
+.white-bg{
+ background: #fff;
+}
+
.overlay {
position: absolute;
top:0;
diff --git a/src/sass/main.scss b/src/sass/main.scss
index 61589fabf..c2cb10722 100644
--- a/src/sass/main.scss
+++ b/src/sass/main.scss
@@ -594,6 +594,10 @@ ul.wallet-selection.wallets {
margin-right: 40px;
}
+.m55r {
+ margin-right: 55px;
+}
+
.m25r {
margin-right: 25px;
}
@@ -992,6 +996,7 @@ input[type=number] {
@import "views/tab-send";
@import "views/tab-settings";
@import "views/walletDetails";
+@import "views/advancedSettings";
@import "views/bitpayCard";
@import "views/address-book";
@import "views/wallet-backup-phrase";
diff --git a/src/sass/views/address-book.scss b/src/sass/views/address-book.scss
index fe188c2da..fe3f5834b 100644
--- a/src/sass/views/address-book.scss
+++ b/src/sass/views/address-book.scss
@@ -20,8 +20,6 @@
.item {
color: #444;
border-top: none;
- padding-top: 1.5rem;
- padding-bottom: 1.5rem;
&:before {
display: block;
position: absolute;
diff --git a/src/sass/views/advancedSettings.scss b/src/sass/views/advancedSettings.scss
new file mode 100644
index 000000000..d3da674d9
--- /dev/null
+++ b/src/sass/views/advancedSettings.scss
@@ -0,0 +1,53 @@
+.settings {
+ .item {
+ color: #444;
+ border-color: rgba(221, 221, 221, 0.3);
+ }
+}
+
+#advanced-settings {
+ .list {
+ .item {
+ color: #444;
+ border-top: none;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+ &:before {
+ display: block;
+ position: absolute;
+ width: 100%;
+ height: 1px;
+ background: rgba(221, 221, 221, 0.3);
+ top: 0;
+ right: 0;
+ content: '';
+ }
+ &.item-divider {
+ color: rgba(74, 74, 74, .8);
+ }
+ &.item-heading {
+ &:before {
+ top: 99%
+ }
+ }
+ &:nth-child(2) {
+ &:before {
+ width: 0;
+ }
+ }
+ .item-note {
+ color: rgb(58, 58, 58);
+ }
+ }
+ .comment {
+ padding: 15px;
+ background-color: #fff;
+ color: rgba(74, 74, 74, 0.8);
+ }
+ .divider-comment {
+ padding: 15px;
+ color: rgba(74, 74, 74, 0.8);
+ font-size: 15px;
+ }
+ }
+}
diff --git a/src/sass/views/onboarding/onboard-backup-warning.scss b/src/sass/views/backup-warning.scss
similarity index 89%
rename from src/sass/views/onboarding/onboard-backup-warning.scss
rename to src/sass/views/backup-warning.scss
index af09d351f..ee1017bcc 100644
--- a/src/sass/views/onboarding/onboard-backup-warning.scss
+++ b/src/sass/views/backup-warning.scss
@@ -1,4 +1,4 @@
-#onboarding-backup-warning{
+#backup-warning{
.warning{
margin:4rem auto 1rem;
height: 11rem;
@@ -21,7 +21,7 @@
}
@media (max-width: 400px){
- #onboarding-backup-warning{
+ #backup-warning{
.warning{
margin: 2rem auto 1rem;
height: 8rem;
@@ -45,10 +45,10 @@
}
}
@media (max-height: 540px){
- #onboarding-backup-warning{
+ #backup-warning{
.cta-buttons{
float:left;
position: relative;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/sass/views/confirm.scss b/src/sass/views/confirm.scss
index 1a739bba1..425850d92 100644
--- a/src/sass/views/confirm.scss
+++ b/src/sass/views/confirm.scss
@@ -9,7 +9,7 @@
}
.accept-slide {
position: fixed;
- bottom: 49px;
+ bottom: 0;
width: 100%;
height: 100px;
background-color: #647CE8;
diff --git a/src/sass/views/includes/modals/modals.scss b/src/sass/views/includes/modals/modals.scss
index 63b8af5fe..7c3aca25f 100644
--- a/src/sass/views/includes/modals/modals.scss
+++ b/src/sass/views/includes/modals/modals.scss
@@ -9,7 +9,12 @@
transform: translate(-50%, -50%);
border-radius: .25rem;
&-header {
- background: rgb(1, 209, 162);
+ &-success {
+ background: rgb(1, 209, 162);
+ }
+ &-warning {
+ background: orange;
+ }
padding: 1rem;
border-radius: .25rem .25rem 0 0;
min-height: 120px;
@@ -26,6 +31,12 @@
background-size: contain;
margin-top: .3rem;
}
+ &-img-warning {
+ background-image: url('../img/onboarding-success.svg');
+ height: 6rem;
+ background-size: contain;
+ margin-top: .3rem;
+ }
}
&-content {
padding: .5rem .8rem;
@@ -42,11 +53,16 @@
font-weight: 200;
}
}
- &-content-success{
+ &-content-success {
button{
color:rgb(23, 174, 140) !important;
}
}
+ &-content-warning {
+ button{
+ color: orange !important;
+ }
+ }
}
.modal-backdrop.active {
diff --git a/src/sass/views/includes/modals/screenshot-warning-model.scss b/src/sass/views/includes/modals/screenshot-warning-model.scss
index e979e9ff8..64662f0ef 100644
--- a/src/sass/views/includes/modals/screenshot-warning-model.scss
+++ b/src/sass/views/includes/modals/screenshot-warning-model.scss
@@ -1,7 +1,7 @@
#screenshot-warning-modal{
.popup-modal-header{
&-img{
- background-image: url('../img/onboarding-no-screenshot.svg');
+ background-image: url('../img/no-screenshot.svg');
}
}
-}
\ No newline at end of file
+}
diff --git a/src/sass/views/includes/txp-details.scss b/src/sass/views/includes/txp-details.scss
index 363466c94..28c1d977e 100644
--- a/src/sass/views/includes/txp-details.scss
+++ b/src/sass/views/includes/txp-details.scss
@@ -3,7 +3,7 @@
bottom: 100px;
}
.head {
- padding-bottom: 55px;
+ padding-bottom: 30px;
.sending-label{
line-height: 70px;
font-size: 25px;
diff --git a/src/sass/views/includes/wallets.scss b/src/sass/views/includes/wallets.scss
index 772b08058..57a616a94 100644
--- a/src/sass/views/includes/wallets.scss
+++ b/src/sass/views/includes/wallets.scss
@@ -9,6 +9,7 @@
padding-left:.25rem;
padding-right:.25rem;
border-radius: .25rem;
+ max-width: 350px;
}
.swiper-slide{
width:100% !important;
diff --git a/src/sass/views/notifications.scss b/src/sass/views/notifications.scss
new file mode 100644
index 000000000..a0433cc5d
--- /dev/null
+++ b/src/sass/views/notifications.scss
@@ -0,0 +1,43 @@
+.settings {
+ .item {
+ color: #444;
+ border-color: rgba(221, 221, 221, 0.3);
+ }
+}
+
+#tab-notifications {
+ .list {
+ .item {
+ color: #444;
+ border-top: none;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+ &:before {
+ display: block;
+ position: absolute;
+ width: 100%;
+ height: 1px;
+ background: rgba(221, 221, 221, 0.3);
+ top: 0;
+ right: 0;
+ content: '';
+ }
+ &.item-divider {
+ color: rgba(74, 74, 74, .8);
+ }
+ &.item-heading {
+ &:before {
+ top: 99%
+ }
+ }
+ &:nth-child(2) {
+ &:before {
+ width: 0;
+ }
+ }
+ .item-note {
+ color: rgb(58, 58, 58);
+ }
+ }
+ }
+}
diff --git a/src/sass/views/onboarding/onboard-backup-request.scss b/src/sass/views/onboarding/onboard-backup-request.scss
index 693ebe0bc..c64f0db77 100644
--- a/src/sass/views/onboarding/onboard-backup-request.scss
+++ b/src/sass/views/onboarding/onboard-backup-request.scss
@@ -15,9 +15,14 @@
position: absolute;
bottom: 0;
}
+ @media (min-width: 415px){
+ .warning{
+ height:16rem;
+ }
+ }
}
-@media (max-width: 400px){
+@media (max-width: 399px){
#onboarding-backup-request{
.warning{
margin: 2rem auto 1rem;
@@ -52,7 +57,7 @@
@media (min-height: 980px){
#onboarding-backup-request{
#arrow-down{
- margin-top: 15rem;
+ margin-top: 7rem;
}
}
}
\ No newline at end of file
diff --git a/src/sass/views/onboarding/onboard-collect-email.scss b/src/sass/views/onboarding/onboard-collect-email.scss
index ebe7ad9b4..a6cf4acc4 100644
--- a/src/sass/views/onboarding/onboard-collect-email.scss
+++ b/src/sass/views/onboarding/onboard-collect-email.scss
@@ -80,6 +80,19 @@
font-size:.8rem;
}
}
+ @media (min-width: 415px){
+ &{
+ max-width: 400px;
+ label{
+ .checkbox{
+ left:1rem;
+ }
+ .item-content{
+ font-size: 1rem;
+ }
+ }
+ }
+ }
}
}
}
diff --git a/src/sass/views/onboarding/onboard-disclaimer.scss b/src/sass/views/onboarding/onboard-disclaimer.scss
index feffbb90a..3bf455da5 100644
--- a/src/sass/views/onboarding/onboard-disclaimer.scss
+++ b/src/sass/views/onboarding/onboard-disclaimer.scss
@@ -10,6 +10,10 @@
margin-top:1.5rem;
}
}
+ .list{
+ max-width: 600px;
+ @include center-block();
+ }
.item {
background: transparent;
border: none;
@@ -42,6 +46,7 @@
.item-content {
width: 90%;
margin-left: 6%;
+ white-space: normal;
}
}
.item-checkbox .checkbox {
@@ -54,6 +59,10 @@
position: absolute;
bottom: 0;
width: 100%;
+ &-content{
+ max-width: 600px;
+ @include center-block();
+ }
.item{
color:rgb(58,58,58);
padding-bottom: 2.5rem;
diff --git a/src/sass/views/onboarding/onboard-push-notifications.scss b/src/sass/views/onboarding/onboard-push-notifications.scss
index 1132317e7..30ff9b4a2 100644
--- a/src/sass/views/onboarding/onboard-push-notifications.scss
+++ b/src/sass/views/onboarding/onboard-push-notifications.scss
@@ -1,40 +1,49 @@
-#onboarding-push-notifications{
- h2{
- margin-top:2rem;
+#onboarding-push-notifications {
+ h2 {
+ margin-top: 2rem;
}
- #cta{
+ #cta {
background-image: url('../img/onboarding-push-notifications.svg');
height: 15rem;
margin-top: .75rem;
}
- .cta-buttons{
- float:none;
- bottom:0;
+ .cta-buttons {
+ float: none;
+ bottom: 0;
position: absolute;
- width:100%;
- button{
+ width: 100%;
+ button {
max-width: 400px;
}
}
}
-@media (max-width: 400px){
- #onboarding-push-notifications{
- .cta-buttons{
- float:none;
- bottom:0;
+@media (max-width: 400px) {
+ #onboarding-push-notifications {
+ .cta-buttons {
+ float: none;
+ bottom: 0;
position: absolute;
}
}
}
-@media (max-height: 540px){
- #onboarding-push-notifications{
- #cta{
+
+@media (max-height: 540px) {
+ #onboarding-push-notifications {
+ #cta {
margin-bottom: 0;
}
- .cta-buttons{
- float:left;
+ .cta-buttons {
+ float: left;
position: relative;
}
}
-}
\ No newline at end of file
+}
+
+@media (min-width: 450px) {
+ #onboarding-push-notifications {
+ #cta {
+ height: 26rem;
+ }
+ }
+}
diff --git a/src/sass/views/onboarding/onboarding.scss b/src/sass/views/onboarding/onboarding.scss
index 22cbf9452..da762022a 100644
--- a/src/sass/views/onboarding/onboarding.scss
+++ b/src/sass/views/onboarding/onboarding.scss
@@ -87,17 +87,21 @@
}
}
-@media (min-width: 400px){
+@media (min-width: 415px){
.onboarding{
ion-content{
h2{
- font-size: 1.2rem;
+ font-size: 2rem;
+ }
+ p{
+ font-size: 1.4rem;
+ line-height: 1.9rem;
}
p,h2,h3{
max-width: 600px !important;
}
button{
- max-width: 400px !important;
+ max-width: 400px !important;
}
}
}
@@ -108,6 +112,6 @@
@import "onboard-tour";
@import "onboard-collect-email";
@import "onboard-backup-request";
-@import "onboard-backup-warning";
+@import "../backup-warning";
@import "onboard-disclaimer";
@import "onboard-push-notifications";
diff --git a/src/sass/views/tab-home.scss b/src/sass/views/tab-home.scss
index f75138075..4ce59566b 100644
--- a/src/sass/views/tab-home.scss
+++ b/src/sass/views/tab-home.scss
@@ -26,14 +26,24 @@
top:0;
right:0;
content:'';
+ @media (min-width: 450px){
+ &{
+ width:90%;
+ }
+ }
}
&.item-heading{
&:before{
- width:100%;
+ width:100% !important;
top:99%
}
}
- &:nth-child(2){
+ &:nth-child(1){
+ &:before{
+ width:0;
+ }
+ }
+ &:nth-child(2):last-child{
&:before{
width:0;
}
diff --git a/src/sass/views/tab-receive.scss b/src/sass/views/tab-receive.scss
index aa66bc642..e24ba8739 100644
--- a/src/sass/views/tab-receive.scss
+++ b/src/sass/views/tab-receive.scss
@@ -9,6 +9,20 @@
}
#address {
background: #fff;
+ .incomplete {
+ padding: 50px;
+ .title {
+ padding: 20px;
+ font-size: 25px;
+ color: #444;
+ }
+ .subtitle {
+ padding: 20px;
+ color: #444;
+ }
+ .button {
+ }
+ }
.item {
border: none;
font-size: .8rem;
@@ -29,6 +43,16 @@
}
&-gen-address {}
}
+ .qr {
+ padding: 30px;
+ }
+ .backup {
+ background-color: orange;
+ color: #fff;
+ i {
+ padding: 10px;
+ }
+ }
}
#wallets {
position: relative;
diff --git a/src/sass/views/tab-send.scss b/src/sass/views/tab-send.scss
index bc8664ec0..bd0f19a99 100644
--- a/src/sass/views/tab-send.scss
+++ b/src/sass/views/tab-send.scss
@@ -16,4 +16,11 @@
position: absolute;
top: 10px;
}
+ .show-more {
+ text-align: center;
+ padding: 20px;
+ font-size: 16px;
+ color: #387ef5;
+ font-weight: bold;
+ }
}
diff --git a/src/sass/views/wallet-backup-phrase.scss b/src/sass/views/wallet-backup-phrase.scss
index 0defd9af5..057dea5f0 100644
--- a/src/sass/views/wallet-backup-phrase.scss
+++ b/src/sass/views/wallet-backup-phrase.scss
@@ -84,7 +84,7 @@
}
}
- @media (min-width : 320px) and (max-width : 340px) and (orientation : portrait), (min-width : 650px) and (max-width : 770px) and (orientation : portrait){
+ @media (min-width : 320px) and (max-width : 415px) and (orientation : portrait), (min-width : 650px) and (max-width : 770px) and (orientation : portrait){
#wallet-backup-phrase{
.cta-buttons,#select-phrase{
bottom: 64px;
Preferences
+
+
+ Notifications
+
+
+
Language
@@ -50,43 +56,6 @@
- Exchanges
-
- Others
-
-
-
- Enable push notifications
-
-
-
- Notifications
-
-
-
-
Notifications
-
- Push notifications for Copay are currently disabled. Enable them in the Settings app.
-
-
- Open Settings app
-
- Wallets Preferences
+
+
+ Advanced
+
+
+
diff --git a/public/views/tabs.html b/public/views/tabs.html
index 66d9a2bc5..b1d26e8fc 100644
--- a/public/views/tabs.html
+++ b/public/views/tabs.html
@@ -3,13 +3,13 @@ Create tabs with an icon and label, using the tabs-positive style.
Each tab's child