-
+
Address Book
+
Preferences
diff --git a/src/js/controllers/addressbook.js b/src/js/controllers/addressbook.js
new file mode 100644
index 000000000..d9e136901
--- /dev/null
+++ b/src/js/controllers/addressbook.js
@@ -0,0 +1,56 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('addressbookListController', function($scope, $log, $timeout, addressbookService, lodash, popupService) {
+
+ var contacts;
+
+ $scope.initAddressbook = function() {
+ addressbookService.list(function(err, ab) {
+ if (err) $log.error(err);
+
+ $scope.isEmptyList = lodash.isEmpty(ab);
+
+ contacts = [];
+ lodash.each(ab, function(v, k) {
+ contacts.push({
+ name: lodash.isObject(v) ? v.name : v,
+ address: k,
+ email: lodash.isObject(v) ? v.email : null
+ });
+ });
+
+ $scope.addressbook = lodash.clone(contacts);
+ });
+ };
+
+ $scope.findAddressbook = function(search) {
+ if (!search || search.length < 2) {
+ $scope.addressbook = contacts;
+ $timeout(function() {
+ $scope.$apply();
+ }, 10);
+ return;
+ }
+
+ var result = lodash.filter(contacts, function(item) {
+ var val = item.name;
+ return lodash.includes(val.toLowerCase(), search.toLowerCase());
+ });
+
+ $scope.addressbook = result;
+ };
+
+ $scope.remove = function(addr) {
+ $timeout(function() {
+ addressbookService.remove(addr, function(err, ab) {
+ if (err) {
+ popupService.showAlert(err);
+ return;
+ }
+ $scope.initAddressbook();
+ $scope.$digest();
+ });
+ }, 100);
+ };
+
+});
diff --git a/src/js/controllers/addressbookAdd.js b/src/js/controllers/addressbookAdd.js
new file mode 100644
index 000000000..8d6831076
--- /dev/null
+++ b/src/js/controllers/addressbookAdd.js
@@ -0,0 +1,36 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('addressbookAddController', function($scope, $state, $timeout, addressbookService, popupService) {
+
+ $scope.addressbookEntry = {
+ 'address': '',
+ 'name': '',
+ 'email': ''
+ };
+
+ $scope.onQrCodeScanned = function(data, addressbookForm) {
+ $timeout(function() {
+ var form = addressbookForm;
+ if (data && form) {
+ data = data.replace('bitcoin:', '');
+ form.address.$setViewValue(data);
+ form.address.$isValid = true;
+ form.address.$render();
+ }
+ $scope.$digest();
+ }, 100);
+ };
+
+ $scope.add = function(addressbook) {
+ $timeout(function() {
+ addressbookService.add(addressbook, function(err, ab) {
+ if (err) {
+ popupService.showAlert(err);
+ return;
+ }
+ $state.go('tabs.addressbook');
+ });
+ }, 100);
+ };
+
+});
diff --git a/src/js/controllers/addressbookView.js b/src/js/controllers/addressbookView.js
new file mode 100644
index 000000000..a0064fad4
--- /dev/null
+++ b/src/js/controllers/addressbookView.js
@@ -0,0 +1,37 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, $state, $timeout, $stateParams, lodash, addressbookService, popupService) {
+
+ var address = $stateParams.address;
+
+ if (!address) {
+ $state.go('tabs.addressbook');
+ return;
+ }
+
+ addressbookService.get(address, function(err, obj) {
+ if (err) {
+ popupService.showAlert(err);
+ return;
+ }
+ if (!lodash.isObject(obj)) {
+ var name = obj;
+ obj = {
+ 'name': name,
+ 'address': address,
+ 'email': ''
+ };
+ }
+ $scope.addressbookEntry = obj;
+ });
+
+ $scope.sendTo = function() {
+ $timeout(function() {
+ $state.transitionTo('send.amount', {
+ toAddress: $scope.addressbookEntry.address,
+ toName: $scope.addressbookEntry.name
+ });
+ }, 100);
+ };
+
+});
diff --git a/src/js/controllers/backup.js b/src/js/controllers/backup.js
index cec5dd02f..1cf2cc0ed 100644
--- a/src/js/controllers/backup.js
+++ b/src/js/controllers/backup.js
@@ -1,209 +1,219 @@
'use strict';
angular.module('copayApp.controllers').controller('backupController',
- function($rootScope, $scope, $timeout, $log, $state, $stateParams, $ionicPopup, $ionicModal, $ionicNavBarDelegate, uxLanguage, lodash, fingerprintService, platformInfo, configService, profileService, bwcService, walletService, ongoingProcess, storageService) {
- var wallet = profileService.getWallet($stateParams.walletId);
- $ionicNavBarDelegate.title(wallet.credentials.walletName);
- $scope.n = wallet.n;
- var keys;
+ function($rootScope, $scope, $timeout, $log, $state, $stateParams, $ionicPopup, $ionicNavBarDelegate, uxLanguage, lodash, fingerprintService, platformInfo, configService, profileService, bwcService, walletService, ongoingProcess, storageService, popupService, gettextCatalog, $ionicModal) {
+ var wallet = profileService.getWallet($stateParams.walletId);
+ $ionicNavBarDelegate.title(wallet.credentials.walletName);
+ $scope.n = wallet.n;
+ var keys;
- $scope.credentialsEncrypted = wallet.isPrivKeyEncrypted();
+ $scope.credentialsEncrypted = wallet.isPrivKeyEncrypted();
- var isDeletedSeed = function() {
- if (!wallet.credentials.mnemonic && !wallet.credentials.mnemonicEncrypted)
- return true;
+ var isDeletedSeed = function() {
+ if (!wallet.credentials.mnemonic && !wallet.credentials.mnemonicEncrypted)
+ return true;
- return false;
- };
+ return false;
+ };
- $scope.init = function() {
- $scope.deleted = isDeletedSeed();
- if ($scope.deleted) {
- $log.debug('no mnemonics');
- return;
- }
-
- walletService.getKeys(wallet, function(err, k) {
- if (err || !k) {
- $state.go('wallet.preferences');
+ $scope.init = function() {
+ $scope.deleted = isDeletedSeed();
+ if ($scope.deleted) {
+ $log.debug('no mnemonics');
return;
}
- $scope.credentialsEncrypted = false;
- keys = k;
- $scope.initFlow();
- });
- };
- var shuffledWords = function(words) {
- var sort = lodash.sortBy(words);
-
- return lodash.map(sort, function(w) {
- return {
- word: w,
- selected: false
- };
- });
- };
-
- $scope.initFlow = function() {
- if (!keys) return;
- $scope.viewTitle = "Backup Phrase";
- var words = keys.mnemonic;
-
- $scope.mnemonicWords = words.split(/[\u3000\s]+/);
- $scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords);
- $scope.mnemonicHasPassphrase = wallet.mnemonicHasPassphrase();
- $scope.useIdeograms = words.indexOf("\u3000") >= 0;
- $scope.passphrase = '';
- $scope.customWords = [];
- $scope.step = 1;
- $scope.selectComplete = false;
- $scope.backupError = false;
-
- words = lodash.repeat('x', 300);
- $timeout(function() {
- $scope.$apply();
- }, 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);
- $scope.backupError = true;
-
- $timeout(function() {
- $scope.$apply();
- }, 1);
- };
-
- $scope.closePopup = function(val) {
- if (val) {
- $scope.closeModal();
- if ($stateParams.fromOnboarding) $state.go('onboarding.disclaimer');
- else $state.go('tabs.home')
- } else {
- confirmBackupPopup.close();
- $scope.goToStep(1);
- }
- };
-
- $ionicModal.fromTemplateUrl('views/includes/confirmBackupPopup.html', {
- scope: $scope,
- animation: 'slide-in-up'
- }).then(function(modal) {
- $scope.modal = modal;
- });
- $scope.openModal = function() {
- $scope.modal.show();
- };
- $scope.closeModal = function() {
- $scope.modal.hide();
- };
- // Cleanup the modal when we're done with it!
- $scope.$on('$destroy', function() {
- $scope.modal.remove();
- });
-
- var confirm = function(cb) {
- $scope.backupError = false;
-
- var customWordList = lodash.pluck($scope.customWords, 'word');
-
- if (!lodash.isEqual($scope.mnemonicWords, customWordList)) {
- return cb('Mnemonic string mismatch');
- }
-
- $timeout(function() {
- if ($scope.mnemonicHasPassphrase) {
- var walletClient = bwcService.getClient();
- var separator = $scope.useIdeograms ? '\u3000' : ' ';
- var customSentence = customWordList.join(separator);
- var passphrase = $scope.passphrase || '';
-
- try {
- walletClient.seedFromMnemonic(customSentence, {
- network: wallet.credentials.network,
- passphrase: passphrase,
- account: wallet.credentials.account
- });
- } catch (err) {
- walletClient.credentials.xPrivKey = lodash.repeat('x', 64);
- return cb(err);
+ walletService.getKeys(wallet, function(err, k) {
+ if (err || !k) {
+ $log.error('Could not get keys: ', err);
+ $state.go('wallet.preferences');
+ return;
}
-
- if (walletClient.credentials.xPrivKey.substr(walletClient.credentials.xPrivKey) != keys.xPrivKey) {
- delete walletClient.credentials;
- return cb('Private key mismatch');
- }
- }
-
- profileService.setBackupFlag(wallet.credentials.walletId);
- return cb();
- }, 1);
- };
-
- var finalStep = function() {
- ongoingProcess.set('validatingWords', true);
- confirm(function(err) {
- ongoingProcess.set('validatingWords', false);
- if (err) {
- backupError(err);
- }
- $timeout(function() {
- $scope.openModal();
- return;
- }, 1);
- });
- };
-
- $scope.goToStep = function(n) {
- if (n == 1)
- $scope.initFlow();
- if (n == 2) {
- $scope.step = 2;
- $scope.viewTitle = "Let's verify your backup phrase";
- }
- if (n == 3) {
- if (!$scope.mnemonicHasPassphrase)
- finalStep();
- else
- $scope.step = 3;
- }
- if (n == 4)
- finalStep();
- };
-
- $scope.addButton = function(index, item) {
- var newWord = {
- word: item.word,
- prevIndex: index
+ $scope.credentialsEncrypted = false;
+ keys = k;
+ $scope.initFlow();
+ });
};
- $scope.customWords.push(newWord);
- $scope.shuffledMnemonicWords[index].selected = true;
- $scope.shouldContinue();
- };
- $scope.removeButton = function(index, item) {
- if ($scope.loading) return;
- $scope.customWords.splice(index, 1);
- $scope.shuffledMnemonicWords[item.prevIndex].selected = false;
- $scope.shouldContinue();
- };
+ var shuffledWords = function(words) {
+ var sort = lodash.sortBy(words);
- $scope.shouldContinue = function() {
- if ($scope.customWords.length == $scope.shuffledMnemonicWords.length)
- $scope.selectComplete = true;
- else
+ return lodash.map(sort, function(w) {
+ return {
+ word: w,
+ selected: false
+ };
+ });
+ };
+
+ $scope.initFlow = function() {
+ if (!keys) return;
+
+ var words = keys.mnemonic;
+
+ $scope.mnemonicWords = words.split(/[\u3000\s]+/);
+ $scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords);
+ $scope.mnemonicHasPassphrase = wallet.mnemonicHasPassphrase();
+ $scope.useIdeograms = words.indexOf("\u3000") >= 0;
+ $scope.passphrase = '';
+ $scope.customWords = [];
+ $scope.step = 1;
$scope.selectComplete = false;
- };
+ $scope.backupError = false;
-});
+ words = lodash.repeat('x', 300);
+ $timeout(function() {
+ $scope.$apply();
+ }, 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);
+ $scope.backupError = true;
+
+ $timeout(function() {
+ $scope.$apply();
+ }, 1);
+ };
+
+ $ionicModal.fromTemplateUrl('views/includes/confirmBackupPopup.html', {
+ scope: $scope,
+ animation: 'slide-in-up'
+ }).then(function(modal) {
+ $scope.modal = modal;
+ });
+ $scope.openModal = function() {
+ $scope.modal.show();
+ };
+ $scope.closeModal = function() {
+ $scope.modal.hide();
+ };
+ // Cleanup the modal when we're done with it!
+ $scope.$on('$destroy', function() {
+ $scope.modal.remove();
+ });
+
+ var openPopup = function() {
+
+ if ($scope.backupError) {
+ var title = gettextCatalog.getString('uh oh...');
+ var message = gettextCatalog.getString("It's importante that you write your backup phrase down correctly. If something happens to your wallet, you'll need this backup to recover your money Please review your backup and try again");
+ popupService.showAlert(title, message, function() {
+ $scope.goToStep(1);
+ })
+ }
+ else {
+ $scope.openModal();
+ $scope.closePopup = function() {
+ $scope.closeModal();
+ if ($stateParams.fromOnboarding) $state.go('onboarding.disclaimer');
+ else {
+ $ionicHistory.clearHistory();
+ $state.go('tabs.home')
+ }
+ };
+ }
+ }
+
+ var confirm = function(cb) {
+ $scope.backupError = false;
+
+ var customWordList = lodash.pluck($scope.customWords, 'word');
+
+ if (!lodash.isEqual($scope.mnemonicWords, customWordList)) {
+ return cb('Mnemonic string mismatch');
+ }
+
+ $timeout(function() {
+ if ($scope.mnemonicHasPassphrase) {
+ var walletClient = bwcService.getClient();
+ var separator = $scope.useIdeograms ? '\u3000' : ' ';
+ var customSentence = customWordList.join(separator);
+ var passphrase = $scope.passphrase || '';
+
+ try {
+ walletClient.seedFromMnemonic(customSentence, {
+ network: wallet.credentials.network,
+ passphrase: passphrase,
+ account: wallet.credentials.account
+ });
+ } catch (err) {
+ walletClient.credentials.xPrivKey = lodash.repeat('x', 64);
+ return cb(err);
+ }
+
+ if (walletClient.credentials.xPrivKey.substr(walletClient.credentials.xPrivKey) != keys.xPrivKey) {
+ delete walletClient.credentials;
+ return cb('Private key mismatch');
+ }
+ }
+
+ profileService.setBackupFlag(wallet.credentials.walletId);
+ return cb();
+ }, 1);
+ };
+
+ var finalStep = function() {
+ ongoingProcess.set('validatingWords', true);
+ confirm(function(err) {
+ ongoingProcess.set('validatingWords', false);
+ if (err) {
+ backupError(err);
+ }
+ $timeout(function() {
+ openPopup();
+ return;
+ }, 1);
+ });
+ };
+
+ $scope.goToStep = function(n) {
+ if (n == 1)
+ $scope.initFlow();
+ if (n == 2)
+ $scope.step = 2;
+ if (n == 3) {
+ if (!$scope.mnemonicHasPassphrase)
+ finalStep();
+ else
+ $scope.step = 3;
+ }
+ if (n == 4)
+ finalStep();
+ };
+
+ $scope.addButton = function(index, item) {
+ var newWord = {
+ word: item.word,
+ prevIndex: index
+ };
+ $scope.customWords.push(newWord);
+ $scope.shuffledMnemonicWords[index].selected = true;
+ $scope.shouldContinue();
+ };
+
+ $scope.removeButton = function(index, item) {
+ if ($scope.loading) return;
+ $scope.customWords.splice(index, 1);
+ $scope.shuffledMnemonicWords[item.prevIndex].selected = false;
+ $scope.shouldContinue();
+ };
+
+ $scope.shouldContinue = function() {
+ if ($scope.customWords.length == $scope.shuffledMnemonicWords.length)
+ $scope.selectComplete = true;
+ else
+ $scope.selectComplete = false;
+ };
+
+ });
\ No newline at end of file
diff --git a/src/js/controllers/copayers.js b/src/js/controllers/copayers.js
index b95a22121..2743f800f 100644
--- a/src/js/controllers/copayers.js
+++ b/src/js/controllers/copayers.js
@@ -21,7 +21,7 @@ angular.module('copayApp.controllers').controller('copayersController',
$scope.isCordova = platformInfo.isCordova;
$scope.showDeletePopup = function() {
- popupService.showConfirm(gettextCatalog.getString('Confirm'), gettextCatalog.getString('Are you sure you want to delete this wallet?'), function(res) {
+ popupService.showConfirm(gettextCatalog.getString('Confirm'), gettextCatalog.getString('Are you sure you want to delete this wallet?'), null, null, function(res) {
if (res) deleteWallet();
});
};
diff --git a/src/js/controllers/modals/addressbook.js b/src/js/controllers/modals/addressbook.js
deleted file mode 100644
index ee63c7e75..000000000
--- a/src/js/controllers/modals/addressbook.js
+++ /dev/null
@@ -1,111 +0,0 @@
-'use strict';
-
-angular.module('copayApp.controllers').controller('addressbookModalController', function($scope, $log, $state, $timeout, $ionicPopup, addressbookService, lodash, popupService) {
-
- var contacts;
-
- $scope.initAddressbook = function() {
- addressbookService.list(function(err, ab) {
- if (err) $log.error(err);
-
- $scope.isEmptyList = lodash.isEmpty(ab);
-
- contacts = [];
- lodash.each(ab, function(v, k) {
- contacts.push({
- label: v,
- address: k
- });
- });
-
- $scope.addressbook = lodash.clone(contacts);
- });
- };
-
- $scope.findAddressbook = function(search) {
- if (!search || search.length < 2) {
- $scope.addressbook = contacts;
- $timeout(function() {
- $scope.$apply();
- }, 10);
- return;
- }
-
- var result = lodash.filter(contacts, function(item) {
- var val = item.label;
- return lodash.includes(val.toLowerCase(), search.toLowerCase());
- });
-
- $scope.addressbook = result;
- };
-
- $scope.sendTo = function(item) {
- $scope.closeAddressbookModal();
- $timeout(function() {
- $state.transitionTo('send.amount', { toAddress: item.address, toName: item.label})
- }, 100);
- };
-
- $scope.closeAddressbookModal = function() {
- $scope.cleanAddressbookEntry();
- $scope.addAddressbookEntry = false;
- $scope.addressbookModal.hide();
- };
-
- $scope.onQrCodeScanned = function(data, addressbookForm) {
- $timeout(function() {
- var form = addressbookForm;
- if (data && form) {
- data = data.replace('bitcoin:', '');
- form.address.$setViewValue(data);
- form.address.$isValid = true;
- form.address.$render();
- }
- $scope.$digest();
- }, 100);
- };
-
- $scope.cleanAddressbookEntry = function() {
- $scope.addressbookEntry = {
- 'address': '',
- 'label': ''
- };
- };
-
- $scope.toggleAddAddressbookEntry = function() {
- $scope.cleanAddressbookEntry();
- $scope.addAddressbookEntry = !$scope.addAddressbookEntry;
- };
-
- $scope.add = function(addressbook) {
- $timeout(function() {
- addressbookService.add(addressbook, function(err, ab) {
- if (err) {
- popupService.showAlert(err);
- return;
- }
- $scope.initAddressbook();
- $scope.toggleAddAddressbookEntry();
- $scope.$digest();
- });
- }, 100);
- };
-
- $scope.remove = function(addr) {
- $timeout(function() {
- addressbookService.remove(addr, function(err, ab) {
- if (err) {
- popupService.showAlert(err);
- return;
- }
- $scope.initAddressbook();
- $scope.$digest();
- });
- }, 100);
- };
-
- $scope.$on('$destroy', function() {
- $scope.addressbookModal.remove();
- });
-
-});
diff --git a/src/js/controllers/modals/receiveTips.js b/src/js/controllers/modals/receiveTips.js
new file mode 100644
index 000000000..2297be7a4
--- /dev/null
+++ b/src/js/controllers/modals/receiveTips.js
@@ -0,0 +1,10 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('receiveTipsController', function($scope, $log, storageService) {
+ $scope.close = function() {
+ $log.debug('Receive tips accepted');
+ storageService.setReceiveTipsAccepted(true, function(err) {
+ $scope.receiveTipsModal.hide();
+ });
+ }
+});
diff --git a/src/js/controllers/modals/scanTips.js b/src/js/controllers/modals/scanTips.js
new file mode 100644
index 000000000..a82f70554
--- /dev/null
+++ b/src/js/controllers/modals/scanTips.js
@@ -0,0 +1,11 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('scanTipsController', function($scope, $log, storageService) {
+ $scope.close = function() {
+ $log.debug('Scan tips accepted');
+ storageService.setScanTipsAccepted(true, function(err) {
+ $scope.$emit('TipsModalClosed', function() {});
+ $scope.scanTipsModal.hide();
+ });
+ }
+});
diff --git a/src/js/controllers/modals/scanner.js b/src/js/controllers/modals/scanner.js
index c1bccb708..6616d505a 100644
--- a/src/js/controllers/modals/scanner.js
+++ b/src/js/controllers/modals/scanner.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('scannerController', function($scope, $timeout) {
+angular.module('copayApp.controllers').controller('scannerController', function($scope, $timeout, storageService, $ionicModal, platformInfo) {
// QR code Scanner
var video;
@@ -73,6 +73,35 @@ angular.module('copayApp.controllers').controller('scannerController', function(
};
$scope.init = function() {
+ if (platformInfo.isCordova) scannerInit();
+ else checkTips();
+ };
+
+ function checkTips() {
+ //TODO addapt tips to the new QR plugin (mobile)
+ storageService.getScanTipsAccepted(function(err, accepted) {
+ if (err) $log.warn(err);
+ if (accepted) {
+ scannerInit();
+ return;
+ }
+
+ $timeout(function() {
+ $ionicModal.fromTemplateUrl('views/modals/scan-tips.html', {
+ scope: $scope
+ }).then(function(modal) {
+ $scope.scanTipsModal = modal;
+ $scope.scanTipsModal.show();
+ });
+ }, 1000);
+ });
+ };
+
+ $scope.$on('TipsModalClosed', function(event) {
+ scannerInit();
+ });
+
+ function scannerInit() {
setScanner();
$timeout(function() {
if ($scope.beforeScan) {
diff --git a/src/js/controllers/onboarding/backupRequest.js b/src/js/controllers/onboarding/backupRequest.js
index 8284baafb..01fcfcfcd 100644
--- a/src/js/controllers/onboarding/backupRequest.js
+++ b/src/js/controllers/onboarding/backupRequest.js
@@ -1,22 +1,28 @@
'use strict';
-angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, $ionicPopup) {
+angular.module('copayApp.controllers').controller('backupRequestController', function($scope, $state, $stateParams, $ionicPopup, popupService, gettextCatalog) {
$scope.walletId = $stateParams.walletId;
+
$scope.openPopup = function() {
- var backupLaterPopup = $ionicPopup.show({
- templateUrl: "views/includes/backupLaterPopup.html",
- scope: $scope,
+
+ var title = gettextCatalog.getString('Without a backup, you could lose money');
+ var message = gettextCatalog.getString('If something happens to this device, this app is deleted, or your password forgotten, neither you nor Bitpay can recover your funds');
+ var okText = gettextCatalog.getString('I understand');
+ var cancelText = gettextCatalog.getString('Go back');
+ popupService.showConfirm(title, message, okText, cancelText, function(val) {
+ if (val) {
+ var title = gettextCatalog.getString('Are you sure you want to skip the backup?');
+ var message = gettextCatalog.getString('You can create a backup later from your wallet settings');
+ var okText = gettextCatalog.getString('Yes, skip backup');
+ var cancelText = gettextCatalog.getString('Go back');
+ popupService.showConfirm(title, message, okText, cancelText, function(val) {
+ if (val) {
+ $state.go('onboarding.disclaimer');
+ }
+ });
+ }
});
-
- $scope.goBack = function() {
- backupLaterPopup.close();
- };
-
- $scope.continue = function() {
- backupLaterPopup.close();
- $state.go('onboarding.disclaimer');
- };
}
});
diff --git a/src/js/controllers/onboarding/collectEmail.js b/src/js/controllers/onboarding/collectEmail.js
index 8fcda40f5..6479e0ea8 100644
--- a/src/js/controllers/onboarding/collectEmail.js
+++ b/src/js/controllers/onboarding/collectEmail.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('collectEmailController', function($scope, $state, $stateParams, profileService, configService, walletService, platformInfo) {
+angular.module('copayApp.controllers').controller('collectEmailController', function($scope, $state, $timeout, $stateParams, profileService, configService, walletService, platformInfo) {
var isCordova = platformInfo.isCordova;
var isWP = platformInfo.isWP;
@@ -9,11 +9,7 @@ angular.module('copayApp.controllers').controller('collectEmailController', func
var wallet = profileService.getWallet($stateParams.walletId);
var walletId = wallet.credentials.walletId;
- var config = configService.getSync();
- config.emailFor = config.emailFor || {};
- $scope.email = config.emailFor && config.emailFor[walletId];
-
- $scope.save = function(form) {
+ $scope.save = function() {
var opts = {
emailFor: {}
};
@@ -25,13 +21,32 @@ angular.module('copayApp.controllers').controller('collectEmailController', func
if (err) $log.warn(err);
configService.set(opts, function(err) {
if (err) $log.warn(err);
- if (!usePushNotifications) $state.go('onboarding.backupRequest', {walletId: walletId});
- else $state.go('onboarding.notifications', {walletId: walletId});
+ if (!usePushNotifications) $state.go('onboarding.backupRequest', {
+ walletId: walletId
+ });
+ else $state.go('onboarding.notifications', {
+ walletId: walletId
+ });
});
});
};
+ $scope.confirm = function(emailForm) {
+ if (emailForm.$invalid) return;
+ $scope.confirmation = true;
+ $scope.email = emailForm.email.$modelValue;
+ };
+
+ $scope.cancel = function() {
+ $scope.confirmation = false;
+ $timeout(function() {
+ $scope.$digest();
+ }, 1);
+ };
+
$scope.onboardingMailSkip = function() {
- $state.go('onboarding.backupRequest', {walletId: walletId});
+ $state.go('onboarding.backupRequest', {
+ walletId: walletId
+ });
};
});
diff --git a/src/js/controllers/paperWallet.js b/src/js/controllers/paperWallet.js
index 6393fdc3f..27c784d2f 100644
--- a/src/js/controllers/paperWallet.js
+++ b/src/js/controllers/paperWallet.js
@@ -1,16 +1,31 @@
angular.module('copayApp.controllers').controller('paperWalletController',
- function($scope, $timeout, $log, $ionicModal, $ionicHistory, configService, profileService, $state, addressService, bitcore, ongoingProcess, txFormatService, $stateParams, walletService) {
-
+ function($scope, $timeout, $log, $ionicModal, $ionicHistory, popupService, gettextCatalog, platformInfo, configService, profileService, $state, bitcore, ongoingProcess, txFormatService, $stateParams, walletService) {
var wallet = profileService.getWallet($stateParams.walletId);
var rawTx;
+ $scope.init = function() {
+ $scope.wallet = wallet;
+ $scope.isCordova = platformInfo.isCordova;
+ $scope.needsBackup = wallet.needsBackup;
+ $scope.walletAlias = wallet.name;
+ $scope.walletName = wallet.credentials.walletName;
+ $scope.formData = {};
+ $scope.formData.inputData = null;
+ $scope.scannedKey = null;
+ $scope.balance = null;
+ $scope.balanceSat = null;
+ $scope.scanned = false;
+ $timeout(function() {
+ $scope.$apply();
+ }, 10);
+ };
+
$scope.onQrCodeScanned = function(data) {
- $scope.inputData = data;
+ $scope.formData.inputData = data;
$scope.onData(data);
};
$scope.onData = function(data) {
- $scope.error = null;
$scope.scannedKey = data;
$scope.isPkEncrypted = (data.substring(0, 2) == '6P');
};
@@ -48,7 +63,6 @@ angular.module('copayApp.controllers').controller('paperWalletController',
$scope.scanFunds = function() {
$scope.privateKey = '';
$scope.balanceSat = 0;
- $scope.error = null;
ongoingProcess.set('scanning', true);
$timeout(function() {
@@ -56,12 +70,13 @@ angular.module('copayApp.controllers').controller('paperWalletController',
ongoingProcess.set('scanning', false);
if (err) {
$log.error(err);
- $scope.error = err.message || err.toString();
+ popupService.showAlert(gettextCatalog.getString('Error scanning funds:'), err || err.toString());
} else {
$scope.privateKey = privateKey;
$scope.balanceSat = balance;
var config = configService.getSync().wallet.settings;
$scope.balance = txFormatService.formatAmount(balance) + ' ' + config.unitName;
+ $scope.scanned = true;
}
$scope.$apply();
@@ -70,7 +85,7 @@ angular.module('copayApp.controllers').controller('paperWalletController',
};
function _sweepWallet(cb) {
- addressService.getAddress(wallet.credentials.walletId, true, function(err, destinationAddress) {
+ walletService.getAddress(wallet, true, function(err, destinationAddress) {
if (err) return cb(err);
wallet.buildTxFromPrivateKey($scope.privateKey, destinationAddress, null, function(err, tx) {
@@ -90,18 +105,16 @@ angular.module('copayApp.controllers').controller('paperWalletController',
$scope.sweepWallet = function() {
ongoingProcess.set('sweepingWallet', true);
$scope.sending = true;
- $scope.error = null;
$timeout(function() {
_sweepWallet(function(err, destinationAddress, txid) {
ongoingProcess.set('sweepingWallet', false);
-
+ $scope.sending = false;
if (err) {
- $scope.error = err.message || err.toString();
$log.error(err);
+ popupService.showAlert(gettextCatalog.getString('Error sweeping wallet:'), err || err.toString());
} else {
- var type = walletService.getViewStatus(wallet, txp);
- $scope.openStatusModal(type, txp, function() {
+ $scope.openStatusModal('broadcasted', function() {
$ionicHistory.clearHistory();
$state.go('tabs.home');
});
@@ -111,19 +124,18 @@ angular.module('copayApp.controllers').controller('paperWalletController',
}, 100);
};
- $scope.openStatusModal = function(type, txp, cb) {
+ $scope.openStatusModal = function(type, cb) {
+ $scope.tx = {};
+ $scope.tx.amountStr = $scope.balance;
$scope.type = type;
- $scope.tx = txFormatService.processTx(txp);
$scope.color = wallet.backgroundColor;
$scope.cb = cb;
$ionicModal.fromTemplateUrl('views/modals/tx-status.html', {
- scope: $scope,
- animation: 'slide-in-up'
+ scope: $scope
}).then(function(modal) {
$scope.txStatusModal = modal;
$scope.txStatusModal.show();
});
};
-
});
diff --git a/src/js/controllers/preferencesAdvancedController.js b/src/js/controllers/preferencesAdvancedController.js
new file mode 100644
index 000000000..0af8cf258
--- /dev/null
+++ b/src/js/controllers/preferencesAdvancedController.js
@@ -0,0 +1,10 @@
+'use strict';
+
+angular.module('copayApp.controllers').controller('preferencesAdvancedController', function($scope, $timeout, $stateParams, profileService) {
+ var wallet = profileService.getWallet($stateParams.walletId);
+ $scope.network = wallet.network;
+
+ $timeout(function() {
+ $scope.$apply();
+ }, 1);
+});
diff --git a/src/js/controllers/preferencesBitpayCard.js b/src/js/controllers/preferencesBitpayCard.js
index 8a297c8aa..9e4c9da8a 100644
--- a/src/js/controllers/preferencesBitpayCard.js
+++ b/src/js/controllers/preferencesBitpayCard.js
@@ -5,7 +5,7 @@ angular.module('copayApp.controllers').controller('preferencesBitpayCardControll
$scope.logout = function() {
var title = 'Are you sure you would like to log out of your Bitpay Card account?';
- popupService.showConfirm(title, null, function(res) {
+ popupService.showConfirm(title, null, null, null, function(res) {
if (res) logout();
});
};
diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js
index 8e95a31c1..1ec93fd4b 100644
--- a/src/js/controllers/preferencesDelete.js
+++ b/src/js/controllers/preferencesDelete.js
@@ -10,7 +10,7 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro
$scope.showDeletePopup = function() {
var title = gettextCatalog.getString('Warning!');
var message = gettextCatalog.getString('Are you sure you want to delete this wallet?');
- popupService.showConfirm(title, message, function(res) {
+ popupService.showConfirm(title, message, null, null, function(res) {
if (res) deleteWallet();
});
};
diff --git a/src/js/controllers/preferencesGlidera.js b/src/js/controllers/preferencesGlidera.js
index 86c3516af..16749e66e 100644
--- a/src/js/controllers/preferencesGlidera.js
+++ b/src/js/controllers/preferencesGlidera.js
@@ -23,7 +23,9 @@ angular.module('copayApp.controllers').controller('preferencesGlideraController'
}
$scope.token = glidera.token;
$scope.permissions = glidera.permissions;
- $scope.update({fullUpdate: true});
+ $scope.update({
+ fullUpdate: true
+ });
});
};
@@ -62,7 +64,7 @@ angular.module('copayApp.controllers').controller('preferencesGlideraController'
};
$scope.revokeToken = function() {
- popupService.showConfirm('Glidera', 'Are you sure you would like to log out of your Glidera account?', function(res) {
+ popupService.showConfirm('Glidera', 'Are you sure you would like to log out of your Glidera account?', null, null, function(res) {
if (res) {
glideraService.removeToken(function() {
$timeout(function() {
diff --git a/src/js/controllers/preferencesHistory.js b/src/js/controllers/preferencesHistory.js
index a44f69b36..500a8bd53 100644
--- a/src/js/controllers/preferencesHistory.js
+++ b/src/js/controllers/preferencesHistory.js
@@ -1,10 +1,11 @@
'use strict';
angular.module('copayApp.controllers').controller('preferencesHistory',
- function($scope, $log, $stateParams, $timeout, $ionicNavBarDelegate, gettextCatalog, storageService, $state, $ionicHistory, profileService, lodash) {
+ function($scope, $log, $stateParams, $timeout, $state, $ionicHistory, $ionicNavBarDelegate, gettextCatalog, storageService, platformInfo, profileService, lodash) {
$ionicNavBarDelegate.title(gettextCatalog.getString('Transaction History'));
$scope.wallet = profileService.getWallet($stateParams.walletId);
$scope.csvReady = false;
+ $scope.isCordova = platformInfo.isCordova;
$scope.csvHistory = function(cb) {
var allTxs = [];
diff --git a/src/js/controllers/tab-receive.js b/src/js/controllers/tab-receive.js
index 3a03d090a..187d3822e 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, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService) {
+angular.module('copayApp.controllers').controller('tabReceiveController', function($scope, $timeout, $log, $ionicModal, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService) {
$scope.isCordova = platformInfo.isCordova;
@@ -8,10 +8,27 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.wallets = profileService.getWallets({
onlyComplete: true
});
- $scope.isCordova = platformInfo.isCordova;
$scope.isNW = platformInfo.isNW;
+ $scope.isCordova = platformInfo.isCordova;
+ if (!$scope.isCordova) $scope.checkTips();
}
+ $scope.checkTips = function() {
+ storageService.getReceiveTipsAccepted(function(err, accepted) {
+ if (err) $log.warn(err);
+ if (accepted) return;
+
+ $timeout(function() {
+ $ionicModal.fromTemplateUrl('views/modals/receive-tips.html', {
+ scope: $scope
+ }).then(function(modal) {
+ $scope.receiveTipsModal = modal;
+ $scope.receiveTipsModal.show();
+ });
+ }, 1000);
+ });
+ };
+
$scope.$on('Wallet/Changed', function(event, wallet) {
if (!wallet) {
$log.debug('No wallet provided');
diff --git a/src/js/controllers/tab-send.js b/src/js/controllers/tab-send.js
index de70a0a0a..a9756e008 100644
--- a/src/js/controllers/tab-send.js
+++ b/src/js/controllers/tab-send.js
@@ -1,18 +1,20 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabSendController', function($scope, $ionicModal, $log, $timeout, addressbookService, profileService, lodash, $state, walletService, incomingData ) {
+angular.module('copayApp.controllers').controller('tabSendController', function($scope, $log, $timeout, addressbookService, profileService, lodash, $state, walletService, incomingData ) {
var originalList;
$scope.init = function() {
originalList = [];
- var wallets = profileService.getWallets({onlyComplete: true});
+ var wallets = profileService.getWallets({
+ onlyComplete: true
+ });
lodash.each(wallets, function(v) {
originalList.push({
color: v.color,
- label: v.name,
+ name: v.name,
isWallet: true,
getAddress: function(cb) {
walletService.getAddress(v, false, cb);
@@ -26,16 +28,20 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
var contacts = [];
lodash.each(ab, function(v, k) {
contacts.push({
- label: v,
+ name: lodash.isObject(v) ? v.name : v,
address: k,
getAddress: function(cb) {
- return cb(null,k);
+ return cb(null, k);
},
});
});
originalList = originalList.concat(contacts);
$scope.list = lodash.clone(originalList);
+
+ $timeout(function() {
+ $scope.$apply();
+ }, 1);
});
};
@@ -54,7 +60,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
}
var result = lodash.filter(originalList, function(item) {
- var val = item.label || item.alias || item.name;
+ var val = item.name;
return lodash.includes(val.toLowerCase(), search.toLowerCase());
});
@@ -62,22 +68,16 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.goToAmount = function(item) {
- item.getAddress(function(err,addr){
- if (err|| !addr) {
+ item.getAddress(function(err, addr) {
+ if (err || !addr) {
$log.error(err);
return;
}
- $log.debug('Got toAddress:' + addr + ' | ' + item.label)
- return $state.transitionTo('send.amount', { toAddress: addr, toName: item.label})
- });
- };
-
- $scope.openAddressbookModal = function() {
- $ionicModal.fromTemplateUrl('views/modals/addressbook.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.addressbookModal = modal;
- $scope.addressbookModal.show();
+ $log.debug('Got toAddress:' + addr + ' | ' + item.name);
+ return $state.transitionTo('send.amount', {
+ toAddress: addr,
+ toName: item.name
+ })
});
};
diff --git a/src/js/controllers/tab-settings.js b/src/js/controllers/tab-settings.js
index e4ce0e833..b779d5f87 100644
--- a/src/js/controllers/tab-settings.js
+++ b/src/js/controllers/tab-settings.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.controllers').controller('tabSettingsController', function($scope, $rootScope, $log, $ionicModal, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {
+angular.module('copayApp.controllers').controller('tabSettingsController', function($scope, $rootScope, $log, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {
$scope.init = function() {
@@ -38,17 +38,6 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
$scope.wallets = profileService.getWallets();
};
- $scope.openAddressbookModal = function() {
-
- $ionicModal.fromTemplateUrl('views/modals/addressbook.html', {
- scope: $scope
- }).then(function(modal) {
- $scope.addressbookModal = modal;
- $scope.addressbookModal.show();
- });
- };
-
-
$scope.openSettings = function() {
cordova.plugins.diagnostic.switchToSettings(function() {
$log.debug('switched to settings');
diff --git a/src/js/routes.js b/src/js/routes.js
index e37d8efa2..0c2158085 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -490,6 +490,41 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
+ /*
+ *
+ * Addressbook
+ *
+ */
+
+
+ .state('tabs.addressbook', {
+ url: '/addressbook',
+ views: {
+ 'tab-settings': {
+ templateUrl: 'views/addressbook.html',
+ controller: 'addressbookListController'
+ }
+ }
+ })
+ .state('tabs.addressbook.add', {
+ url: '/add',
+ views: {
+ 'tab-settings@tabs': {
+ templateUrl: 'views/addressbook.add.html',
+ controller: 'addressbookAddController'
+ }
+ }
+ })
+ .state('tabs.addressbook.view', {
+ url: '/view/:address',
+ views: {
+ 'tab-settings@tabs': {
+ templateUrl: 'views/addressbook.view.html',
+ controller: 'addressbookViewController'
+ }
+ }
+ })
+
/*
*
*TO DO
@@ -726,7 +761,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
})
- .run(function($rootScope, $state, $location, $log, $timeout, $ionicHistory, $ionicPlatform, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService) {
+ .run(function($rootScope, $state, $location, $log, $timeout, $ionicHistory, $ionicPlatform, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService) {
uxLanguage.init();
openURLService.init();
@@ -739,21 +774,35 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
cordova.plugins.Keyboard.disableScroll(true);
}
+ window.addEventListener('native.keyboardshow', function() {
+ document.querySelector('div.tabs').style.display = 'none';
+ angular.element(document.querySelector('ion-content.has-tabs')).css('bottom', 0);
+ });
+
+ window.addEventListener('native.keyboardhide', function() {
+ var tabs = document.querySelectorAll('div.tabs');
+ angular.element(tabs[0]).css('display', '');
+ });
+
$ionicPlatform.registerBackButtonAction(function(e) {
- var fromDisclaimer = $ionicHistory.currentStateName().match(/disclaimer/) ? 'true' : '';
- var fromTabs = $ionicHistory.currentStateName().match(/tabs/) ? 'true' : '';
+ var fromWelcome = $ionicHistory.currentStateName().match(/welcome/) ? true : false;
+ var matchHome = $ionicHistory.currentStateName().match(/home/) ? true : false;
+ var matchReceive = $ionicHistory.currentStateName().match(/receive/) ? true : false;
+ var matchSend = $ionicHistory.currentStateName().match(/send/) ? true : false;
+ var matchSettings = $ionicHistory.currentStateName().match(/settings/) ? true : false;
+ var fromTabs = matchHome | matchReceive | matchSend | matchSettings;
- if ($rootScope.backButtonPressedOnceToExit || fromDisclaimer) {
- ionic.Platform.exitApp();
- } else if ($ionicHistory.backView() && !fromTabs) {
+ if ($ionicHistory.backView() && !fromTabs) {
$ionicHistory.goBack();
+ } else if ($rootScope.backButtonPressedOnceToExit || fromWelcome) {
+ ionic.Platform.exitApp();
} else {
$rootScope.backButtonPressedOnceToExit = true;
window.plugins.toast.showShortBottom(gettextCatalog.getString('Press again to exit'));
- setInterval(function() {
+ $timeout(function() {
$rootScope.backButtonPressedOnceToExit = false;
- }, 5000);
+ }, 3000);
}
e.preventDefault();
}, 101);
@@ -782,10 +831,19 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
if (err) {
if (err.message && err.message.match('NOPROFILE')) {
$log.debug('No profile... redirecting');
- $state.transitionTo('onboarding.welcome');
+ $state.go('onboarding.welcome');
} else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
$log.debug('Display disclaimer... redirecting');
- $state.transitionTo('onboarding.disclaimer');
+ storageService.getLastState(function(err, state) {
+ if (err && !state) {
+ $log.error(err);
+ $state.go('onboarding.disclaimer');
+ }
+ else {
+ var state = JSON.parse(state);
+ $state.go(state.name, state.toParams);
+ }
+ })
} else {
throw new Error(err); // TODO
}
@@ -793,7 +851,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
profileService.storeProfileIfDirty();
$log.debug('Profile loaded ... Starting UX.');
- $state.transitionTo('tabs.home');
+ $state.go('tabs.home');
}
});
});
@@ -816,6 +874,9 @@ 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 || {}));
-
+ var state = {};
+ state.name = toState.name;
+ state.toParams = toParams;
+ storageService.setLastState(JSON.stringify(state), function() {});
});
});
diff --git a/src/js/services/addressbookService.js b/src/js/services/addressbookService.js
index 74fe7edcc..edd3237d1 100644
--- a/src/js/services/addressbookService.js
+++ b/src/js/services/addressbookService.js
@@ -3,12 +3,16 @@
angular.module('copayApp.services').factory('addressbookService', function(bitcore, storageService, lodash) {
var root = {};
- root.getLabel = function(addr, cb) {
+ root.get = function(addr, cb) {
storageService.getAddressbook('testnet', function(err, ab) {
- if (ab && ab[addr]) return cb(ab[addr]);
+ if (err) return cb(err);
+ if (ab) ab = JSON.parse(ab);
+ if (ab && ab[addr]) return cb(null, ab[addr]);
- storageService.getAddressbook('livnet', function(err, ab) {
- if (ab && ab[addr]) return cb(ab[addr]);
+ storageService.getAddressbook('livenet', function(err, ab) {
+ if (err) return cb(err);
+ if (ab) ab = JSON.parse(ab);
+ if (ab && ab[addr]) return cb(null, ab[addr]);
return cb();
});
});
@@ -38,7 +42,7 @@ angular.module('copayApp.services').factory('addressbookService', function(bitco
ab = ab || {};
if (lodash.isArray(ab)) ab = {}; // No array
if (ab[entry.address]) return cb('Entry already exist');
- ab[entry.address] = entry.label;
+ ab[entry.address] = entry;
storageService.setAddressbook(network, JSON.stringify(ab), function(err, ab) {
if (err) return cb('Error adding new entry');
root.list(function(err, ab) {
diff --git a/src/js/services/popupService.js b/src/js/services/popupService.js
index c94e6df6a..a510ca153 100644
--- a/src/js/services/popupService.js
+++ b/src/js/services/popupService.js
@@ -10,14 +10,19 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
if (!cb) cb = function() {};
$ionicPopup.alert({
title: title,
- template: message
+ template: message,
+ okType: 'button-clear button-positive'
}).then(cb);
};
- var _ionicConfirm = function(title, message, cb) {
+ var _ionicConfirm = function(title, message, okText, cancelText, cb) {
$ionicPopup.confirm({
title: title,
- template: message
+ template: message,
+ cancelText: cancelText,
+ cancelType: 'button-clear button-positive',
+ okText: okText,
+ okType: 'button-clear button-positive'
}).then(function(res) {
return cb(res);
});
@@ -42,16 +47,16 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
navigator.notification.alert(message, cb, title);
};
- var _cordovaConfirm = function(title, message, cb) {
- var onConfirm = function (buttonIndex) {
+ var _cordovaConfirm = function(title, message, okText, cancelText, cb) {
+ var onConfirm = function(buttonIndex) {
if (buttonIndex == 1) return cb(true);
else return cb(false);
}
- navigator.notification.confirm(message, onConfirm, title);
+ navigator.notification.confirm(message, onConfirm, title, [okText, cancelText]);
};
var _cordovaPrompt = function(title, message, cb) {
- var onPrompt = function (results) {
+ var onPrompt = function(results) {
if (results.buttonIndex == 1) return cb(results.input1);
else return cb();
}
@@ -81,17 +86,19 @@ angular.module('copayApp.services').service('popupService', function($log, $ioni
*
* @param {String} Title
* @param {String} Message
+ * @param {String} okText
+ * @param {String} cancelText
* @param {Callback} Function
* @returns {Callback} OK: true, Cancel: false
*/
- this.showConfirm = function(title, message, cb) {
+ this.showConfirm = function(title, message, okText, cancelText, cb) {
$log.warn(title + ": " + message);
if (isCordova)
- _cordovaConfirm(title, message, cb);
+ _cordovaConfirm(title, message, okText, cancelText, cb);
else
- _ionicConfirm(title, message, cb);
+ _ionicConfirm(title, message, okText, cancelText, cb);
};
/**
diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js
index a498dfb89..4df36dab1 100644
--- a/src/js/services/storageService.js
+++ b/src/js/services/storageService.js
@@ -276,6 +276,13 @@ angular.module('copayApp.services')
storage.remove('nextStep-' + service, cb);
};
+ root.setLastState = function(state, toParams, cb) {
+ storage.set('lastState', state, toParams, cb);
+ };
+
+ root.getLastState = function(cb) {
+ storage.get('lastState', cb);
+ };
root.checkQuota = function() {
var block = '';
@@ -342,6 +349,22 @@ angular.module('copayApp.services')
});
};
+ root.setScanTipsAccepted = function(val, cb) {
+ storage.set('scanTips', val, cb);
+ };
+
+ root.getScanTipsAccepted = function(cb) {
+ storage.get('scanTips', cb);
+ };
+
+ root.setReceiveTipsAccepted = function(val, cb) {
+ storage.set('receiveTips', val, cb);
+ };
+
+ root.getReceiveTipsAccepted = function(cb) {
+ storage.get('receiveTips', cb);
+ };
+
root.setAmazonGiftCards = function(network, gcs, cb) {
storage.set('amazonGiftCards-' + network, gcs, cb);
};
diff --git a/src/js/services/walletService.js b/src/js/services/walletService.js
index 204869c61..d23c8b906 100644
--- a/src/js/services/walletService.js
+++ b/src/js/services/walletService.js
@@ -1023,7 +1023,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
try {
keys = wallet.getKeys(password);
} catch (e) {
- return cb(err);
+ return cb(e);
}
return cb(null, keys);
diff --git a/src/sass/views/onboarding/onboard-backup-request.scss b/src/sass/views/onboarding/onboard-backup-request.scss
index 0ad4d641d..8ed5a36d8 100644
--- a/src/sass/views/onboarding/onboard-backup-request.scss
+++ b/src/sass/views/onboarding/onboard-backup-request.scss
@@ -8,4 +8,50 @@
#arrow-down{
font-size: 4.2rem;
}
+ .cta-buttons{
+ width:100%;
+ float:none;
+ position: absolute;
+ bottom: 0;
+ }
+}
+
+@media (max-width: 400px){
+ #onboarding-backup-request{
+ .warning{
+ margin: 2rem auto 1rem;
+ height: 8rem;
+ }
+ h3{
+ font-size:1.3rem;
+ }
+ p{
+ font-size:.9rem;
+ max-width: 80%;
+ flex: 0 0 80%;
+ }
+ .cta-buttons{
+ float:none;
+ bottom:0;
+ position: absolute;
+ button{
+ max-width: 400px;
+ }
+ }
+ }
+}
+@media (max-height: 540px){
+ #onboarding-backup-request{
+ .cta-buttons{
+ float:left;
+ position: relative;
+ }
+ }
+}
+@media (min-height: 980px){
+ #onboarding-backup-request{
+ #arrow-down{
+ margin-top: 15rem;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/sass/views/onboarding/onboard-backup-warning.scss b/src/sass/views/onboarding/onboard-backup-warning.scss
index 0ee7b5c1b..7eaeacbca 100644
--- a/src/sass/views/onboarding/onboard-backup-warning.scss
+++ b/src/sass/views/onboarding/onboard-backup-warning.scss
@@ -8,4 +8,46 @@
#arrow-down{
font-size: 4.2rem;
}
+ .cta-buttons{
+ float:none;
+ bottom:46px;
+ position: absolute;
+ width:100%;
+ button{
+ max-width: 400px;
+ }
+ }
+}
+
+@media (max-width: 400px){
+ #onboarding-backup-warning{
+ .warning{
+ margin: 2rem auto 1rem;
+ height: 8rem;
+ }
+ h3{
+ font-size:1.3rem;
+ }
+ p{
+ font-size:.9rem;
+ max-width: 80%;
+ flex: 0 0 80%;
+ }
+ .warning-image{
+ height: 11rem;
+ }
+ .cta-buttons{
+ float:none;
+ bottom:46px;
+ position: absolute;
+ }
+ }
+}
+@media (max-height: 540px){
+ #onboarding-backup-warning{
+ .cta-buttons{
+ float:left;
+ position: relative;
+ }
+ }
}
\ 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 125d21a93..ad0be19fb 100644
--- a/src/sass/views/onboarding/onboard-collect-email.scss
+++ b/src/sass/views/onboarding/onboard-collect-email.scss
@@ -14,25 +14,22 @@
margin-top: 1rem;
margin-bottom: 1rem;
}
- .collect-overlay, .bar-overlay {
- animation-name: opacity;
- animation-iteration-count: 1;
- animation-timing-function: ease-in;
- animation-duration: .2s;
- animation-delay: .8s;
- animation-fill-mode: forwards;
- opacity: 0;
- }
- .collect-overlay{
- top:-1px;
- }
- .bar-overlay{
- background: rgba(0, 0, 0, 0.23);
- .button-clear{
- color:#fff;
- min-width: 100%;
- }
- }
+ .collect-overlay {
+ animation-name: opacity;
+ animation-iteration-count: 1;
+ animation-timing-function: ease-in;
+ animation-duration: .2s;
+ animation-delay: .8s;
+ animation-fill-mode: forwards;
+ opacity: 0;
+ button {
+ position: absolute;
+ right: 11px;
+ }
+ }
+ .collect-overlay{
+ top:-1px;
+ }
#collect-email {
opacity: 1;
background: #fff;
@@ -52,10 +49,7 @@
label {
background: rgba(200, 200, 200, 0.20);
height: 3rem;
- margin-top: 0;
- input {
- position: absolute;
- }
+ margin-top:0;
i {
position: absolute;
right: 3%;
@@ -64,6 +58,19 @@
}
}
}
+@media (min-width: 1000px){
+ #onboarding-collect-email{
+ #collect-email{
+ p, form{
+ max-width: 600px;
+ @include center-block();
+ }
+ form{
+ margin-top:.5rem;
+ }
+ }
+ }
+}
@keyframes topBottom {
0% {
diff --git a/src/sass/views/onboarding/onboard-tour.scss b/src/sass/views/onboarding/onboard-tour.scss
index ddb13b75e..b955d6c53 100644
--- a/src/sass/views/onboarding/onboard-tour.scss
+++ b/src/sass/views/onboarding/onboard-tour.scss
@@ -23,6 +23,10 @@
background-position: top;
}
}
+ .cta-button{
+ position: absolute;
+ bottom: 85px;
+ }
}
@media (max-width: 400px){
@@ -34,3 +38,22 @@
}
}
}
+
+@media (min-width: 1000px){
+ #onboard-tour{
+ p, h2, h3{
+ max-width: 600px;
+ }
+ button{
+ max-width: 400px;
+ }
+ #cta{
+ margin: 2rem 0 0;
+ }
+ &-control{
+ #cta{
+ margin-bottom: 2rem;
+ }
+ }
+ }
+}
diff --git a/src/sass/views/onboarding/onboarding.scss b/src/sass/views/onboarding/onboarding.scss
index 0c5522ac3..c84b0e3df 100644
--- a/src/sass/views/onboarding/onboarding.scss
+++ b/src/sass/views/onboarding/onboarding.scss
@@ -81,6 +81,12 @@
h2{
font-size: 1.2rem;
}
+ p,h2,h3{
+ max-width: 600px !important;
+ }
+ button{
+ max-width: 400px !important;
+ }
}
}
}