diff --git a/app-template/index.html b/app-template/index.html
index 65c217daf..6a32429c8 100644
--- a/app-template/index.html
+++ b/app-template/index.html
@@ -20,7 +20,9 @@
autocomplete="address-level4" />
-
+
+
+
diff --git a/src/js/controllers/confirm.js b/src/js/controllers/confirm.js
index 4158d937d..2c0e2b595 100644
--- a/src/js/controllers/confirm.js
+++ b/src/js/controllers/confirm.js
@@ -15,6 +15,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.toEmail = data.stateParams.toEmail;
$scope.description = data.stateParams.description;
$scope.paypro = data.stateParams.paypro;
+ $scope._paypro = $scope.paypro;
$scope.paymentExpired = {
value: false
};
@@ -25,13 +26,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
var initConfirm = function() {
- if ($scope.paypro) {
- return setFromPayPro($scope.paypro, function(err) {
- if (err && !isChromeApp) {
- popupService.showAlert(gettext('Could not fetch payment'));
- }
- });
- }
// TODO (URL , etc)
if (!$scope.toAddress || !$scope.toAmount) {
$log.error('Bad params at amount');
@@ -100,6 +94,10 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.alternativeAmountStr = v;
});
+ if($scope.paypro) {
+ _paymentTimeControl($scope.paypro.expires);
+ }
+
$timeout(function() {
$scope.$apply();
}, 100);
@@ -149,56 +147,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
return amountStr.split(' ')[1];
}
- var setFromPayPro = function(uri, cb) {
- if (!cb) cb = function() {};
-
- var wallet = profileService.getWallets({
- onlyComplete: true
- })[0];
-
- if (!wallet) return cb();
-
- if (isChromeApp) {
- popupService.showAlert(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
- return cb(true);
- }
-
- $log.debug('Fetch PayPro Request...', uri);
-
- ongoingProcess.set('fetchingPayPro', true);
- wallet.fetchPayPro({
- payProUrl: uri,
- }, function(err, paypro) {
-
- ongoingProcess.set('fetchingPayPro', false);
-
- if (err) {
- $log.warn('Could not fetch payment request:', err);
- var msg = err.toString();
- if (msg.match('HTTP')) {
- msg = gettextCatalog.getString('Could not fetch payment information');
- }
- popupService.showAlert(msg);
- return cb(true);
- }
-
- if (!paypro.verified) {
- $log.warn('Failed to verify payment protocol signatures');
- popupService.showAlert(gettextCatalog.getString('Payment Protocol Invalid'));
- return cb(true);
- }
-
- $scope.toAmount = paypro.amount;
- $scope.toAddress = paypro.toAddress;
- $scope.description = paypro.memo;
- $scope.paypro = null;
-
- $scope._paypro = paypro;
- _paymentTimeControl(paypro.expires);
- return initConfirm();
- });
- };
-
function _paymentTimeControl(expirationTime) {
$scope.paymentExpired.value = false;
setExpirationTime();
@@ -219,7 +167,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var m = Math.floor(totalSecs / 60);
var s = totalSecs % 60;
$scope.remainingTimeStr.value = ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2);
- };
+ }
function setExpiredValues() {
$scope.paymentExpired.value = true;
@@ -228,8 +176,8 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$timeout(function() {
$scope.$apply();
});
- };
- };
+ }
+ }
function setWallet(wallet, delayed) {
var stop;
@@ -257,7 +205,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
}, delayed ? 2000 : 1);
}
- };
+ }
var setSendError = function(msg) {
$scope.sendStatus = '';
@@ -294,7 +242,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var msg = 'Amount too big';
$log.warn(msg);
return setSendError(msg);
- };
+ }
outputs.push({
'toAddress': toAddress,
@@ -313,7 +261,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txp.outputs = outputs;
txp.message = description;
- txp.payProUrl = paypro;
+ if(paypro) {
+ txp.payProUrl = paypro.url;
+ }
txp.excludeUnconfirmedUtxos = config.spendUnconfirmed ? false : true;
txp.feeLevel = config.settings && config.settings.feeLevel ? config.settings.feeLevel : 'normal';
txp.dryRun = dryRun;
@@ -349,7 +299,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var wallet = $scope.wallet;
if (!wallet) {
return setSendError(gettextCatalog.getString('No wallet selected'));
- };
+ }
if (!wallet.canSign() && !wallet.isPrivKeyExternal()) {
$log.info('No signing proposal: No private key');
diff --git a/src/js/controllers/tab-scan.js b/src/js/controllers/tab-scan.js
index 3d95c3a25..f04bad7cf 100644
--- a/src/js/controllers/tab-scan.js
+++ b/src/js/controllers/tab-scan.js
@@ -58,6 +58,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
$scope.$on("$ionicView.afterEnter", function() {
// try initializing and refreshing status any time the view is entered
scannerService.gentleInitialize();
+ scannerService.resumePreview();
});
function activate(){
@@ -95,9 +96,15 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
function handleSuccessfulScan(contents){
$log.debug('Scan returned: "' + contents + '"');
+ scannerService.pausePreview();
incomingData.redir(contents);
}
+ $rootScope.$on('incomingDataMenu.menuHidden', function() {
+ scannerService.resumePreview();
+ activate();
+ });
+
$scope.openSettings = function(){
scannerService.openSettings();
};
@@ -126,7 +133,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
$scope.canGoBack = function(){
return $state.params.passthroughMode;
- }
+ };
function goBack(){
$ionicHistory.nextViewOptions({
disableAnimate: true
diff --git a/src/js/controllers/tab-send.js b/src/js/controllers/tab-send.js
index 0ea31438b..afea741e1 100644
--- a/src/js/controllers/tab-send.js
+++ b/src/js/controllers/tab-send.js
@@ -61,7 +61,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.openScanner = function() {
$state.go('tabs.scan');
- }
+ };
$scope.showMore = function() {
currentContactsPage++;
diff --git a/src/js/directives/actionSheet.js b/src/js/directives/actionSheet.js
index 4ca9fddb0..6ea5cb292 100644
--- a/src/js/directives/actionSheet.js
+++ b/src/js/directives/actionSheet.js
@@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.directives')
- .directive('actionSheet', function() {
+ .directive('actionSheet', function($rootScope, $timeout) {
return {
restrict: 'E',
templateUrl: 'views/includes/actionSheet.html',
@@ -10,8 +10,16 @@ angular.module('copayApp.directives')
show: '=actionSheetShow',
},
link: function(scope, element, attrs) {
+ scope.$watch('show', function() {
+ if(scope.show) {
+ $timeout(function() { scope.revealMenu = true; }, 100);
+ } else {
+ scope.revealMenu = false;
+ }
+ });
scope.hide = function() {
scope.show = false;
+ $rootScope.$broadcast('incomingDataMenu.menuHidden');
};
}
};
diff --git a/src/js/directives/incomingDataMenu.js b/src/js/directives/incomingDataMenu.js
new file mode 100644
index 000000000..a43351438
--- /dev/null
+++ b/src/js/directives/incomingDataMenu.js
@@ -0,0 +1,50 @@
+'use strict';
+
+angular.module('copayApp.directives')
+ .directive('incomingDataMenu', function($timeout, $rootScope, $state, externalLinkService) {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/includes/incomingDataMenu.html',
+ link: function(scope, element, attrs) {
+ $rootScope.$on('incomingDataMenu.showMenu', function(event, data) {
+ $timeout(function() {
+ scope.data = data.data;
+ scope.type = data.type;
+ scope.showMenu = true;
+ scope.https = false;
+
+ if(scope.type === 'url') {
+ if(scope.data.indexOf('https://') === 0) {
+ scope.https = true;
+ }
+ }
+ });
+ });
+ scope.hide = function() {
+ scope.showMenu = false;
+ $rootScope.$broadcast('incomingDataMenu.menuHidden');
+ };
+ scope.goToUrl = function(url){
+ externalLinkService.open(url);
+ };
+ scope.sendPaymentToAddress = function(bitcoinAddress) {
+ scope.showMenu = false;
+ $state.go('tabs.send').then(function() {
+ $timeout(function() {
+ $state.transitionTo('tabs.send.amount', {toAddress: bitcoinAddress});
+ }, 50);
+ });
+ };
+ scope.addToAddressBook = function(bitcoinAddress) {
+ scope.showMenu = false;
+ $timeout(function() {
+ $state.go('tabs.send').then(function() {
+ $timeout(function() {
+ $state.transitionTo('tabs.send.addressbook', {addressbookEntry: bitcoinAddress});
+ });
+ });
+ }, 100);
+ };
+ }
+ };
+ });
diff --git a/src/js/routes.js b/src/js/routes.js
index c09789ab2..e7017cc41 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -269,13 +269,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.confirm', {
- url: '/confirm/:isWallet/:toAddress/:toName/:toAmount/:toEmail/:description/:paypro',
+ url: '/confirm/:isWallet/:toAddress/:toName/:toAmount/:toEmail/:description',
views: {
'tab-send@tabs': {
controller: 'confirmController',
templateUrl: 'views/confirm.html'
}
- }
+ },
+ params: { paypro: null }
})
.state('tabs.send.addressbook', {
url: '/addressbook/add/:fromSendTab/:addressbookEntry',
diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js
index c0b41b1a2..17e93c67d 100644
--- a/src/js/services/incomingData.js
+++ b/src/js/services/incomingData.js
@@ -1,9 +1,13 @@
'use strict';
-angular.module('copayApp.services').factory('incomingData', function($log, $state, $window, $timeout, bitcore, lodash) {
+angular.module('copayApp.services').factory('incomingData', function($log, $state, $window, $timeout, bitcore, profileService, popupService, ongoingProcess, platformInfo, gettextCatalog, $rootScope) {
var root = {};
+ root.showMenu = function(data) {
+ $rootScope.$broadcast('incomingDataMenu.showMenu', data);
+ };
+
root.redir = function(data) {
$log.debug('Processing incoming data: ' + data);
@@ -21,7 +25,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
newUri.replace('://', ':');
return newUri;
- };
+ }
function getParameterByName(name, url) {
if (!url) return;
@@ -53,59 +57,59 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
var amount = parsed.amount ? parsed.amount : '';
- $state.go('tabs.send');
- // Timeout is required to enable the "Back" button
- $timeout(function() {
- if (parsed.r) {
- $state.transitionTo('tabs.send.confirm', {paypro: parsed.r});
- } else {
+ if (parsed.r) {
+ getPayProDetails(parsed.r, function(err, details) {
+ handlePayPro(details);
+ });
+ } else {
+ $state.go('tabs.send');
+ // Timeout is required to enable the "Back" button
+ $timeout(function() {
if (amount) {
$state.transitionTo('tabs.send.confirm', {toAmount: amount, toAddress: addr, description:message});
} else {
$state.transitionTo('tabs.send.amount', {toAddress: addr});
}
- }
- });
+ });
+ }
return true;
// Plain URL
} else if (/^https?:\/\//.test(data)) {
- $state.go('tabs.send').then(function() {
- $state.transitionTo('tabs.send.confirm', {paypro: data});
- });
- return true;
- // Plain Address
- } else if (bitcore.Address.isValid(data, 'livenet')) {
- $state.go('tabs.send').then(function() {
- $state.transitionTo('tabs.send.amount', {toAddress: data});
+ getPayProDetails(data, function(err, details) {
+ if(err) {
+ root.showMenu({data: data, type: 'url'});
+ return;
+ }
+ handlePayPro(details);
+ return true;
});
- return true;
- } else if (bitcore.Address.isValid(data, 'testnet')) {
- $state.go('tabs.send').then(function() {
- $state.transitionTo('tabs.send.amount', {toAddress: data});
- });
- return true;
+ // Plain Address
+ } else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
+ if($state.includes('tabs.scan')) {
+ root.showMenu({data: data, type: 'bitcoinAddress'});
+ } else {
+ goToAmountPage(data);
+ }
+ } else if (data && data.indexOf($window.appConfig.name + '://glidera') === 0) {
+ return $state.go('uriglidera', {url: data});
+ } else if (data && data.indexOf($window.appConfig.name + '://coinbase') === 0) {
+ return $state.go('uricoinbase', {url: data});
- // Protocol
- } else if (data && data.indexOf($window.appConfig.name + '://glidera')==0) {
- return $state.go('uriglidera', {url: data});
- } else if (data && data.indexOf($window.appConfig.name + '://coinbase')==0) {
- return $state.go('uricoinbase', {url: data});
-
- // BitPayCard Authentication
- } else if (data && data.indexOf($window.appConfig.name + '://')==0) {
- var secret = getParameterByName('secret', data);
- var email = getParameterByName('email', data);
- var otp = getParameterByName('otp', data);
- $state.go('tabs.home').then(function() {
- $state.transitionTo('tabs.bitpayCardIntro', {
- secret: secret,
- email: email,
- otp: otp
+ // BitPayCard Authentication
+ } else if (data && data.indexOf($window.appConfig.name + '://') === 0) {
+ var secret = getParameterByName('secret', data);
+ var email = getParameterByName('email', data);
+ var otp = getParameterByName('otp', data);
+ $state.go('tabs.home').then(function() {
+ $state.transitionTo('tabs.bitpayCardIntro', {
+ secret: secret,
+ email: email,
+ otp: otp
+ });
});
- });
- return true;
+ return true;
// Join
} else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
@@ -120,11 +124,74 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
$state.transitionTo('tabs.add.join', {url: data});
});
return true;
+ } else {
+
+ if($state.includes('tabs.scan')) {
+ root.showMenu({data: data, type: 'text'});
+ }
}
return false;
};
+ function getPayProDetails(uri, cb) {
+ if (!cb) cb = function() {};
+
+ var wallet = profileService.getWallets({
+ onlyComplete: true
+ })[0];
+
+ if (!wallet) return cb();
+
+ if (platformInfo.isChromeApp) {
+ popupService.showAlert(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
+ return cb(true);
+ }
+
+ $log.debug('Fetch PayPro Request...', uri);
+
+ ongoingProcess.set('fetchingPayPro', true);
+
+ wallet.fetchPayPro({
+ payProUrl: uri,
+ }, function(err, paypro) {
+
+ ongoingProcess.set('fetchingPayPro', false);
+ if (err) {
+ return cb(true);
+ }
+
+ if (!paypro.verified) {
+ $log.warn('Failed to verify payment protocol signatures');
+ popupService.showAlert(gettextCatalog.getString('Payment Protocol Invalid'));
+ return cb(true);
+ }
+ cb(null, paypro);
+
+ });
+ }
+
+ function goToAmountPage(toAddress) {
+ $state.go('tabs.send');
+ $timeout(function() {
+ $state.transitionTo('tabs.send.amount', {toAddress: toAddress});
+ }, 100);
+ }
+
+ function handlePayPro(payProDetails){
+ var stateParams = {
+ toAmount: payProDetails.amount,
+ toAddress: payProDetails.toAddress,
+ description: payProDetails.memo,
+ paypro: payProDetails
+ };
+ $state.go('tabs.send').then(function() {
+ $timeout(function() {
+ $state.transitionTo('tabs.send.confirm', stateParams);
+ });
+ });
+ }
+
return root;
});
diff --git a/src/js/services/scannerService.js b/src/js/services/scannerService.js
index 3baff576a..12f05867e 100644
--- a/src/js/services/scannerService.js
+++ b/src/js/services/scannerService.js
@@ -1,9 +1,9 @@
'use strict';
-angular.module('copayApp.services').service('scannerService', function($log, $timeout, platformInfo, $rootScope) {
+angular.module('copayApp.services').service('scannerService', function($log, $timeout, platformInfo, $rootScope, $window) {
var isDesktop = !platformInfo.isCordova;
- var QRScanner = window.QRScanner;
+ var QRScanner = $window.QRScanner;
var lightEnabled = false;
var backCamera = true; // the plugin defaults to the back camera
@@ -55,8 +55,8 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
canEnableLight: canEnableLight,
canChangeCamera: canChangeCamera,
canOpenSettings: canOpenSettings
- }
- }
+ };
+ };
var initializeStarted = false;
/**
@@ -123,10 +123,10 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
}
this.isInitialized = function(){
return initializeCompleted;
- }
+ };
this.initializeStarted = function(){
return initializeStarted;
- }
+ };
var nextHide = null;
var nextDestroy = null;
@@ -167,6 +167,14 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
QRScanner.scan(callback);
};
+ this.pausePreview = function() {
+ QRScanner.pausePreview();
+ };
+
+ this.resumePreview = function() {
+ QRScanner.resumePreview();
+ };
+
/**
* Deactivate the QRScanner. To balance user-perceived performance and power
* consumption, this kicks off a countdown which will "sleep" the scanner
@@ -177,7 +185,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
*/
this.deactivate = function(callback) {
$log.debug('Deactivating scanner...');
- // QRScanner.cancelScan();
+ QRScanner.cancelScan();
nextHide = $timeout(_hide, hideAfterSeconds * 1000);
nextDestroy = $timeout(_destroy, destroyAfterSeconds * 1000);
};
@@ -200,7 +208,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
initializeCompleted = false;
QRScanner.destroy();
initialize(callback);
- }
+ };
/**
* Toggle the device light (if available).
@@ -236,7 +244,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
var nextCamera = backCamera? 1 : 0;
function cameraToString(index){
return index === 1? 'front' : 'back'; // front = 1, back = 0
- };
+ }
$log.debug('Toggling to the ' + cameraToString(nextCamera) + ' camera...');
QRScanner.useCamera(nextCamera, function(err, status){
if(err){
diff --git a/src/sass/views/includes/actionSheet.scss b/src/sass/views/includes/actionSheet.scss
index a0137618c..5e9fb7fd4 100644
--- a/src/sass/views/includes/actionSheet.scss
+++ b/src/sass/views/includes/actionSheet.scss
@@ -12,8 +12,8 @@ action-sheet {
transition: transform 250ms cubic-bezier(0.4, 0.0, 0.2, 1);
z-index: 100;
padding-top: 1.75rem;
- padding-left: 2rem;
- padding-right: .75rem;
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
color: #2f2f2f;
padding-bottom: 3.5rem;
max-width: 550px;
diff --git a/src/sass/views/includes/incomingDataMenu.scss b/src/sass/views/includes/incomingDataMenu.scss
new file mode 100644
index 000000000..2ce6e462a
--- /dev/null
+++ b/src/sass/views/includes/incomingDataMenu.scss
@@ -0,0 +1,81 @@
+incoming-data-menu {
+ .bp-action-sheet__sheet {
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0;
+ padding: 0;
+ }
+ .incoming-data-menu {
+ &__header {
+ padding-bottom: 1rem;
+ font-size: 16px;
+ }
+
+ &__item {
+ border-top: 1px solid #f7f4f4;
+ font-size: 14px;
+ padding: 1rem 1.25rem;
+ color: #4A4A4A;
+ display: flex;
+ align-items: center;
+
+ &.head {
+ display: block;
+ padding-top: 1.5rem;
+ }
+
+ &:first-child {
+ border: 0;
+ }
+
+ > img {
+ margin-left: .2rem;
+ position: absolute;
+ }
+
+ &__text {
+ padding-left: 2.7rem;
+ }
+ }
+
+ &__cancel {
+ background: #EDEDED;
+ font-size: 18px;
+ height: 66px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #3A3A3A;
+ border-top: 1px solid #e4e4e4;
+
+ &:active {
+ background: #dadada;
+ }
+ }
+ &__url {
+ background: rgba(203, 203, 203, .13);
+ padding: .5rem;
+ padding-left: 0;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ margin-bottom: .5rem;
+
+ &__icon {
+ padding: 0 9px 0 10px;
+ display: flex;
+ align-items: center;
+ }
+
+ &__text {
+ color: #4A4A4A;
+ font-size: 14px;
+ border-left: 1px solid #E4E4E4;
+ padding-left: .7rem;//1rem;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ }
+ }
+}
diff --git a/src/sass/views/includes/walletSelector.scss b/src/sass/views/includes/walletSelector.scss
index d0990b71b..a0b382f90 100644
--- a/src/sass/views/includes/walletSelector.scss
+++ b/src/sass/views/includes/walletSelector.scss
@@ -1,7 +1,12 @@
wallet-selector {
-
+
$border-color: #EFEFEF;
+ .bp-action-sheet__sheet {
+ padding-left: 2rem;
+ padding-right: .75rem;
+ }
+
.wallet-selector {
.wallet {
border: 0;
diff --git a/src/sass/views/views.scss b/src/sass/views/views.scss
index 3fa9643f1..c85824ba3 100644
--- a/src/sass/views/views.scss
+++ b/src/sass/views/views.scss
@@ -24,6 +24,7 @@
@import "includes/wallets";
@import "includes/modals/modals";
@import "includes/clickToAccept";
+@import "includes/incomingDataMenu";
@import "includes/slideToAccept";
@import "includes/slideToAcceptSuccess";
@import "includes/tx-details";
diff --git a/www/img/icon-contacts.svg b/www/img/icon-contacts.svg
new file mode 100644
index 000000000..01c52492a
--- /dev/null
+++ b/www/img/icon-contacts.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-link-external.svg b/www/img/icon-link-external.svg
new file mode 100644
index 000000000..8e198c75f
--- /dev/null
+++ b/www/img/icon-link-external.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-lock-green.svg b/www/img/icon-lock-green.svg
new file mode 100644
index 000000000..d1be82334
--- /dev/null
+++ b/www/img/icon-lock-green.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/www/img/icon-lock-x.svg b/www/img/icon-lock-x.svg
new file mode 100644
index 000000000..e59f48487
--- /dev/null
+++ b/www/img/icon-lock-x.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-paperclip.svg b/www/img/icon-paperclip.svg
new file mode 100644
index 000000000..ce65f0abc
--- /dev/null
+++ b/www/img/icon-paperclip.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/www/img/icon-send-alt.svg b/www/img/icon-send-alt.svg
new file mode 100644
index 000000000..27c7bd1dc
--- /dev/null
+++ b/www/img/icon-send-alt.svg
@@ -0,0 +1,21 @@
+
+
\ No newline at end of file
diff --git a/www/img/logo-negative.svg b/www/img/logo-negative.svg
new file mode 100644
index 000000000..d325ec632
--- /dev/null
+++ b/www/img/logo-negative.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/www/img/logo.svg b/www/img/logo.svg
new file mode 100644
index 000000000..bae45745c
--- /dev/null
+++ b/www/img/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/www/views/includes/actionSheet.html b/www/views/includes/actionSheet.html
index df159bc2b..3ced59686 100644
--- a/www/views/includes/actionSheet.html
+++ b/www/views/includes/actionSheet.html
@@ -1,10 +1,8 @@
-
-
-
+
diff --git a/www/views/includes/incomingDataMenu.html b/www/views/includes/incomingDataMenu.html
new file mode 100644
index 000000000..0478e88ff
--- /dev/null
+++ b/www/views/includes/incomingDataMenu.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/www/views/includes/walletSelector.html b/www/views/includes/walletSelector.html
index ba97edad0..42ec0d772 100644
--- a/www/views/includes/walletSelector.html
+++ b/www/views/includes/walletSelector.html
@@ -1,4 +1,6 @@
+
+
+