Merge branch 'wallet/sprint/20' into wallet/task/427

This commit is contained in:
Jean-Baptiste Dominguez 2018-08-09 23:30:12 +09:00 committed by GitHub
commit bc9e1710c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 3580 additions and 796 deletions

View file

@ -21,6 +21,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
$timeout(function() {
var form = addressbookForm;
if (data && form) {
if (data.result) {
data = data.result;
}
data = data.replace(/^bitcoin(cash)?:/, '');
form.address.$setViewValue(data);
form.address.$isValid = true;
@ -36,9 +39,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
addressbook.address = translated.legacy;
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("contact_created", [{
"coin": $scope.addressbookEntry.coin

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
angular.module('copayApp.controllers').controller('addressbookViewController', function($scope, sendFlowService, $state, $timeout, lodash, addressbookService, popupService, $ionicHistory, platformInfo, gettextCatalog, configService, bitcoinCashJsService) {
var config = configService.getSync();
var defaults = configService.getDefaults();
@ -22,6 +22,7 @@ angular.module('copayApp.controllers').controller('addressbookViewController', f
$scope.sendTo = function() {
$ionicHistory.removeBackView();
sendFlowService.clear();
$state.go('tabs.send');
$timeout(function() {
var to = '';
@ -31,12 +32,16 @@ angular.module('copayApp.controllers').controller('addressbookViewController', f
} else {
to = $scope.addressbookEntry.address;
}
$state.transitionTo('tabs.send.amount', {
var stateParams = {
toAddress: to,
toName: $scope.addressbookEntry.name,
toEmail: $scope.addressbookEntry.email,
coin: $scope.addressbookEntry.coin
});
};
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 100);
};

View file

@ -2,7 +2,7 @@
angular.module('copayApp.controllers').controller('amountController', amountController);
function amountController(configService, $filter, gettextCatalog, $ionicHistory, $ionicModal, $ionicScrollDelegate, lodash, $log, nodeWebkitService, rateService, $scope, $state, $timeout, shapeshiftService, txFormatService, platformInfo, profileService, walletService, $window) {
function amountController(configService, $filter, gettextCatalog, $ionicHistory, $ionicModal, $ionicScrollDelegate, lodash, $log, nodeWebkitService, rateService, $scope, $state, $timeout, sendFlowService, shapeshiftService, txFormatService, platformInfo, profileService, walletService, $window) {
var vm = this;
vm.allowSend = false;
@ -29,6 +29,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
vm.finish = finish;
vm.goBack = goBack;
vm.loadMore = loadMore;
vm.next = next;
vm.openPopup = openPopup;
vm.pushDigit = pushDigit;
vm.removeDigit = removeDigit;
@ -66,19 +67,23 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
}
function onBeforeEnter(event, data) {
console.log('amount onBeforeEnter sendflow ', sendFlowService.getState());
if (data.direction == "back") {
sendFlowService.popState();
}
initCurrencies();
passthroughParams = data.stateParams;
console.log('stateParams:', data.stateParams);
passthroughParams = sendFlowService;
vm.fromWalletId = data.stateParams.fromWalletId;
vm.toWalletId = data.stateParams.toWalletId;
vm.minAmount = parseFloat(data.stateParams.minAmount);
vm.maxAmount = parseFloat(data.stateParams.maxAmount);
vm.fromWalletId = passthroughParams.fromWalletId;
vm.toWalletId = passthroughParams.toWalletId;
vm.minAmount = parseFloat(passthroughParams.minAmount);
vm.maxAmount = parseFloat(passthroughParams.maxAmount);
if (passthroughParams.thirdParty) {
vm.thirdParty = JSON.parse(passthroughParams.thirdParty); // Parse stringified JSON-object
vm.thirdParty = passthroughParams.thirdParty; // Parse stringified JSON-object
if (vm.thirdParty) {
if (vm.thirdParty.id === 'shapeshift') {
if (!vm.thirdParty.data) {
@ -90,7 +95,6 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
vm.toWallet = profileService.getWallet(vm.toWalletId);
shapeshiftService.getMarketData(vm.fromWallet.coin, vm.toWallet.coin, function(data) {
console.log(data);
vm.thirdParty.data['minAmount'] = vm.minAmount = parseFloat(data.minimum);
vm.thirdParty.data['maxAmount'] = vm.maxAmount = parseFloat(data.maxLimit);
});
@ -98,7 +102,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
}
}
vm.isRequestingSpecificAmount = !data.stateParams.fromWalletId;
vm.isRequestingSpecificAmount = !passthroughParams.fromWalletId;
var config = configService.getSync().wallet.settings;
@ -179,8 +183,8 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
// currency have preference
var fiatName;
if (data.stateParams.currency) {
fiatCode = data.stateParams.currency;
if (passthroughParams.currency) {
fiatCode = passthroughParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
@ -207,20 +211,11 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
var fromWallet = profileService.getWallet(passthroughParams.fromWalletId);
updateAvailableFundsFromWallet(fromWallet);
}
};
};
}
}
function goBack() {
if (vm.thirdParty && vm.thirdParty.id === 'shapeshift') {
$state.go('tabs.send').then(function() {
$ionicHistory.clearHistory();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.shapeshift');
});
});
} else {
$ionicHistory.goBack();
}
$ionicHistory.goBack();
}
function paste(value) {
@ -229,18 +224,18 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
$timeout(function() {
$scope.$apply();
});
};
}
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
};
}
function sendMax() {
useSendMax = true;
finish();
};
}
function updateUnitUI() {
vm.unit = availableUnits[unitIndex].shortName;
@ -248,7 +243,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
processAmount();
$log.debug('Update unit coin @amount unit:' + vm.unit + " alternativeUnit:" + vm.alternativeUnit);
};
}
function changeUnit() {
@ -269,7 +264,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
updateAvailableFundsStringIfNeeded();
updateUnitUI();
};
}
function pushDigit(digit) {
if (vm.amount && digit != '.') {
@ -293,7 +288,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
vm.amount = (vm.amount + digit).replace('..', '.');
processAmount();
};
}
function pushOperator(operator) {
if (!vm.amount || vm.amount.length == 0) return;
@ -305,18 +300,18 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
} else {
return val.slice(0, -1) + operator;
}
};
};
}
}
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
};
}
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
};
}
function removeDigit() {
vm.amount = (vm.amount).toString().slice(0, -1);
@ -341,7 +336,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
function close() {
altCurrencyModal.remove();
altCurrencyModal = null;
};
}
function processAmount() {
var formatedValue = format(vm.amount);
@ -411,22 +406,22 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
} else {
vm.errorMessage = '';
}
};
}
function processResult(val) {
if (availableUnits[unitIndex].isFiat) return $filter('formatFiatAmount')(val);
else return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
};
}
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
};
}
function toFiat(val) {
if (!rateService.getRate(fiatCode)) return;
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
};
}
function evaluate(val) {
var result;
@ -437,7 +432,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
}
if (!lodash.isFinite(result)) return 0;
return result;
};
}
function format(val) {
if (!val) return;
@ -447,7 +442,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
if (isOperator(lodash.last(val))) result = result.slice(0, -1);
return result.replace('x', '*');
};
}
function finish() {
var unit = availableUnits[unitIndex];
@ -469,23 +464,22 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
};
if (vm.thirdParty) {
confirmData['thirdParty'] = JSON.stringify(this.thirdParty);
confirmData['thirdParty'] = this.thirdParty;
}
console.log('confirmData:', confirmData);
sendFlowService.pushState(confirmData);
if (!confirmData.fromWalletId) {
$state.transitionTo('tabs.paymentRequest.confirm', confirmData);
} else {
$state.transitionTo('tabs.send.review', confirmData);
$scope.useSendMax = null;
}
};
}
// Currency
var next = 10;
var nextCurrencies = 10;
var completeAlternativeList = [];
var popularCurrencyList = [
@ -499,7 +493,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
{isoCode: 'CNY', order: 7},
{isoCode: 'KRW', order: 8},
{isoCode: 'HKD', order: 9},
]
];
function initCurrencies() {
var unusedCurrencyList = [{
@ -544,12 +538,17 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
function loadMore() {
$timeout(function() {
vm.altCurrencyList = completeAlternativeList.slice(0, next);
next += 10;
vm.altCurrencyList = completeAlternativeList.slice(0, nextCurrencies);
nextCurrencies += 10;
vm.listComplete = vm.altCurrencyList.length >= completeAlternativeList.length;
$scope.$broadcast('scroll.infiniteScrollComplete');
}, 100);
};
}
function next() {
useSendMax = false;
vm.finish();
}
function findCurrency(search) {
if (!search) initCurrencies();
@ -562,7 +561,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
$timeout(function() {
$scope.$apply();
});
};
}
function save(newAltCurrency) {
var opts = {
@ -588,26 +587,25 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
updateUnitUI();
close();
});
};
}
function updateAvailableFundsStringIfNeeded() {
if (passthroughParams.fromWalletId && availableSatoshis !== null) {
availableFundsInFiat = '';
vm.availableFunds = availableFundsInCrypto;
var coin = availableUnits[altUnitIndex].isFiat ? availableUnits[unitIndex].id : availableUnits[altUnitIndex].id;
txFormatService.formatAlternativeStr(coin, availableSatoshis, function formatCallback(formatted){
if (formatted) {
availableFundsInFiat = formatted;
$scope.$apply(function() {
if (availableUnits[unitIndex].isFiat) {
if (availableUnits[unitIndex].isFiat) {
var coin = availableUnits[altUnitIndex].id;
txFormatService.formatAlternativeStr(coin, availableSatoshis, function formatCallback(formatted){
if (formatted) {
availableFundsInFiat = formatted;
$scope.$apply(function() {
vm.availableFunds = availableFundsInFiat;
} else {
vm.availableFunds = availableFundsInCrypto;
}
});
}
});
});
}
});
}
}
}
@ -644,5 +642,4 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
vm.availableFunds = availableFundsInCrypto;
}
}
}

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('backupController',
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal, firebaseEventsService) {
function($scope, $timeout, $log, $state, $stateParams, $ionicHistory, lodash, profileService, bwcService, walletService, ongoingProcess, popupService, gettextCatalog, $ionicModal) {
if ($state.current.name == 'onboarding.backup') {
$scope.onboarding = true;
@ -89,7 +89,8 @@ angular.module('copayApp.controllers').controller('backupController',
$scope.setFlow(2);
})
} else {
firebaseEventsService.logEvent('backed_up_wallet');
//firebaseEventsService.logEvent('backed_up_wallet');
openConfirmBackupModal();
}
};

View file

@ -1,11 +1,12 @@
'use strict';
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, gettextCatalog, walletService, platformInfo, lodash, configService, $stateParams, $window, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bitcoinCashJsService, bwcError, txConfirmNotification, externalLinkService, firebaseEventsService, soundService) {
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $timeout, $ionicScrollDelegate, $ionicLoading, ionicToast, addressbookService, gettextCatalog, walletService, platformInfo, lodash, configService, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, feeService, bitcoinCashJsService, bwcError, txConfirmNotification, soundService, clipboardService) {
var countDown = null;
var FEE_TOO_HIGH_LIMIT_PER = 15;
var tx = {};
var lastTxId = "";
// Config Related values
var config = configService.getSync();
@ -25,6 +26,17 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}, 10);
}
$scope.shareTransaction = function() {
var explorerTxUrl = 'https://explorer.bitcoin.com/'+tx.coin+'/tx/'+lastTxId;
if (platformInfo.isCordova) {
var text = 'Take a look at this Bitcoin transaction here: '+explorerTxUrl;
window.plugins.socialsharing.share(text, null, null, null);
} else {
ionicToast.show(gettextCatalog.getString('Copied to clipboard'), 'bottom', false, 3000);
clipboardService.copyToClipboard(explorerTxUrl);
}
};
$scope.showWalletSelector = function() {
$scope.walletSelector = true;
refresh();
@ -652,6 +664,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txConfirmNotification.subscribe(wallet, {
txid: txp.txid
});
lastTxId = txp.txid;
}
}, onSendStatusChange);
};
@ -683,9 +696,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
soundService.play('misc/payment_sent.mp3');
}
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -695,8 +708,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
// Should be removed
firebaseEventsService.logEvent('sent_bitcoin', { coin: $scope.wallet.coin });
$timeout(function() {
$scope.$digest();
}, 100);

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('createController',
function($scope, $rootScope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, storageService, popupService, appConfigService, pushNotificationsService, firebaseEventsService, $ionicNavBarDelegate) {
function($scope, $timeout, $log, lodash, $state, $ionicScrollDelegate, $ionicHistory, profileService, configService, gettextCatalog, ledger, trezor, intelTEE, derivationPathHelper, ongoingProcess, walletService, popupService, appConfigService, pushNotificationsService, $ionicNavBarDelegate) {
/* For compressed keys, m*73 + n*34 <= 496 */
var COPAYER_PAIR_LIMITS = {
@ -268,7 +268,7 @@ angular.module('copayApp.controllers').controller('createController',
}, 100);
}
else {
firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
//firebaseEventsService.logEvent('wallet_created', { coin: opts.coin });
$state.go('tabs.home');
}
}

View file

@ -65,6 +65,14 @@ angular.module('copayApp.controllers').controller('customAmountController', func
var currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$timeout(function () {
$scope.$apply();
});
});
if (currency != 'BTC' && currency != 'BCH') {
// Convert to BTC or BCH
var config = configService.getSync().wallet.settings;

View file

@ -76,9 +76,9 @@ angular.module('copayApp.controllers').controller('preferencesNotificationsContr
emailService.updateEmail(opts);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("settings_email_notification_toggle", [{
"toggle": $scope.emailNotifications.value

View file

@ -4,7 +4,7 @@ angular
.module('copayApp.controllers')
.controller('reviewController', reviewController);
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicLoading, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicModal, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, sendFlowService, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
var vm = this;
vm.buttonText = '';
@ -49,9 +49,10 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
vm.memoExpanded = false;
// Functions
vm.goBack = goBack;
vm.onSuccessConfirm = onSuccessConfirm;
var sendFlowData;
var config = null;
var countDown = null;
var defaults = {};
@ -74,22 +75,22 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
function onBeforeEnter(event, data) {
console.log('walletSelector onBeforeEnter sendflow ', sendFlowService.getState());
defaults = configService.getDefaults();
originWalletId = data.stateParams.fromWalletId;
satoshis = parseInt(data.stateParams.amount, 10);
toAddress = data.stateParams.toAddress;
destinationWalletId = data.stateParams.toWalletId;
sendFlowData = sendFlowService.getState();
originWalletId = sendFlowData.fromWalletId;
satoshis = parseInt(sendFlowData.amount, 10);
toAddress = sendFlowData.toAddress;
destinationWalletId = sendFlowData.toWalletId;
vm.originWallet = profileService.getWallet(originWalletId);
vm.origin.currency = vm.originWallet.coin.toUpperCase();
coin = vm.originWallet.coin;
if (data.stateParams.thirdParty) {
vm.thirdParty = JSON.parse(data.stateParams.thirdParty); // Parse stringified JSON-object
if (vm.thirdParty) {
handleThirdPartyInitIfBip70();
handleThirdPartyInitIfShapeshift();
}
if (sendFlowData.thirdParty) {
vm.thirdParty = sendFlowData.thirdParty;
handleThirdPartyInitIfBip70();
handleThirdPartyInitIfShapeshift();
}
configService.get(function onConfig(err, configCache) {
@ -105,7 +106,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
updateSendAmounts();
getOriginWalletBalance(vm.originWallet);
handleDestinationAsAddress(toAddress, coin);
handleDestinationAsWallet(data.stateParams.toWalletId);
handleDestinationAsWallet(sendFlowData.toWalletId);
createVanityTransaction(data);
});
}
@ -221,10 +222,10 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
// Grab stateParams
tx = {
amount: parseInt(data.stateParams.amount),
sendMax: data.stateParams.sendMax === 'true' ? true : false,
fromWalletId: data.stateParams.fromWalletId,
toAddress: data.stateParams.toAddress,
amount: parseInt(sendFlowData.amount),
sendMax: sendFlowData.sendMax,
fromWalletId: sendFlowData.fromWalletId,
toAddress: sendFlowData.toAddress,
paypro: txPayproData,
feeLevel: configFeeLevel,
@ -241,7 +242,6 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
};
if (data.stateParams.requiredFeeRate) {
vm.usingMerchantFee = true;
tx.feeRate = parseInt(data.stateParams.requiredFeeRate);
@ -251,18 +251,18 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
tx.feeLevel = 'normal';
}
var B = data.stateParams.coin === 'bch' ? bitcoreCash : bitcore;
var B = tx.coin === 'bch' ? bitcoreCash : bitcore;
var networkName;
try {
if (vm.destination.kind === 'wallet') { // This is a wallet-to-wallet transfer
$ionicLoading.show();
ongoingProcess.set('generatingNewAddress', true);
var toWallet = profileService.getWallet(destinationWalletId);
// We need an address to send to, so we ask the walletService to create a new address for the toWallet.
console.log('Getting address for wallet...');
walletService.getAddress(toWallet, true, function onWalletAddress(err, addr) {
console.log('getAddress cb called', err);
$ionicLoading.hide();
ongoingProcess.set('generatingNewAddress', false);
tx.toAddress = addr;
networkName = (new B.Address(tx.toAddress)).network.name;
tx.network = networkName;
@ -395,6 +395,10 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
};
}
function goBack() {
$ionicHistory.goBack();
}
function handleDestinationAsAddress(address, originCoin) {
if (!address) {
return;
@ -403,16 +407,20 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
// Check if the recipient is a contact
addressbookService.get(originCoin + address, function(err, contact) {
if (!err && contact) {
handleDestinationAsContact(contact);
handleDestinationAsAddressOfContact(contact);
} else {
vm.destination.address = address;
if (originCoin === 'bch') {
vm.destination.address = bitcoinCashJsService.readAddress(address).cashaddr;
} else {
vm.destination.address = address;
}
vm.destination.kind = 'address';
}
});
}
function handleDestinationAsContact(contact) {
function handleDestinationAsAddressOfContact(contact) {
vm.destination.kind = 'contact';
vm.destination.name = contact.name;
vm.destination.email = contact.email;
@ -473,27 +481,28 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
vm.destination.color = toWallet.color;
vm.destination.currency = toWallet.coin.toUpperCase();
$ionicLoading.show();
ongoingProcess.set('connectingShapeshift', true);
walletService.getAddress(vm.originWallet, false, function onReturnWalletAddress(err, returnAddr) {
if (err) {
$ionicLoading.hide();
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString());
return;
}
walletService.getAddress(toWallet, false, function onWithdrawalWalletAddress(err, withdrawalAddr) {
if (err) {
$ionicLoading.hide();
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString());
return;
}
shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function onShiftIt(err, shapeshiftData) {
if (err && err != null) {
$ionicLoading.hide();
ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString());
} else {
vm.memoExpanded = !!vm.memo;
vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId;
vm.memoExpanded = !!vm.memo;
tx.toAddress = shapeshiftData.toAddress;
vm.destination.address = toAddress;
vm.destination.kind = 'shapeshift';

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, $state, $interval, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
angular.module('copayApp.controllers').controller('shapeshiftController', function($scope, sendFlowService, $state, $timeout, $ionicHistory, profileService, walletService, popupService, lodash, $ionicNavBarDelegate) {
var walletsBtc = [];
var walletsBch = [];
@ -63,11 +63,22 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
};
$scope.shapeshift = function() {
var params = {
thirdParty: JSON.stringify({id: 'shapeshift'})
var stateParams = {
thirdParty: {
id: 'shapeshift'
}
};
// Starting new send flow, so ensure everything is reset
sendFlowService.clear();
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.send.origin', params);
$ionicHistory.clearHistory();
$state.go('tabs.send').then(function() {
$timeout(function () {
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 60);
});
});
}
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.controllers').controller('tabHomeController',
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, communityService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, sendFlowService, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
var wallet;
var listeners = [];
var notifications = [];
@ -20,7 +20,12 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = '';
$scope.$on("$ionicView.afterEnter", function() {
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
$scope.$on("$ionicView.afterEnter", onAfterEnter);
$scope.$on("$ionicView.leave", onLeave);
function onAfterEnter () {
startupService.ready();
bannerService.getBanner(function (banner) {
@ -28,9 +33,10 @@ angular.module('copayApp.controllers').controller('tabHomeController',
$scope.bannerUrl = banner.url;
$scope.bannerIsLoading = false;
});
});
};
function onBeforeEnter (event, data) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
if (!$scope.homeTip) {
storageService.getHomeTipAccepted(function(error, value) {
$scope.homeTip = (value == 'accepted') ? false : true;
@ -51,9 +57,9 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
});
}
});
};
$scope.$on("$ionicView.enter", function(event, data) {
function onEnter(event, data) {
$ionicNavBarDelegate.showBar(true);
updateAllWallets();
@ -97,26 +103,29 @@ angular.module('copayApp.controllers').controller('tabHomeController',
}
$scope.showServices = true;
pushNotificationsService.init();
firebaseEventsService.init();
$timeout(function() {
$ionicScrollDelegate.resize();
$scope.$apply();
}, 10);
});
});
};
$scope.$on("$ionicView.leave", function(event, data) {
function onLeave (event, data) {
lodash.each(listeners, function(x) {
x();
});
});
};
$scope.createdWithinPastDay = function(time) {
return timeService.withinPastDay(time);
};
$scope.startFreshSend = function() {
sendFlowService.clear();
$state.go('tabs.send');
}
$scope.openExternalLink = function() {
var url = 'https://github.com/Bitcoin-com/Wallet/releases/latest';
var optIn = true;
@ -224,6 +233,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
cb();
}
}
$scope.walletsWithFunds = profileService.getWallets({hasFunds: true});
});
});
};

View file

@ -144,9 +144,9 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
}
$scope.paymentReceivedCoin = $scope.wallet.coin;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@ -232,10 +232,14 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
if (!$scope.wallets[0]) return;
// select first wallet if no wallet selected previously
var selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
var selectedWallet = null;
if (data.stateParams.walletId) { // from walletDetails
selectedWallet = checkSelectedWallet(profileService.getWallet(data.stateParams.walletId), $scope.wallets);
} else {
// select first wallet if no wallet selected previously
selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
}
$scope.onWalletSelect(selectedWallet);
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
listeners = [

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) {
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, sendFlowService, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) {
var clipboardHasAddress = false;
var clipboardHasContent = false;
var originalList;
@ -33,6 +33,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
text = text.substring(0, 200);
}
var stateParams = sendFlowService.getState();
$scope.fromWallet = profileService.getWallet(stateParams.fromWalletId);
$scope.clipboardHasAddress = false;
$scope.clipboardHasContent = false;
if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr
@ -179,14 +182,30 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
}
$log.debug('Got toAddress:' + toAddress + ' | ' + item.name);
var stateParams = sendFlowService.getState();
stateParams.toAddress = toAddress,
stateParams.coin = item.coin;
sendFlowService.pushState(stateParams);
if (!stateParams.fromWalletId) { // If we have no toAddress or fromWallet
$state.transitionTo('tabs.send.origin');
} else {
$state.transitionTo('tabs.send.amount');
}
return $state.transitionTo('tabs.send.origin', {
toAddress: toAddress,
coin: item.coin
});
});
};
$scope.startWalletToWalletTransfer = function() {
console.log('startWalletToWalletTransfer()');
var params = sendFlowService.getState();
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.wallet-to-wallet', {
fromWalletId: sendFlowService.fromWalletId
});
}
// This could probably be enhanced refactoring the routes abstract states
$scope.createWallet = function() {
$state.go('tabs.home').then(function() {
@ -201,6 +220,8 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
};
$scope.$on("$ionicView.beforeEnter", function(event, data) {
console.log(data);
console.log('tab-send onBeforeEnter sendflow ', sendFlowService.getState());
$scope.isIOS = platformInfo.isIOS && platformInfo.isCordova;
$scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false;
@ -215,5 +236,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
});
if (data.direction == "back") {
sendFlowService.clear();
}
});
});
});

View file

@ -16,7 +16,7 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
isoCode: config.wallet.settings.alternativeIsoCode
};
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay === 'crypto' ? gettextCatalog.getString('Cryptocurrency') : gettextCatalog.getString('Fiat');
// TODO move this to a generic service
bitpayAccountService.getAccounts(function(err, data) {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingData, lodash, popupService, gettextCatalog, scannerService) {
angular.module('copayApp.controllers').controller('tabsController', function($rootScope, $log, $scope, $state, $stateParams, $timeout, platformInfo, incomingData, lodash, popupService, gettextCatalog, scannerService, sendFlowService) {
$scope.onScan = function(data) {
if (!incomingData.redir(data)) {
@ -15,6 +15,11 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
};
$scope.startFreshSend = function() {
sendFlowService.clear();
$state.go('tabs.send');
};
$scope.importInit = function() {
$scope.fromOnboarding = $stateParams.fromOnboarding;
$timeout(function() {
@ -23,7 +28,7 @@ angular.module('copayApp.controllers').controller('tabsController', function($ro
};
$scope.chooseScanner = function() {
sendFlowService.clear();
var isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
if (!isWindowsPhoneApp) {

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService) {
angular.module('copayApp.controllers').controller('walletDetailsController', function($scope, $rootScope, $interval, $timeout, $filter, $log, $ionicModal, $ionicPopover, $state, $stateParams, $ionicHistory, profileService, lodash, configService, platformInfo, walletService, txpModalService, externalLinkService, popupService, addressbookService, sendFlowService, storageService, $ionicScrollDelegate, $window, bwcError, gettextCatalog, timeService, feeService, appConfigService, rateService) {
var HISTORY_SHOW_LIMIT = 10;
var currentTxHistoryPage = 0;
@ -12,9 +12,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIOS = platformInfo.isIOS;
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
@ -342,9 +342,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
top = TOP_BALANCE_BUTTON;
}
var amountTop = ((amountScale - 0.7) / 0.7) * top;
if (amountTop < -10) {
amountTop = -10;
var amountTop = ((amountScale - 0.80) / 0.80) * top;
if (amountTop < -2) {
amountTop = -2;
}
if (amountTop > top) {
amountTop = top;
@ -353,6 +353,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var t = amountTop;
$scope.altAmountOpacity = (amountHeight - 100) / 80;
$scope.buttonsOpacity = (amountHeight - 140) / 70;
$window.requestAnimationFrame(function() {
$scope.amountHeight = amountHeight + 'px';
$scope.contentMargin = contentMargin + 'px';
@ -373,6 +374,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
sendFlowService.clear();
configService.whenAvailable(function (config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
@ -469,4 +471,36 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
$scope.goToSend = function() {
sendFlowService.startSend({
fromWalletId: $scope.wallet.id
});
// Go home first so that the Home tab works properly
$state.go('tabs.home').then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.send');
});
};
$scope.goToReceive = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.receive', {
walletId: $scope.wallet.id
});
});
};
$scope.goToBuy = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).then(function () {
$ionicHistory.clearHistory();
$state.go('tabs.buyandsell');
});
};
});

View file

@ -1,13 +1,24 @@
'use strict';
angular.module('copayApp.controllers').controller('walletSelectorController', function($scope, $rootScope, $state, $log, $ionicHistory, configService, gettextCatalog, profileService, txFormatService) {
angular.module('copayApp.controllers').controller('walletSelectorController', function($scope, $rootScope, $state, $log, $ionicHistory, sendFlowService, configService, gettextCatalog, profileService, txFormatService) {
var fromWalletId = '';
var priceDisplayAsFiat = false;
var unitDecimals = 0;
var unitsFromSatoshis = 0;
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.$on("$ionicView.beforeEnter", onBeforeEnter);
$scope.$on("$ionicView.enter", onEnter);
function onBeforeEnter(event, data) {
console.log('walletSelector onBeforeEnter sendflow', sendFlowService.getState());
if (data.direction == "back") {
sendFlowService.popState();
}
var stateParams = sendFlowService.getState();
var config = configService.getSync().wallet.settings;
priceDisplayAsFiat = config.priceDisplay === 'fiat';
unitDecimals = config.unitDecimals;
@ -18,7 +29,7 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer');
break;
case 'tabs.send.destination':
if (data.stateParams.fromWalletId) {
if (stateParams.fromWalletId) {
$scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer');
}
break;
@ -26,10 +37,14 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
// nop
}
$scope.params = $state.params;
$scope.params = sendFlowService;
$scope.coin = false; // Wallets to show (for destination screen or contacts)
$scope.type = data.stateParams && data.stateParams['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
fromWalletId = data.stateParams && data.stateParams.fromWalletId;
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
fromWalletId = $scope.params['fromWalletId'];
if ($scope.type === 'destination' && $scope.params.toAddress) {
$state.transitionTo(getNextStep());
}
if ($scope.params.coin) {
$scope.coin = $scope.params.coin; // Contacts have a coin embedded
@ -41,11 +56,11 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.isPaymentRequest = true;
}
if ($scope.params.thirdParty) {
$scope.thirdParty = JSON.parse($scope.params.thirdParty); // Parse stringified JSON-object
$scope.thirdParty = $scope.params.thirdParty;
}
});
};
$scope.$on("$ionicView.enter", function(event, data) {
function onEnter (event, data) {
configService.whenAvailable(function(config) {
$scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
});
@ -57,7 +72,7 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
prepareWalletLists();
formatRequestedAmount();
});
};
function formatRequestedAmount() {
if ($scope.params.amount) {
@ -90,7 +105,7 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
function getNextStep() {
if ($scope.thirdParty) {
$scope.params.thirdParty = JSON.stringify($scope.thirdParty) // re-stringify JSON-object
$scope.params.thirdParty = $scope.thirdParty
}
if (!$scope.params.toWalletId && !$scope.params.toAddress) { // If we have no toAddress or fromWallet
return 'tabs.send.destination';
@ -178,11 +193,13 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.useWallet = function(wallet) {
var params = sendFlowService.getState();
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
$scope.params['fromWalletId'] = wallet.id;
params.fromWalletId = wallet.id;
} else { // we're on the destination screen, set wallet to send to
$scope.params['toWalletId'] = wallet.id;
params.toWalletId = wallet.id;
}
sendFlowService.pushState(params);
$state.transitionTo(getNextStep(), $scope.params);
};

View file

@ -9,12 +9,12 @@ angular.module('copayApp.directives')
scope: {
isShown: '=slideSuccessShow',
onConfirm: '&slideSuccessOnConfirm',
hideOnConfirm: '=slideSuccessHideOnConfirm'
hideOnConfirm: '=slideSuccessHideOnConfirm',
onShare: '=slideSuccessOnShare',
},
link: function(scope, element, attrs) {
scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
scope.isCordova = platformInfo.isCordova;
scope.hasShareFunction = typeof scope.onShare === 'function';
var elm = element[0];
elm.style.display = 'none';
scope.$watch('isShown', function() {
@ -32,6 +32,9 @@ angular.module('copayApp.directives')
elm.style.display = 'none';
}
};
scope.onShareButtonClick = function() {
scope.onShare();
}
}
};
});

View file

@ -236,7 +236,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.receive', {
url: '/receive',
url: '/receive/:walletId',
views: {
'tab-receive': {
controller: 'tabReceiveController',
@ -287,7 +287,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
*/
.state('tabs.send.amount', {
url: '/amount/:thirdParty/:fromWalletId/:maxAmount/:minAmount/:toWalletId/:toAddress',
url: '/amount',
views: {
'tab-send@tabs': {
controller: 'amountController',
@ -306,7 +306,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.origin', {
url: '/origin/:thirdParty/:amount/:toAddress/:toWalletId/:coin',
url: '/origin',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
@ -315,7 +315,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.destination', {
url: '/destination/:thirdParty/:amount/:fromWalletId',
url: '/destination',
views: {
'tab-send@tabs': {
controller: 'walletSelectorController',
@ -324,7 +324,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.confirm', {
url: '/confirm/:thirdParty/:amount/:fromWalletId/:toWalletId/:toAddress',
url: '/confirm',
views: {
'tab-send@tabs': {
controller: 'confirmController',
@ -1207,7 +1207,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
})
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
.run(function($rootScope, $state, $location, $log, $timeout, startupService, ionicToast, fingerprintService, $ionicHistory, $ionicPlatform, $window, appConfigService, lodash, platformInfo, profileService, uxLanguage, gettextCatalog, openURLService, storageService, scannerService, configService, emailService, /* plugins START HERE => */ buydotbitcoindotcomService, pushNotificationsService, glideraService, amazonService, bitpayCardService, applicationService, mercadoLibreService, rateService) {
$ionicPlatform.ready(function() {
@ -1231,9 +1231,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
configService.whenAvailable(function(config) {
pushNotificationsService.init();
});
//firebaseEventsService.init();
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
// Send a log to test

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('bitcoincomService', function(platformInfo, nextStepsService) {
angular.module('copayApp.services').factory('bitcoincomService', function(gettextCatalog, nextStepsService, platformInfo) {
var root = {};
var credentials = {};
@ -19,42 +19,42 @@ angular.module('copayApp.services').factory('bitcoincomService', function(platfo
var cashGamesItem = {
name: 'games',
title: 'Bitcoin Cash Games',
title: gettextCatalog.getString('Bitcoin Cash Games'),
icon: 'icon-games',
href: 'https://cashgames.bitcoin.com'
};
var newsItem = {
name: 'news',
title: 'News',
title: gettextCatalog.getString('News'),
icon: 'icon-news',
href: 'https://news.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=News'
};
var poolItem = {
name: 'pool',
title: 'Mining Pool',
title: gettextCatalog.getString('Mining Pool'),
icon: 'icon-mining',
href: 'https://pool.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Pool'
};
var toolsItem = {
name: 'tools',
title: 'Tools',
title: gettextCatalog.getString('Tools'),
icon: 'icon-tools',
href: 'https://tools.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Tools'
};
var priceChartItem = {
name: 'pricechart',
title: 'Bitcoin Price Charts',
title: gettextCatalog.getString('Bitcoin Price Charts'),
icon: 'icon-chart',
sref: 'tabs.pricechart',
};
var faucetItem = {
name: 'faucet',
title: 'Free Bitcoin Cash',
title: gettextCatalog.getString('Free Bitcoin Cash'),
icon: 'icon-faucet',
href: 'https://free.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Faucet'
};

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('buyAndSellService', function($log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
angular.module('copayApp.services').factory('buyAndSellService', function(gettextCatalog, $log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
var root = {};
var services = [];
var linkedServices = [];
@ -23,7 +23,7 @@ angular.module('copayApp.services').factory('buyAndSellService', function($log,
if (linkedServices.length == 0) {
servicesService.register({
title: 'Buy Bitcoin',
title: gettextCatalog.getString('Buy Bitcoin'),
name: 'buyandsell',
icon: 'icon-buy-bitcoin2',
sref: 'tabs.buyandsell',

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('clipboardService', function ($http, $log, platformInfo, nodeWebkitService, gettextCatalog, ionicToast, clipboard) {
angular.module('copayApp.services').factory('clipboardService', function ($http, $log, $timeout, platformInfo, nodeWebkitService, gettextCatalog, ionicToast, clipboard) {
var root = {};
root.copyToClipboard = function (data) {
@ -11,10 +11,15 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cordova.plugins.clipboard.copy(data);
} else if (platformInfo.isNW) {
nodeWebkitService.writeToClipboard(data);
} else if (navigator && navigator.clipboard) {
$log.debug("Use navigator clipboard.")
navigator.clipboard.writeText(data).catch(function onClipboardError(err) {
$log.debug("Clipboard writing is not supported in your browser..");
});
} else if (clipboard.supported) {
clipboard.copyText(data);
} else {
// No supported
// Not supported
return;
}
};
@ -26,7 +31,9 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cb(text);
})
} else if (platformInfo.isNW) {
cb(nodeWebkitService.readFromClipboard());
$timeout(function() {
cb(nodeWebkitService.readFromClipboard());
},0);
} else {
navigator.clipboard.readText()
.then(function (text) {

View file

@ -1,5 +1,5 @@
'use strict'
angular.module('copayApp.services').factory('communityService', function(configService, $log, lodash) {
angular.module('copayApp.services').factory('communityService', function(configService, gettextCatalog, $log, lodash) {
var root = {};
var services = [];
@ -37,14 +37,14 @@ angular.module('copayApp.services').factory('communityService', function(configS
var bchRedditItem = {
name: 'bchreddit',
title: 'Bitcoin Cash Reddit',
title: gettextCatalog.getString('Bitcoin Cash Reddit'),
icon: 'icon-reddit-white',
href: 'http://reddit.com/r/btc'
};
var bitcoincomTwitterItem = {
name: 'bitcoincomTwitter',
title: 'Bitcoin.com Twitter',
title: gettextCatalog.getString('Bitcoin.com Twitter'),
icon: 'icon-twitter-white',
href: 'https://twitter.com/BTCTN'
};

View file

@ -1,5 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, $state, $ionicHistory, sjcl, platformInfo, lodash, appConfigService, profileService, configService) {
angular.module('copayApp.services').factory('firebaseEventsService', function firebaseEventsService($log, platformInfo) {
var root = {};
var useEvents = platformInfo.isCordova && !platformInfo.isWP;

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {
angular.module('copayApp.services').factory('incomingData', function($log, $state, $timeout, $ionicHistory, bitcore, bitcoreCash, $rootScope, payproService, scannerService, sendFlowService, appConfigService, popupService, gettextCatalog, bitcoinCashJsService) {
var root = {};
@ -82,7 +82,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
});
// Timeout is required to enable the "Back" button
$timeout(function() {
var params = {};
var params = sendFlowService.getState();
if (amount) {
params.amount = amount;
@ -105,10 +105,11 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
params.thirdParty = [];
params.thirdParty.id = serviceId;
params.thirdParty.data = serviceData;
params.thirdParty = JSON.stringify(params.thirdParty);
$state.transitionTo('tabs.send.amount', params);
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.amount');
} else {
$state.transitionTo('tabs.send.origin', params);
sendFlowService.pushState(params);
$state.transitionTo('tabs.send.origin');
}
}, 100);
}
@ -387,11 +388,13 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
'notify': $state.current.name == 'tabs.send' ? false : true
});
$timeout(function() {
$state.transitionTo('tabs.send.origin', {
var stateParams = {
toAddress: toAddress,
coin: coin,
noPrefix: 1
});
};
sendFlowService.pushState(stateParams);
$state.transitionTo('tabs.send.origin');
}, 100);
}
@ -458,7 +461,8 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
'notify': $state.current.name == 'tabs.send' ? false : true
}).then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.origin', stateParams);
sendFlowService.pushState(stateParams); // Need to do more here
$state.transitionTo('tabs.send.origin');
});
});
}

View file

@ -427,9 +427,9 @@ angular.module('copayApp.services')
}, function(err, secret) {
if (err) return bwcError.cb(err, gettextCatalog.getString('Error creating wallet'), cb);
var channel = "firebase";
if (platformInfo.isNW) {
channel = "ga";
var channel = "ga";
if (platformInfo.isCordova) {
channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_created", [{
"coin": opts.coin

View file

@ -0,0 +1,95 @@
'use strict';
(function(){
angular
.module('copayApp.services')
.factory('sendFlowService', sendFlowService);
function sendFlowService($log) {
var service = {
amount: '',
fromWalletId: '',
sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: '',
previousStates: [],
// Functions
clear: clear,
getState: getState,
map: map,
popState: popState,
pushState: pushState,
startSend: startSend
};
return service;
function clear() {
console.log("sendFlow clear()");
clearCurrent();
service.previousStates = [];
}
function clearCurrent() {
console.log("sendFlow clearCurrent()");
service.amount = '';
service.fromWalletId = '';
service.sendMax = false;
service.thirdParty = null;
service.toAddress = '';
service.toWalletId = '';
}
/**
* Handy for debugging
*/
function getState() {
var currentState = {};
Object.keys(service).forEach(function forCurrentParam(key) {
if (typeof service[key] !== 'function' && key !== 'previousStates') {
currentState[key] = service[key];
}
});
return currentState;
}
/**
* Clears all previous state
*/
function startSend(params) {
console.log('startSend()');
clear();
map(params);
}
function map(params) {
Object.keys(params).forEach(function forNewParam(key) {
service[key] = params[key];
});
};
function popState() {
console.log('sendFlow pop');
if (service.previousStates.length) {
var params = service.previousStates.pop();
clearCurrent();
map(params);
} else {
clear();
}
};
function pushState(params) {
console.log('sendFlow push');
var currentParams = getState();
service.previousStates.push(currentParams);
clearCurrent();
map(params);
};
};
})();

View file

@ -1,7 +1,12 @@
'use strict'
angular.module('copayApp.services').factory('servicesService', function(configService, $log, lodash) {
var root = {};
var services = [];
var services = [{
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
}];
root.register = function(serviceInfo) {
$log.info('Adding Services entry:' + serviceInfo.name);

View file

@ -1,4 +1,5 @@
'use strict';
angular.module('copayApp.services').factory('shapeshiftService', function ($http, $interval, $log, lodash, moment, ongoingProcess, shapeshiftApiService, storageService, configService, incomingData, platformInfo, servicesService) {
var root = {};
root.ShiftState = 'Shift';
@ -136,16 +137,5 @@ angular.module('copayApp.services').factory('shapeshiftService', function ($http
});
};
var servicesItem = {
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
};
var register = function () {
servicesService.register(servicesItem);
};
register();
return root;
});

View file

@ -201,7 +201,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency
if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') {
if (currency && currency.toUpperCase() != 'BCH' && currency.toUpperCase() != 'BTC' && currency != 'sat') {
amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0);
} else if (currency == 'sat') {

View file

@ -343,21 +343,19 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (err) return cb(err);
if (!txsFromServer.length)
return cb();
return cb(null, []);
var res = lodash.takeWhile(txsFromServer, function(tx) {
return tx.txid != endingTxid;
});
return cb(null, res, res.length >= limit);
return cb(null, txsFromServer);
});
};
var removeAndMarkSoftConfirmedTx = function(txs) {
return lodash.filter(txs, function(tx) {
if (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT)
return tx;
tx.recent = true;
var isConfirm = (tx.confirmations >= root.SOFT_CONFIRMATION_LIMIT);
if (!isConfirm) {
tx.recent = true;
}
return isConfirm;
});
}
@ -437,12 +435,14 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null;
var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null;
$log.debug('Confirmed TXs. Got:' + confirmedTxs.length + '/' + txsFromLocal.length);
// First update
progressFn(txsFromLocal, 0);
wallet.completeHistory = txsFromLocal;
function getNewTxs(newTxs, skip, next) {
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res, shouldContinue) {
getTxsFromServer(wallet, skip, endingTxid, requestLimit, function(err, res) {
if (err) {
$log.warn(bwcError.msg(err, 'Server Error')); //TODO
if (err instanceof errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) {
@ -454,7 +454,22 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
return next(err);
}
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(res)));
// Check if new txs are founds, if yes, lets investigate in the 50 next
// To be sure we are not missing txs by sorting (maybe a new tx is after the "endingTxid"
var newDiscoveredTxs = res.filter(function (x) {
return confirmedTxs.filter(function (confX) {
return confX.txid == x.txid;
}).length == 0;
});
$log.debug('Discovering TXs. Got:' + newDiscoveredTxs.length);
var shouldContinue = newDiscoveredTxs.length > 0;
// If no new tx, no need to check
if (shouldContinue) {
newTxs = newTxs.concat(processNewTxs(wallet, lodash.compact(newDiscoveredTxs)));
}
progressFn(newTxs.concat(txsFromLocal), newTxs.length);

View file

@ -55,6 +55,7 @@
.button {
border-radius: 6px;
&.button-full {
border-radius: 0;
display: block;
}
&-green {
@ -72,5 +73,17 @@
&.activated {
color: #FFF;
}
&-outline {
@include button-style(transparent, #FFFFFF, #FAFAFA, #FFF, #FFFFFF);
@include button-outline(#FFFFFF);
background: none;
box-shadow: none;
}
}
&-grey-outline {
@include button-style(transparent, #727272, #FAFAFA, #727272, #727272);
@include button-outline(#727272);
background: none;
box-shadow: none;
}
}

View file

@ -5,8 +5,8 @@ qrcode {
content: "";
background-size: 100% 100%;
display: block;
left: 88px;
margin-top: 88px;
left: calc(50% - 22px);
margin-top: calc(50% - 22px);
width: 44px;
height: 44px;
position:absolute;

View file

@ -233,6 +233,10 @@ input[type=number] {
font-size: 24px;
}
.size-25 {
font-size: 25px;
}
.size-28 {
font-size: 28px;
}
@ -464,3 +468,7 @@ input[type=file] {
.white-space-initial {
white-space: initial;
}
.height-spacer {
height: 15px;
}

View file

@ -26,16 +26,10 @@
height: 100%;
.qr-code {
text-align: center;
margin-top: 24vh;
margin-bottom: 7vh;
@media(max-height: 800px) {
margin-top: 18vh;
}
@media(max-height: 700px) {
margin-top: 14vh;
}
@media(max-height: 600px) {
margin-top: 8vh;
margin-top: 6px;
qrcode canvas {
height: 30vh;
max-height: 220px;
}
}
.info {
@ -91,5 +85,34 @@
.address-types {
text-align: center;
}
.amount {
margin-top: 20vh;
margin-bottom: 4vh;
@media(max-height: 800px) {
margin-top: 12vh;
margin-bottom: 6vh;
}
@media(max-height: 700px) {
margin-top: 10vh;
margin-bottom: 4vh;
}
@media(max-height: 600px) {
margin-top: 6vh;
margin-bottom: 2vh;
}
width: 100%;
text-align: center;
//padding-top: 30px;
display: block;
align-items: center;
justify-content: center;
&-alternative {
line-height: 36px;
}
}
}
}

View file

@ -8,6 +8,7 @@ click-to-accept {
.click-to-accept {
&__button.button.button-primary.button-standard {
border-radius: 0;
height: 100%;
max-width: 9999px;
width: 100%;

View file

@ -13,6 +13,9 @@ slide-to-accept {
}
.slide {
.button {
border-radius: 0;
}
&__listener {
height: 100%;
width: 100%;

View file

@ -12,12 +12,6 @@ slide-to-accept-success {
.slide-success {
$duration: 400ms;
&__windows-background {
background: $v-success-bg-color;
height: 100%;
width: 100%;
position: fixed;
}
&__background {
$start-radius: 5;
$scale-factor: 20;
@ -40,9 +34,11 @@ slide-to-accept-success {
&__content {
position: relative;
z-index: 1;
margin-top: -20vh;
margin-top: -10vh;
> img {
width: 45vw;
max-width: 166px;
margin-bottom: 1.8rem;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
@ -59,7 +55,7 @@ slide-to-accept-success {
&__header {
color: #FFFFFF;
font-size: 26px;
font-size: 29px;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
opacity: 0;
@ -72,6 +68,26 @@ slide-to-accept-success {
opacity: 1;
}
}
&__share {
transition: transform $duration ease, opacity $duration ease;
transition-delay: 600ms;
opacity: 0;
margin-top: 15vh;
span {
color: #FFF;
font-size: 22px;
height: 28px;
}
img {
height: 28px;
width: auto;
vertical-align: bottom;
margin-right: 4px;
}
&.reveal {
opacity: 0.79;
}
}
}
&__footer {
@ -98,11 +114,11 @@ slide-to-accept-success {
&__btn {
display: block;
color: #FFFFFF;
font-size: 18px;
font-size: 22px;
font-weight: 600;
letter-spacing: 2.86px;
padding: 1rem 0 1.1rem;
border-top: 1px solid rgba(255, 255, 255, .45);
padding: 2rem 0 2.1rem;
border-top: 1px solid rgba(255, 255, 255, 0.25);
cursor: pointer;
}
}

View file

@ -69,6 +69,30 @@
}
}
}
.buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
margin: 6px auto -12px;
text-align: center;
width: 100%;
>.col {
padding: 5px 10px;
margin-bottom: 0;
}
.button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px;
}
}
.wallet-coin-logo {
vertical-align: middle;
margin-right: 5px;

View file

@ -2,15 +2,15 @@
@extend .deflash-blue;
&-header{
height: 300px;
//height: 300px;
width: 100%;
}
&-contacts {
height: calc(100vh - 300px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
//height: calc(100vh - 300px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
&.ios {
height: calc(100vh - 300px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
//height: calc(100vh - 300px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
}
overflow: scroll;
//overflow: scroll;
}
.input {
@ -223,12 +223,12 @@
}
}
#tab-send-header {
height: 270px;
//height: 270px;
}
#tab-send-contacts {
height: calc(100vh - 270px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
//height: calc(100vh - 270px - 50px - 44px); /* screen size - button container - bottom-tab-menu - header top */
&.ios {
height: calc(100vh - 270px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
//height: calc(100vh - 270px - 50px - 44px - 18px); // Remove the notification-bar height on iOS
}
}
}

View file

@ -135,11 +135,12 @@
&.status-bar {
margin-top: 20px;
margin-top: env(safe-area-inset-top);
}
}
.bar-header {
border: 0;
background: none;
background: rgb(238, 182, 64);
.title, .button {
color: #fff;
}
@ -153,7 +154,7 @@
ion-content {
&.collapsible {
margin-top: 210px;
margin-top: 230px;
}
padding-top: 0;
@ -190,12 +191,38 @@
transform: translateY(100px);
}
}
.send-receive-buttons {
display: flex;
flex-direction: row;
justify-content: space-evenly;
width: 100%;
position: absolute;
bottom: 20px;
>.col {
padding: 5px 10px;
margin-bottom: 0;
}
.button {
border: 2px solid;
border-radius: 47px;
padding: 0 15px 0 15px;
text-align: center;
width: 100%;
max-width: 300px;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px;
}
}
}
.amount {
width: 100%;
text-align: center;
color: #fff;
height: 210px;
height: 230px;
padding-top: 40px;
display: block;
align-items: center;