Wallet/src/js/routes.js

714 lines
18 KiB
JavaScript
Raw Normal View History

2015-03-06 12:00:10 -03:00
'use strict';
2015-05-12 14:56:24 -03:00
var unsupported, isaosp;
2015-03-06 12:00:10 -03:00
if (window && window.navigator) {
var rxaosp = window.navigator.userAgent.match(/Android.*AppleWebKit\/([\d.]+)/);
2015-05-12 14:56:24 -03:00
isaosp = (rxaosp && rxaosp[1] < 537);
2015-03-06 12:00:10 -03:00
if (!window.cordova && isaosp)
unsupported = true;
if (unsupported) {
window.location = '#/unsupported';
}
2015-03-06 12:00:10 -03:00
}
//Setting up route
2016-06-06 12:24:07 -03:00
angular.module('copayApp').config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider, $compileProvider) {
2016-08-18 10:37:08 -03:00
$urlRouterProvider.otherwise('/tabs.home');
2015-03-06 12:00:10 -03:00
2016-08-18 10:37:08 -03:00
$logProvider.debugEnabled(true);
$provide.decorator('$log', ['$delegate', 'platformInfo',
function($delegate, platformInfo) {
var historicLog = historicLogProvider.$get();
2015-04-25 12:37:04 -03:00
2016-08-18 10:37:08 -03:00
['debug', 'info', 'warn', 'error', 'log'].forEach(function(level) {
if (platformInfo.isDevel && level == 'error') return;
2016-08-18 10:37:08 -03:00
var orig = $delegate[level];
$delegate[level] = function() {
if (level == 'error')
console.log(arguments);
2015-05-28 14:55:48 -03:00
2016-08-18 10:37:08 -03:00
var args = Array.prototype.slice.call(arguments);
2016-08-18 10:37:08 -03:00
args = args.map(function(v) {
try {
if (typeof v == 'undefined') v = 'undefined';
if (!v) v = 'null';
if (typeof v == 'object') {
if (v.message)
v = v.message;
else
v = JSON.stringify(v);
}
// Trim output in mobile
if (platformInfo.isCordova) {
v = v.toString();
if (v.length > 3000) {
v = v.substr(0, 2997) + '...';
2015-07-13 13:21:47 -03:00
}
}
2015-04-26 20:13:02 -03:00
} catch (e) {
2016-08-18 10:37:08 -03:00
console.log('Error at log decorator:', e);
v = 'undefined';
2015-04-26 20:13:02 -03:00
}
2016-08-18 10:37:08 -03:00
return v;
});
2015-04-25 12:37:04 -03:00
2016-08-18 10:37:08 -03:00
try {
if (platformInfo.isCordova)
console.log(args.join(' '));
2016-08-18 10:37:08 -03:00
historicLog.add(level, args.join(' '));
orig.apply(null, args);
} catch (e) {
console.log('ERROR (at log decorator):', e, args[0]);
2015-07-29 18:15:37 -03:00
}
2016-08-18 10:37:08 -03:00
};
});
return $delegate;
}
]);
2016-08-17 13:16:06 -03:00
2016-08-18 10:37:08 -03:00
// whitelist 'chrome-extension:' for chromeApp to work with image URLs processed by Angular
// link: http://stackoverflow.com/questions/15606751/angular-changes-urls-to-unsafe-in-extension-page?lq=1
$compileProvider.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|blob|chrome-extension):|data:image\/)/);
2016-08-17 15:23:17 -03:00
2016-08-18 10:37:08 -03:00
$stateProvider
.state('translators', {
url: '/translators',
needProfile: true,
views: {
'main': {
templateUrl: 'views/translators.html'
2015-11-23 12:17:04 -03:00
}
2016-08-18 10:37:08 -03:00
}
})
.state('disclaimer', {
url: '/disclaimer',
needProfile: false,
views: {
'main': {
templateUrl: 'views/disclaimer.html',
Feat/coinbase integration (#4012) * Oauth2 and first view * Connect with Coinbase using mobile * Buy and Sell through Coinbase * Fix buy * Receive and send bitcoin to Coinbase account * Receive bitcoin from Coinbase to Copay * Complete user and account information. Connection errors * Improves error handler * Removes console.log * Coinbase background color. Send to Coinbase form validation * Fix send from different wallet * Send and receive using Coinbase * Pagination activity * Fix Buy and Sell * One option in the sidebar to Buy and Sell * Native balance on Coinbase homepage * Rename receive and send * Auto-close window after authenticate * Reorder * Get payment methods * Fix when token expired * Fix token expired * Integration: sell and send to Coinbase * Store pending transaction before sell * Sell flow completed * Removing files * Fix sell * Fix sell * Fix sell * Sell completed * Buy bitcoin through coinbase * Buy auto * Currency set to USD * Select payment methods. Limits * Removes payment methods from preferences * Fix signs. Tx ordered by updated. Minor fixes * Removes console.log * Improving ux-language things * Fix selectedpaymentmethod if not verified * Set error if tx not found * Price sensitivity. Minor fixes * Adds coinbase api key to gitignore * Coinbase production ready * Fix sell in usd * Bug fixes * New Sensitivity step * Refresh token with a simple click * Refresh token * Refactor * Fix auto reconnect if token expired Signed-off-by: Gustavo Maximiliano Cortez <cmgustavo83@gmail.com> * Fix calls if token expired
2016-04-13 14:08:03 -03:00
}
2016-08-18 10:37:08 -03:00
}
})
.state('wallet', {
url: '/wallet/{walletId}',
abstract: true,
needProfile: true,
views: {
'main': {
template: '<ui-view/>',
},
},
})
.state('wallet.details', {
url: '/details',
templateUrl: 'views/walletDetails.html',
needProfile: true
})
.state('wallet.preferences', {
url: '/preferences',
templateUrl: 'views/preferences.html',
needProfile: true
})
.state('wallet.preferencesAlias', {
url: '/preferencesAlias',
templateUrl: 'views/preferencesAlias.html',
needProfile: true
})
.state('wallet.preferencesColor', {
url: '/preferencesColor',
templateUrl: 'views/preferencesColor.html',
needProfile: true
})
.state('wallet.preferencesEmail', {
url: '/preferencesEmail',
templateUrl: 'views/preferencesEmail.html',
needProfile: true
})
.state('wallet.backup', {
url: '/backup',
templateUrl: 'views/backup.html',
needProfile: true
})
.state('wallet.preferencesAdvanced', {
url: '/preferencesAdvanced',
templateUrl: 'views/preferencesAdvanced.html',
needProfile: true
})
.state('wallet.information', {
url: '/information',
templateUrl: 'views/preferencesInformation.html',
needProfile: true
})
.state('wallet.export', {
url: '/export',
templateUrl: 'views/export.html',
needProfile: true
})
.state('wallet.preferencesBwsUrl', {
url: '/preferencesBwsUrl',
templateUrl: 'views/preferencesBwsUrl.html',
needProfile: true
})
.state('wallet.preferencesHistory', {
url: '/preferencesHistory',
templateUrl: 'views/preferencesHistory.html',
needProfile: true
})
.state('wallet.deleteWords', {
url: '/deleteWords',
templateUrl: 'views/preferencesDeleteWords.html',
needProfile: true
})
.state('wallet.delete', {
url: '/delete',
templateUrl: 'views/preferencesDeleteWallet.html',
needProfile: true
})
.state('wallet.copayers', {
url: '/copayers',
needProfile: true,
cache: false,
templateUrl: 'views/copayers.html'
})
// OLD
// .state('walletHome', {
// url: '/old',
// needProfile: true,
// views: {
// 'main': {
// templateUrl: 'views/walletHome.html',
// },
// }
// })
.state('tabs', {
url: '/tabs',
cache: false,
needProfile: true,
abstract: true,
views: {
'main': {
templateUrl: 'views/tabs.html',
},
}
})
.state('tabs.home', {
url: '/home',
cache: false,
needProfile: true,
views: {
'tab-home': {
templateUrl: 'views/tab-home.html',
},
}
})
.state('tabs.receive', {
url: '/receive',
cache: false,
needProfile: true,
views: {
'tab-receive': {
templateUrl: 'views/tab-receive.html',
},
}
})
.state('tabs.scan', {
url: '/scan',
needProfile: true,
views: {
'tab-scan': {
templateUrl: 'views/tab-scan.html',
},
}
})
.state('tabs.send', {
url: '/send',
cache: false,
needProfile: true,
views: {
'tab-send': {
templateUrl: 'views/tab-send.html',
},
}
})
.state('tabs.settings', {
url: '/settings',
needProfile: true,
views: {
'tab-settings': {
templateUrl: 'views/tab-settings.html',
},
}
})
.state('amount', {
cache: false,
url: '/amount:/:toAddress/:toName',
needProfile: true,
views: {
'main': {
templateUrl: 'views/amount.html',
},
},
})
.state('confirm', {
cache: false,
url: '/confirm/:toAddress/:toName/:toAmount',
needProfile: true,
views: {
'main': {
templateUrl: 'views/confirm.html',
},
},
})
.state('unsupported', {
url: '/unsupported',
needProfile: false,
views: {
'main': {
templateUrl: 'views/unsupported.html'
}
}
})
.state('uri', {
url: '/uri/:url',
needProfile: true,
views: {
'main': {
templateUrl: 'views/uri.html'
Feat/coinbase integration (#4012) * Oauth2 and first view * Connect with Coinbase using mobile * Buy and Sell through Coinbase * Fix buy * Receive and send bitcoin to Coinbase account * Receive bitcoin from Coinbase to Copay * Complete user and account information. Connection errors * Improves error handler * Removes console.log * Coinbase background color. Send to Coinbase form validation * Fix send from different wallet * Send and receive using Coinbase * Pagination activity * Fix Buy and Sell * One option in the sidebar to Buy and Sell * Native balance on Coinbase homepage * Rename receive and send * Auto-close window after authenticate * Reorder * Get payment methods * Fix when token expired * Fix token expired * Integration: sell and send to Coinbase * Store pending transaction before sell * Sell flow completed * Removing files * Fix sell * Fix sell * Fix sell * Sell completed * Buy bitcoin through coinbase * Buy auto * Currency set to USD * Select payment methods. Limits * Removes payment methods from preferences * Fix signs. Tx ordered by updated. Minor fixes * Removes console.log * Improving ux-language things * Fix selectedpaymentmethod if not verified * Set error if tx not found * Price sensitivity. Minor fixes * Adds coinbase api key to gitignore * Coinbase production ready * Fix sell in usd * Bug fixes * New Sensitivity step * Refresh token with a simple click * Refresh token * Refactor * Fix auto reconnect if token expired Signed-off-by: Gustavo Maximiliano Cortez <cmgustavo83@gmail.com> * Fix calls if token expired
2016-04-13 14:08:03 -03:00
}
2016-08-18 10:37:08 -03:00
}
})
.state('uripayment', {
url: '/uri-payment/:url',
templateUrl: 'views/paymentUri.html',
views: {
'main': {
templateUrl: 'views/paymentUri.html',
},
},
needProfile: true
})
.state('join', {
url: '/join',
needProfile: true,
views: {
'main': {
templateUrl: 'views/join.html'
},
}
})
.state('import', {
url: '/import',
needProfile: true,
views: {
'main': {
templateUrl: 'views/import.html'
},
}
})
.state('create', {
url: '/create',
templateUrl: 'views/create.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/create.html'
},
}
})
.state('preferencesLanguage', {
url: '/preferencesLanguage',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesLanguage.html'
},
}
})
.state('preferencesUnit', {
url: '/preferencesUnit',
templateUrl: 'views/preferencesUnit.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesUnit.html'
},
}
})
.state('preferencesFee', {
url: '/preferencesFee',
templateUrl: 'views/preferencesFee.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesFee.html'
},
}
})
.state('uriglidera', {
url: '/uri-glidera/:url',
needProfile: true,
views: {
'main': {
templateUrl: 'views/glideraUri.html'
},
}
})
.state('glidera', {
url: '/glidera',
needProfile: true,
views: {
'main': {
templateUrl: 'views/glidera.html'
},
}
})
.state('buyGlidera', {
url: '/buy',
needProfile: true,
views: {
'main': {
templateUrl: 'views/buyGlidera.html'
},
}
})
.state('sellGlidera', {
url: '/sell',
needProfile: true,
views: {
'main': {
templateUrl: 'views/sellGlidera.html'
},
}
})
.state('preferencesGlidera', {
url: '/preferencesGlidera',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesGlidera.html'
},
}
})
.state('bitpayCard', {
url: '/bitpay-card',
needProfile: true,
views: {
'main': {
templateUrl: 'views/bitpayCard.html'
},
}
})
.state('preferencesBitpayCard', {
url: '/preferences-bitpay-card',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesBitpayCard.html'
},
}
})
.state('coinbase', {
url: '/coinbase',
needProfile: true,
views: {
'main': {
templateUrl: 'views/coinbase.html'
},
}
})
.state('preferencesCoinbase', {
url: '/preferencesCoinbase',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesCoinbase.html'
},
}
})
.state('uricoinbase', {
url: '/uri-coinbase/:url',
needProfile: true,
views: {
'main': {
templateUrl: 'views/coinbaseUri.html'
},
}
})
.state('buyCoinbase', {
url: '/buycoinbase',
needProfile: true,
views: {
'main': {
templateUrl: 'views/buyCoinbase.html'
},
}
})
.state('sellCoinbase', {
url: '/sellcoinbase',
needProfile: true,
views: {
'main': {
templateUrl: 'views/sellCoinbase.html'
},
}
})
.state('buyandsell', {
url: '/buyandsell',
needProfile: true,
views: {
'main': {
templateUrl: 'views/buyAndSell.html',
controller: function(platformInfo) {
if (platformInfo.isCordova && StatusBar.isVisible) {
StatusBar.backgroundColorByHexString("#4B6178");
}
}
}
2016-08-18 10:37:08 -03:00
}
})
.state('amazon', {
url: '/amazon',
needProfile: true,
views: {
'main': {
templateUrl: 'views/amazon.html'
},
}
})
.state('buyAmazon', {
url: '/buyamazon',
needProfile: true,
views: {
'main': {
templateUrl: 'views/buyAmazon.html'
},
}
})
.state('preferencesAltCurrency', {
url: '/preferencesAltCurrency',
templateUrl: 'views/preferencesAltCurrency.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesAltCurrency.html'
},
}
})
.state('about', {
url: '/about',
templateUrl: 'views/preferencesAbout.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesAbout.html'
},
}
})
.state('logs', {
url: '/logs',
templateUrl: 'views/preferencesLogs.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesLogs.html'
},
}
})
.state('paperWallet', {
url: '/paperWallet',
templateUrl: 'views/paperWallet.html',
needProfile: true,
views: {
'main': {
templateUrl: 'views/paperWallet.html'
},
}
})
.state('preferencesGlobal', {
url: '/preferencesGlobal',
needProfile: true,
views: {
'main': {
templateUrl: 'views/preferencesGlobal.html',
},
}
})
.state('termOfUse', {
url: '/termOfUse',
needProfile: true,
views: {
'main': {
templateUrl: 'views/termOfUse.html',
},
}
})
.state('add', {
url: '/add',
needProfile: true,
views: {
'main': {
templateUrl: 'views/add.html',
controller: function(platformInfo) {
if (platformInfo.isCordova && StatusBar.isVisible) {
StatusBar.backgroundColorByHexString("#4B6178");
}
}
}
2016-08-18 10:37:08 -03:00
}
});
})
.run(function($rootScope, $state, $location, $log, $timeout, $ionicPlatform, lodash, platformInfo, profileService, uxLanguage, go, gettextCatalog) {
2015-12-10 09:59:56 -03:00
2016-06-23 16:18:18 -03:00
if (platformInfo.isCordova) {
if (screen.width < 768) {
screen.lockOrientation('portrait');
} else {
window.addEventListener("orientationchange", function() {
var leftMenuWidth = document.querySelector("ion-side-menu[side='left']").clientWidth;
if (screen.orientation.includes('portrait')) {
// Portrait
document.querySelector("ion-side-menu-content").style.width = (screen.width - leftMenuWidth) + "px";
} else {
// Landscape
document.querySelector("ion-side-menu-content").style.width = (screen.height - leftMenuWidth) + "px";
}
});
}
} else {
if (screen.width >= 768) {
window.addEventListener('resize', lodash.throttle(function() {
2016-06-23 16:18:18 -03:00
$rootScope.$emit('Local/WindowResize');
}, 100));
2016-06-23 16:18:18 -03:00
}
}
$ionicPlatform.ready(function() {
2016-06-06 12:24:07 -03:00
if (platformInfo.isCordova) {
2015-12-10 15:55:08 -03:00
window.addEventListener('native.keyboardhide', function() {
$timeout(function() {
$rootScope.shouldHideMenuBar = false; //show menu bar when keyboard is hidden with back button action on send screen
2016-07-15 01:27:45 -03:00
}, 100);
});
window.addEventListener('native.keyboardshow', function() {
2016-07-15 01:27:45 -03:00
$timeout(function() {
$rootScope.shouldHideMenuBar = true; //hide menu bar when keyboard opens with back button action on send screen
}, 300);
});
2016-08-17 15:23:17 -03:00
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleLightContent();
2016-06-28 15:18:55 -03:00
}
$ionicPlatform.registerBackButtonAction(function(event) {
event.preventDefault();
}, 100);
2015-12-10 15:55:08 -03:00
2016-06-06 12:24:07 -03:00
var secondBackButtonPress = false;
var intval = setInterval(function() {
2016-06-06 12:24:07 -03:00
secondBackButtonPress = false;
}, 5000);
$ionicPlatform.on('pause', function() {
// Nothing to do
});
$ionicPlatform.on('resume', function() {
$rootScope.$emit('Local/Resume');
});
$ionicPlatform.on('backbutton', function(event) {
var loc = window.location;
var fromDisclaimer = loc.toString().match(/disclaimer/) ? 'true' : '';
var fromHome = loc.toString().match(/index\.html#\/$/) ? 'true' : '';
if (fromDisclaimer == 'true')
navigator.app.exitApp();
2016-06-06 12:24:07 -03:00
if (platformInfo.isMobile && fromHome == 'true') {
if (secondBackButtonPress)
navigator.app.exitApp();
2016-06-06 12:24:07 -03:00
else
window.plugins.toast.showShortBottom(gettextCatalog.getString('Press again to exit'));
2015-03-06 12:00:10 -03:00
}
2016-06-06 12:24:07 -03:00
if (secondBackButtonPress)
clearInterval(intval);
2016-06-06 12:24:07 -03:00
else
secondBackButtonPress = true;
$timeout(function() {
$rootScope.$emit('Local/SetTab', 'walletHome', true);
}, 100);
2016-06-06 12:24:07 -03:00
go.walletHome();
});
$ionicPlatform.on('menubutton', function() {
window.location = '#/preferences';
});
setTimeout(function() {
navigator.splashscreen.hide();
}, 1000);
}
2016-08-16 18:38:18 -03:00
$log.info('Init profile...');
// Try to open local profile
profileService.loadAndBindProfile(function(err) {
if (err) {
if (err.message && err.message.match('NOPROFILE')) {
$log.debug('No profile... redirecting');
$state.transitionTo('disclaimer');
} else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
$log.debug('Display disclaimer... redirecting');
$state.transitionTo('disclaimer');
} else {
throw new Error(err); // TODO
}
} else {
profileService.storeProfileIfDirty();
$log.debug('Profile loaded ... Starting UX.');
$state.transitionTo('tabs.home');
}
});
});
2015-04-25 12:37:04 -03:00
2015-08-27 12:07:13 -03:00
uxLanguage.init();
2015-03-06 12:00:10 -03:00
if (platformInfo.isNW) {
2015-05-28 10:52:33 -03:00
var gui = require('nw.gui');
var win = gui.Window.get();
2015-07-13 13:21:47 -03:00
var nativeMenuBar = new gui.Menu({
type: "menubar"
});
2015-05-28 12:14:04 -03:00
try {
nativeMenuBar.createMacBuiltin("Copay");
2015-07-13 13:21:47 -03:00
} catch (e) {
2015-05-28 12:14:04 -03:00
$log.debug('This is not OSX');
}
2015-05-28 10:52:33 -03:00
win.menu = nativeMenuBar;
}
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$log.debug('Route change from:', fromState.name || '-', ' to:', toState.name);
$log.debug(' toParams:' + JSON.stringify(toParams || {}));
$log.debug(' fromParams:' + JSON.stringify(fromParams || {}));
2015-05-04 19:23:18 -03:00
2015-03-06 12:00:10 -03:00
});
});