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

This commit is contained in:
Jean-Baptiste Dominguez 2018-08-08 11:23:35 +09:00 committed by GitHub
commit 037c00ec9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 633 additions and 151 deletions

View file

@ -163,7 +163,7 @@ module.exports = function(grunt) {
}, },
bitanalytics: { bitanalytics: {
src: [ src: [
'bitanalytics/bitanalytics-0.1.0.js' 'bitanalytics/bitanalytics.js'
], ],
dest: 'www/lib/bitanalytics.js' dest: 'www/lib/bitanalytics.js'
}, },

View file

@ -72,7 +72,7 @@
<plugin name="cordova-plugin-queries-schemes" spec="~0.1.5" /> <plugin name="cordova-plugin-queries-schemes" spec="~0.1.5" />
<plugin name="cordova-plugin-firebase" spec="https://github.com/arnesson/cordova-plugin-firebase.git" /> <plugin name="cordova-plugin-firebase" spec="https://github.com/arnesson/cordova-plugin-firebase.git" />
<plugin name="cordova-plugin-wkwebview-inputfocusfix" spec="https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfix.git" /> <plugin name="cordova-plugin-wkwebview-inputfocusfix" spec="https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfix.git" />
<plugin name="cordova-plugin-media" spec="~5.0.2"> <plugin name="cordova-plugin-media-fork" spec="~5.0.3">
<variable name="KEEP_AVAUDIOSESSION_ALWAYS_ACTIVE" value="NO" /> <variable name="KEEP_AVAUDIOSESSION_ALWAYS_ACTIVE" value="NO" />
</plugin> </plugin>
<!-- Supported Platforms --> <!-- Supported Platforms -->

View file

@ -6276,7 +6276,7 @@ var ClickAction = /** @class */ (function (_super) {
}(action_1.default)); }(action_1.default));
exports.default = ClickAction; exports.default = ClickAction;
},{"../action":4,"../log-event":15,"../log-event-handlers":14}],6:[function(require,module,exports){ },{"../action":4,"../log-event":16,"../log-event-handlers":15}],6:[function(require,module,exports){
"use strict"; "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6315,7 +6315,7 @@ var BitAnalytics = /** @class */ (function () {
exports.default = BitAnalytics; exports.default = BitAnalytics;
BitAnalytics.main(); BitAnalytics.main();
},{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":15,"./log-event-handlers":14}],7:[function(require,module,exports){ },{"./action-factory":2,"./action-handlers":3,"./channels/adjust-channel":9,"./channels/mixpanel-channel":12,"./log-event":16,"./log-event-handlers":15}],7:[function(require,module,exports){
"use strict"; "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6560,11 +6560,10 @@ var FirebaseChannel = /** @class */ (function (_super) {
var keys = Object.keys(params); var keys = Object.keys(params);
var keysLength = keys.length; var keysLength = keys.length;
var sanitized = {}; var sanitized = {};
for (var i = 0; i < keysLength; i++) { keys.map(function (key) {
var key = keys[i];
var cleanKey = key.replace('-', '_').replace(/[\W]+/g, ''); var cleanKey = key.replace('-', '_').replace(/[\W]+/g, '');
sanitized[cleanKey] = params[key]; sanitized[cleanKey] = params[key];
} });
return sanitized; return sanitized;
}; };
return FirebaseChannel; return FirebaseChannel;
@ -6588,13 +6587,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var channel_1 = __importDefault(require("../channel")); var channel_1 = __importDefault(require("../channel"));
var ga_1 = __importDefault(require("../external-libs/ga"));
var GoogleAnalyticsChannel = /** @class */ (function (_super) { var GoogleAnalyticsChannel = /** @class */ (function (_super) {
__extends(GoogleAnalyticsChannel, _super); __extends(GoogleAnalyticsChannel, _super);
function GoogleAnalyticsChannel(name, config) { function GoogleAnalyticsChannel(name, config) {
var _this = _super.call(this, name) || this; var _this = _super.call(this, name) || this;
_this.dataLayer = null;
_this.gaInstance = null; _this.gaInstance = null;
_this.trackingId = '';
_this.eventLabels = ['id']; _this.eventLabels = ['id'];
if (!config.trackingId) { if (!config.trackingId) {
throw new Error('[BitAnalytics] Google Analytics config is missing tracking ID.'); throw new Error('[BitAnalytics] Google Analytics config is missing tracking ID.');
@ -6602,8 +6600,12 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
if (config.eventLabels) { if (config.eventLabels) {
_this.eventLabels = config.eventLabels; _this.eventLabels = config.eventLabels;
} }
_this.trackingId = config.trackingId; _this.gaInstance = new ga_1.default({
_this.setUpGa(); trackID: config.trackingId,
appVersion: config.appVersion,
appName: config.appName || 'App'
});
_this.isReady = true;
return _this; return _this;
} }
/** /**
@ -6612,49 +6614,26 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
* *
*/ */
GoogleAnalyticsChannel.prototype.postEvent = function (name, params) { GoogleAnalyticsChannel.prototype.postEvent = function (name, params) {
// Default Google Analytics Events
// https://developers.google.com/analytics/devguides/collection/gtagjs/events
// Useful to convert to these, or start with these?
if (this.isReady) { if (this.isReady) {
params.event_category = name; var category = name;
var action = name;
var label = name;
var value = params['value'] || '';
for (var _i = 0, _a = this.eventLabels; _i < _a.length; _i++) { for (var _i = 0, _a = this.eventLabels; _i < _a.length; _i++) {
var eventLabel = _a[_i]; var eventLabel = _a[_i];
if (params[eventLabel]) { if (params[eventLabel]) {
params.event_label = params[eventLabel]; label = params[eventLabel];
break; break;
} }
} }
this.gtag('event', name, params); this.gaInstance.event(category, action, label, value);
} }
}; };
/**
*
* Private methods
*
*/
/**
* Mimics function in the tracking snippet
*/
GoogleAnalyticsChannel.prototype.gtag = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log(arguments);
window.dataLayer.push(arguments);
};
GoogleAnalyticsChannel.prototype.setUpGa = function () {
// From what GA recommends to insert into page
window.dataLayer = window.dataLayer || [];
this.gtag('js', new Date());
this.gtag('config', this.trackingId);
this.isReady = true;
};
return GoogleAnalyticsChannel; return GoogleAnalyticsChannel;
}(channel_1.default)); }(channel_1.default));
exports.default = GoogleAnalyticsChannel; exports.default = GoogleAnalyticsChannel;
},{"../channel":8}],12:[function(require,module,exports){ },{"../channel":8,"../external-libs/ga":14}],12:[function(require,module,exports){
"use strict"; "use strict";
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = Object.setPrototypeOf ||
@ -6746,6 +6725,207 @@ exports.default = MixpanelChannel;
},{}],14:[function(require,module,exports){ },{}],14:[function(require,module,exports){
"use strict"; "use strict";
/*
* name: nwjs-analytics -Node-Webkit Google Analytics integration
* version: 1.0.2
* github: https://github.com/Daaru00/nwjs-analytics
*/
function GA(opt) {
this.apiVersion = opt.apiVersion || '1';
this.trackID = opt.trackID || 'UA-XXXXXXXX-X';
this.clientID = opt.clientID || null;
this.userID = opt.userID || null;
this.appName = opt.appName || 'App';
this.appVersion = opt.appVersion || '1.0.0';
this.debug = opt.debug || false;
this.performanceTracking = opt.performanceTracking || true;
this.errorTracking = opt.errorTracking || true;
this.userLanguage = opt.userLanguage || "en";
this.currency = opt.currency || "EUR";
this.lastScreenName = opt.lastScreenName || '';
}
GA.prototype.sendRequest = function (data, callback) {
var ga = this;
if (!this.clientID || this.clientID == null)
this.clientID = this.generateClientID();
if (!this.userID || this.userID == null)
this.userID = this.generateClientID();
var postData = "v=" + this.apiVersion
+ "&an=" + this.appName
+ "&av=" + this.appVersion
+ "&tid=" + this.trackID
+ "&cid=" + this.clientID
+ "&sr=" + this.getScreenResolution()
+ "&vp=" + this.getViewportSize();
Object.keys(data).forEach(function (key) {
var val = data[key];
if (typeof val != "undefined")
postData += "&" + key + "=" + val;
});
var http = new XMLHttpRequest();
var url = "https://www.google-analytics.com";
if (!this.debug)
url += "/collect";
else
url += "/debug/collect";
http.open("GET", url + "?" + postData, true);
http.onreadystatechange = function () {
if (ga.debug)
console.log(http.response);
if (http.readyState == 4 && http.status == 200) {
if (callback)
callback(true);
}
else {
if (callback)
callback(false);
}
};
http.send();
};
GA.prototype.generateClientID = function () {
var id = "";
var possibilities = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
};
GA.prototype.getScreenResolution = function () {
return screen.width + "x" + screen.height;
};
GA.prototype.getColorDept = function () {
return screen.colorDepth + "-bits";
};
GA.prototype.getUserAgent = function () {
return navigator.userAgent;
};
GA.prototype.getViewportSize = function () {
return window.screen.availWidth + "x" + window.screen.availHeight;
};
/*
* Measurement Protocol
* [https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide]
*/
GA.prototype.screenView = function (screename) {
var data = {
't': 'screenview',
'cd': screename
};
this.sendRequest(data);
this.lastScreenName = screename;
};
GA.prototype.event = function (category, action, label, value) {
var data = {
't': 'event',
'ec': category,
'ea': action,
};
if (label) {
data['el'] = label;
}
if (value) {
data['ev'] = value;
}
if (this.lastScreenName) {
data['cd'] = this.lastScreenName;
}
this.sendRequest(data);
};
GA.prototype.exception = function (msg, fatal) {
var data = {
't': 'exception',
'exd': msg,
'exf': fatal || 0
};
this.sendRequest(data);
};
GA.prototype.timing = function (category, variable, time, label) {
var data = {
't': 'timing',
'utc': category,
'utv': variable,
'utt': time,
'utl': label,
};
this.sendRequest(data);
},
GA.prototype.ecommerce = {
transactionID: false,
generateTransactionID: function () {
var id = "";
var possibilities = "0123456789";
for (var i = 0; i < 5; i++)
id += possibilities.charAt(Math.floor(Math.random() * possibilities.length));
return id;
},
transaction: function (total, items) {
var t_id = "";
if (!this.ecommerce.transactionID)
t_id = this.ecommerce.generateTransactionID();
else
t_id = this.ecommerce.transactionID;
var data = {
't': 'transaction',
'ti': t_id,
'tr': total,
'cu': this.currency,
};
this.sendRequest(data);
items.forEach(function (item) {
var data = {
't': 'item',
'ti': t_id,
'in': item.name,
'ip': item.price,
'iq': item.qty,
'ic': item.id,
'cu': this.currency
};
this.sendRequest(data);
});
}
},
GA.prototype.custom = function (data) {
this.sendRequest(data);
};
module.exports = GA;
/*
* Performance Tracking
*/
/*window.addEventListener("load", function() {
if(ga.performanceTracking) {
setTimeout(function() {
var timing = window.performance.timing;
var userTime = timing.loadEventEnd - timing.navigationStart;
ga.timing("performance", "pageload", userTime);
}, 0);
}
}, false);*/
/*
* Error Reporting
*/
/*window.onerror = function (msg, url, lineNo, columnNo, error) {
var message = [
'Message: ' + msg,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
if(ga.errorTracking)
{
setTimeout(function() {
ga.exception(message.toString());
}, 0);
}
return false;
};*/
},{}],15:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
@ -6865,7 +7045,7 @@ var LogEventHandlers = /** @class */ (function () {
}()); }());
exports.default = LogEventHandlers; exports.default = LogEventHandlers;
},{"./channel-factory":7}],15:[function(require,module,exports){ },{"./channel-factory":7}],16:[function(require,module,exports){
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var LogEvent = /** @class */ (function () { var LogEvent = /** @class */ (function () {

View file

@ -201,6 +201,16 @@ msgstr ""
msgid "Price Display" msgid "Price Display"
msgstr "" msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:12
msgid "Fiat"
msgstr ""
#: src/js/controllers/tab-settings.js:19
#: www/views/preferencesPriceDisplay.html:15
msgid "Cryptocurrency"
msgstr ""
#: src/js/controllers/buyAmazon.js:98 #: src/js/controllers/buyAmazon.js:98
msgid "Amazon.com is not available at this moment. Please try back later." msgid "Amazon.com is not available at this moment. Please try back later."
msgstr "" msgstr ""
@ -432,6 +442,7 @@ msgid "Buy &amp; Sell Bitcoin"
msgstr "" msgstr ""
#: www/views/tab-send.html:35 #: www/views/tab-send.html:35
#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin" msgid "Buy Bitcoin"
msgstr "" msgstr ""
@ -656,6 +667,7 @@ msgstr ""
#: src/js/controllers/copayers.js:79 #: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193 #: src/js/controllers/export.js:193
#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4 #: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard" msgid "Copied to clipboard"
msgstr "" msgstr ""
@ -2162,6 +2174,10 @@ msgstr ""
msgid "Payment Sent" msgid "Payment Sent"
msgstr "" msgstr ""
#: www/views/includes/slideToAcceptSuccess.html:12
msgid "Share this transaction"
msgstr ""
#: www/views/modals/txp-details.html:32 #: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted" msgid "Payment accepted, but not yet broadcasted"
msgstr "" msgstr ""
@ -3725,6 +3741,54 @@ msgstr ""
msgid "{{wallet.m}}-of-{{wallet.n}}" msgid "{{wallet.m}}-of-{{wallet.n}}"
msgstr "" msgstr ""
#: src/js/services/shapeshiftService.js:8
msgid "Shapeshift"
msgstr ""
#: www/views/includes/community.html:3
msgid "Community"
msgstr ""
#: src/js/services/communityService.js:40
msgid "Bitcoin Cash Reddit"
msgstr ""
#: src/js/services/communityService.js:47
msgid "Bitcoin.com Twitter"
msgstr ""
#: www/views/includes/nextSteps.html:3
msgid "Explore Bitcoin.com"
msgstr ""
#: src/js/services/bitcoincomService.js:21
msgid "Bitcoin Cash Games"
msgstr ""
#: src/js/services/bitcoincomService.js:28
msgid "News"
msgstr ""
#: src/js/services/bitcoincomService.js:35
msgid "Mining Pool"
msgstr ""
#: src/js/services/bitcoincomService.js:42
msgid "Tools"
msgstr ""
#: src/js/services/bitcoincomService.js:49
msgid "Bitcoin Price Charts"
msgstr ""
#: src/js/services/bitcoincomService.js:56
msgid "Free Bitcoin Cash"
msgstr ""
#: www/views/tab-home.html:30
msgid "Your Bitcoin Wallets are ready!"
msgstr ""
#: src/js/controllers/amount.js:49 #: src/js/controllers/amount.js:49
msgid "Address doesn\'t contain currency information, please make sure you are sending the correct currency." msgid "Address doesn\'t contain currency information, please make sure you are sending the correct currency."
msgstr "" msgstr ""

View file

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

View file

@ -1,11 +1,12 @@
'use strict'; '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, $filter, $timeout, $ionicScrollDelegate, $ionicLoading, ionicToast, 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, clipboardService) {
var countDown = null; var countDown = null;
var FEE_TOO_HIGH_LIMIT_PER = 15; var FEE_TOO_HIGH_LIMIT_PER = 15;
var tx = {}; var tx = {};
var lastTxId = "";
// Config Related values // Config Related values
var config = configService.getSync(); var config = configService.getSync();
@ -25,6 +26,17 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}, 10); }, 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.showWalletSelector = function() {
$scope.walletSelector = true; $scope.walletSelector = true;
refresh(); refresh();
@ -652,6 +664,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txConfirmNotification.subscribe(wallet, { txConfirmNotification.subscribe(wallet, {
txid: txp.txid txid: txp.txid
}); });
lastTxId = txp.txid;
} }
}, onSendStatusChange); }, onSendStatusChange);
}; };
@ -683,9 +696,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
soundService.play('misc/payment_sent.mp3'); soundService.play('misc/payment_sent.mp3');
} }
var channel = "firebase"; var channel = "ga";
if (platformInfo.isNW) { if (platformInfo.isCordova) {
channel = "ga"; channel = "firebase";
} }
var log = new window.BitAnalytics.LogEvent("transfer_success", [{ var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin, "coin": $scope.wallet.coin,

View file

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

View file

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

View file

@ -224,6 +224,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
cb(); 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; $scope.paymentReceivedCoin = $scope.wallet.coin;
var channel = "firebase"; var channel = "ga";
if (platformInfo.isNW) { if (platformInfo.isCordova) {
channel = "ga"; channel = "firebase";
} }
var log = new window.BitAnalytics.LogEvent("transfer_success", [{ var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin, "coin": $scope.wallet.coin,
@ -232,10 +232,14 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
if (!$scope.wallets[0]) return; if (!$scope.wallets[0]) return;
// select first wallet if no wallet selected previously var selectedWallet = null;
var selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets); 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.onWalletSelect(selectedWallet);
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null; $scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
listeners = [ listeners = [

View file

@ -16,7 +16,7 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
isoCode: config.wallet.settings.alternativeIsoCode 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 // TODO move this to a generic service
bitpayAccountService.getAccounts(function(err, data) { bitpayAccountService.getAccounts(function(err, data) {

View file

@ -12,9 +12,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.isAndroid = platformInfo.isAndroid; $scope.isAndroid = platformInfo.isAndroid;
$scope.isIOS = platformInfo.isIOS; $scope.isIOS = platformInfo.isIOS;
var channel = "firebase"; var channel = "ga";
if (platformInfo.isNW) { if (platformInfo.isCordova) {
channel = "ga"; channel = "firebase";
} }
var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]); var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]);
window.BitAnalytics.LogEventHandlers.postEvent(log); window.BitAnalytics.LogEventHandlers.postEvent(log);
@ -342,9 +342,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
top = TOP_BALANCE_BUTTON; top = TOP_BALANCE_BUTTON;
} }
var amountTop = ((amountScale - 0.7) / 0.7) * top; var amountTop = ((amountScale - 0.80) / 0.80) * top;
if (amountTop < -10) { if (amountTop < -2) {
amountTop = -10; amountTop = -2;
} }
if (amountTop > top) { if (amountTop > top) {
amountTop = top; amountTop = top;
@ -353,6 +353,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var t = amountTop; var t = amountTop;
$scope.altAmountOpacity = (amountHeight - 100) / 80; $scope.altAmountOpacity = (amountHeight - 100) / 80;
$scope.buttonsOpacity = (amountHeight - 140) / 70;
$window.requestAnimationFrame(function() { $window.requestAnimationFrame(function() {
$scope.amountHeight = amountHeight + 'px'; $scope.amountHeight = amountHeight + 'px';
$scope.contentMargin = contentMargin + 'px'; $scope.contentMargin = contentMargin + 'px';
@ -469,4 +470,30 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function rgbToHex(r, g, b) { function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
} }
$scope.goToSend = function() {
$state.go('tabs.home', {
walletId: $scope.wallet.id
}).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

@ -9,12 +9,12 @@ angular.module('copayApp.directives')
scope: { scope: {
isShown: '=slideSuccessShow', isShown: '=slideSuccessShow',
onConfirm: '&slideSuccessOnConfirm', onConfirm: '&slideSuccessOnConfirm',
hideOnConfirm: '=slideSuccessHideOnConfirm' hideOnConfirm: '=slideSuccessHideOnConfirm',
onShare: '=slideSuccessOnShare',
}, },
link: function(scope, element, attrs) { link: function(scope, element, attrs) {
scope.isCordova = platformInfo.isCordova;
scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP; scope.hasShareFunction = typeof scope.onShare === 'function';
var elm = element[0]; var elm = element[0];
elm.style.display = 'none'; elm.style.display = 'none';
scope.$watch('isShown', function() { scope.$watch('isShown', function() {
@ -32,6 +32,9 @@ angular.module('copayApp.directives')
elm.style.display = 'none'; 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', { .state('tabs.receive', {
url: '/receive', url: '/receive/:walletId',
views: { views: {
'tab-receive': { 'tab-receive': {
controller: 'tabReceiveController', controller: 'tabReceiveController',
@ -1231,9 +1231,9 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
} }
}); });
var channel = "firebase"; var channel = "ga";
if (platformInfo.isNW) { if (platformInfo.isCordova) {
channel = "ga"; channel = "firebase";
} }
// Send a log to test // Send a log to test

View file

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

View file

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

View file

@ -11,10 +11,15 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cordova.plugins.clipboard.copy(data); cordova.plugins.clipboard.copy(data);
} else if (platformInfo.isNW) { } else if (platformInfo.isNW) {
nodeWebkitService.writeToClipboard(data); nodeWebkitService.writeToClipboard(data);
} else if (navigator && navigator.clipboard) {
$log.debug("Use navigator clipboard.")
navigator.clipboard.writeText(data).catch(err => {
$log.debug("Clipboard writing is not supported in your browser..");
});
} else if (clipboard.supported) { } else if (clipboard.supported) {
clipboard.copyText(data); clipboard.copyText(data);
} else { } else {
// No supported // Not supported
return; return;
} }
}; };

View file

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

View file

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

View file

@ -1,4 +1,5 @@
'use strict'; 'use strict';
angular.module('copayApp.services').factory('shapeshiftService', function ($http, $interval, $log, lodash, moment, ongoingProcess, shapeshiftApiService, storageService, configService, incomingData, platformInfo, servicesService) { angular.module('copayApp.services').factory('shapeshiftService', function ($http, $interval, $log, lodash, moment, ongoingProcess, shapeshiftApiService, storageService, configService, incomingData, platformInfo, servicesService) {
var root = {}; var root = {};
root.ShiftState = 'Shift'; root.ShiftState = 'Shift';
@ -135,17 +136,4 @@ 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; var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency // 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; amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0); amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0);
} else if (currency == 'sat') { } else if (currency == 'sat') {

View file

@ -72,5 +72,17 @@
&.activated { &.activated {
color: #FFF; 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: ""; content: "";
background-size: 100% 100%; background-size: 100% 100%;
display: block; display: block;
left: 88px; left: calc(50% - 22px);
margin-top: 88px; margin-top: calc(50% - 22px);
width: 44px; width: 44px;
height: 44px; height: 44px;
position:absolute; position:absolute;

View file

@ -233,6 +233,10 @@ input[type=number] {
font-size: 24px; font-size: 24px;
} }
.size-25 {
font-size: 25px;
}
.size-28 { .size-28 {
font-size: 28px; font-size: 28px;
} }

View file

@ -26,16 +26,10 @@
height: 100%; height: 100%;
.qr-code { .qr-code {
text-align: center; text-align: center;
margin-top: 24vh; margin-top: 6px;
margin-bottom: 7vh; qrcode canvas {
@media(max-height: 800px) { height: 30vh;
margin-top: 18vh; max-height: 220px;
}
@media(max-height: 700px) {
margin-top: 14vh;
}
@media(max-height: 600px) {
margin-top: 8vh;
} }
} }
.info { .info {
@ -91,5 +85,34 @@
.address-types { .address-types {
text-align: center; 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

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

View file

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

View file

@ -135,11 +135,12 @@
&.status-bar { &.status-bar {
margin-top: 20px; margin-top: 20px;
margin-top: env(safe-area-inset-top);
} }
} }
.bar-header { .bar-header {
border: 0; border: 0;
background: none; background: rgb(238, 182, 64);
.title, .button { .title, .button {
color: #fff; color: #fff;
} }
@ -153,7 +154,7 @@
ion-content { ion-content {
&.collapsible { &.collapsible {
margin-top: 210px; margin-top: 230px;
} }
padding-top: 0; padding-top: 0;
@ -190,12 +191,34 @@
transform: translateY(100px); transform: translateY(100px);
} }
} }
.send-receive-buttons {
max-width: 600px;
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%;
font-size: 19px;
font-weight: bolder;
min-height: auto;
line-height: 36px;
}
}
} }
.amount { .amount {
width: 100%; width: 100%;
text-align: center; text-align: center;
color: #fff; color: #fff;
height: 210px; height: 230px;
padding-top: 40px; padding-top: 40px;
display: block; display: block;
align-items: center; align-items: center;

View file

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 166">
<defs>
<style>
.cls-1 {
fill: #fff;
}
</style>
</defs>
<path id="_ionicons_svg_md-checkmark-circle-outline" class="cls-1" d="M96.969,115.231,85.35,126.85,122.7,164.2l83-83L194.081,69.581,122.7,140.544,96.969,115.231ZM197.4,131a66.116,66.116,0,1,1-48.138-63.91l12.863-12.865A77.206,77.206,0,0,0,131,48a83,83,0,1,0,83,83Z" transform="translate(-48 -48)"/>
</svg>

After

Width:  |  Height:  |  Size: 458 B

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="400px" height="400px" viewBox="56 56 400 400" enable-background="new 56 56 400 400" xml:space="preserve">
<g>
<g>
<path fill="#FFFFFF" d="M350.833,297.017c-17.517,0-32.967,8.346-43.062,21.124l-93.629-47.881
c1.226-4.571,2.106-9.296,2.106-14.267c0-5.412-1.046-10.507-2.506-15.465l93.216-47.661
c10.039,13.358,25.889,22.089,43.888,22.089c30.489,0,55.153-24.664,55.153-55.125c0-30.435-24.664-55.112-55.152-55.112
c-30.42,0-55.111,24.677-55.111,55.111c0,4.985,0.882,9.723,2.12,14.308l-93.615,47.882
c-10.108-12.793-25.587-21.166-43.131-21.166c-30.462,0-55.111,24.691-55.111,55.139c0,30.447,24.65,55.125,55.111,55.125
c18.026,0,33.863-8.758,43.943-22.129l93.174,47.66c-1.46,4.943-2.52,10.081-2.52,15.507c0,30.447,24.691,55.125,55.111,55.125
c30.489,0,55.152-24.678,55.152-55.125C405.985,321.681,381.322,297.017,350.833,297.017z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -120,6 +120,7 @@
<slide-to-accept-success <slide-to-accept-success
slide-success-show="sendStatus === 'success'" slide-success-show="sendStatus === 'success'"
slide-success-on-confirm="onSuccessConfirm()" slide-success-on-confirm="onSuccessConfirm()"
slide-success-on-share="shareTransaction"
slide-success-hide-on-confirm="true"> slide-success-hide-on-confirm="true">
<span ng-show="wallet.m == 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Payment Sent</span> <span ng-show="wallet.m == 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Payment Sent</span>
<span ng-show="wallet.m > 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Proposal Created</span> <span ng-show="wallet.m > 1 && (wallet.canSign() || wallet.isPrivKeyExternal())" translate>Proposal Created</span>

View file

@ -30,8 +30,22 @@
<br/>Return To Address<br/> <br/>Return To Address<br/>
</p> </p>
</div> </div>
<div ng-show="!showingPaymentReceived" class="amount">
<div ng-show="selectedPriceDisplay=='fiat'">
<span class="size-36">{{amountUnitStr}}</span>
<div class="size-14 amount-alternative">
{{altAmountStr | uppercase}}
</div>
</div>
<div ng-show="selectedPriceDisplay=='crypto'">
<span class="size-36">{{altAmountStr | uppercase}}</span>
<div class="size-14 amount-alternative">
{{amountUnitStr}}
</div>
</div>
</div>
<div ng-show="!showingPaymentReceived" class="qr-code" copy-to-clipboard="copyToClipboard()"> <div ng-show="!showingPaymentReceived" class="qr-code" copy-to-clipboard="copyToClipboard()">
<qrcode size="220" data="{{ protocolHandler }}:{{address + '?amount=' + amountBtc}}" color="#334"></qrcode> <qrcode class="qr-overlay qr-overlay--{{ wallet.coin }}" size="220" data="{{ protocolHandler }}:{{address + '?amount=' + amountBtc}}" color="#334"></qrcode>
</div> </div>
<div ng-show="!showingPaymentReceived" ng-show="address && coin == 'bch'" class="address-types"> <div ng-show="!showingPaymentReceived" ng-show="address && coin == 'bch'" class="address-types">
<div> <div>
@ -57,12 +71,6 @@
{{address}} {{address}}
</span> </span>
</div> </div>
<div class="item single-line">
<span class="label" translate>Amount</span>
<span class="item-note">
{{amountUnitStr}} - {{altAmountStr}}
</span>
</div>
<div class="item single-line"> <div class="item single-line">
<div class="wallet"> <div class="wallet">
<i class="icon big-icon-svg" ng-include="'views/includes/walletIcon.html'"></i> <i class="icon big-icon-svg" ng-include="'views/includes/walletIcon.html'"></i>

View file

@ -1,13 +1,16 @@
<div <div
class="slide-success__background" class="slide-success__background"
ng-class="{'fill-screen': fillScreen, 'slide-success__windows-background': isWindowsPhoneApp}"> ng-class="{'fill-screen': fillScreen}">
</div> </div>
<div ng-disabled="wallet" class="slide-success__content"> <div ng-disabled="wallet" class="slide-success__content">
<img src="img/onboarding-success.svg" ng-class="{reveal: fillScreen}"> <img src="img/icon-sent-successful.svg" ng-class="{reveal: fillScreen}">
<div class="slide-success__content__header" ng-class="{reveal: fillScreen}"> <div class="slide-success__content__header" ng-class="{reveal: fillScreen}">
<ng-transclude>Payment Sent</ng-transclude> <ng-transclude>Payment Sent</ng-transclude>
</div> </div>
<div class="slide-success__content__share" ng-if="hasShareFunction" ng-class="{reveal: fillScreen}" ng-click="onShareButtonClick()">
<span><img src="img/icon-share-white.svg"></span><span translate>Share this transaction</span>
</div>
</div> </div>
<div class="slide-success__footer" ng-class="{reveal: fillScreen}"> <div class="slide-success__footer" ng-class="{reveal: fillScreen}">

View file

@ -1,18 +1,18 @@
<ion-view id="settings-pricedisplay" class="settings" show-tabs> <ion-view id="settings-pricedisplay" class="settings" show-tabs>
<ion-nav-bar class="bar-royal"> <ion-nav-bar class="bar-royal">
<ion-nav-title> <ion-nav-title>
{{'Price display'|translate}} {{'Price Display'|translate}}
</ion-nav-title> </ion-nav-title>
<ion-nav-back-button> <ion-nav-back-button>
</ion-nav-back-button> </ion-nav-back-button>
</ion-nav-bar> </ion-nav-bar>
<ion-content> <ion-content>
<div class="price-display"> <div class="price-display">
<ion-radio class="capitalize" ng-value="'fiat'" ng-model="selectedPriceDisplay" ng-click="save(selectedPriceDisplay)"> <ion-radio ng-value="'fiat'" ng-model="selectedPriceDisplay" ng-click="save(selectedPriceDisplay)">
fiat <span translate>Fiat</span>
</ion-radio> </ion-radio>
<ion-radio class="capitalize" ng-value="'crypto'" ng-model="selectedPriceDisplay" ng-click="save(selectedPriceDisplay)"> <ion-radio ng-value="'crypto'" ng-model="selectedPriceDisplay" ng-click="save(selectedPriceDisplay)">
cryptocurrency <span translate>Cryptocurrency</span>
</ion-radio> </ion-radio>
</div> </div>
</ion-content> </ion-content>

View file

@ -22,6 +22,24 @@
</div> </div>
</div> </div>
<div class="buttons row">
<div class="col">
<div class="button button-outline button-grey-outline" ui-sref="tabs.receive">
<span translate>Receive</span>
</div>
</div>
<div class="col">
<div class="button button-outline button-grey-outline" ng-class="{'ng-hide': walletsWithFunds.length}"
ui-sref="tabs.buyandsell">
<span translate>Buy Bitcoin</span>
</div>
<div class="button button-outline button-grey-outline" ng-class="{'ng-hide': !walletsWithFunds.length}"
ui-sref="tabs.send">
<span translate>Send</span>
</div>
</div>
</div>
<div class="list card homeTip" ng-if="homeTip"> <div class="list card homeTip" ng-if="homeTip">
<div class="item item-icon-right item-heading"> <div class="item item-icon-right item-heading">
<div class="title" translate> <div class="title" translate>

View file

@ -15,7 +15,7 @@
<div class="buttons"> <div class="buttons">
<div class="row"> <div class="row">
<div class="col-40"> <div class="col-40">
<button class="button button-standard button-primary button-outline button-clipboard-paste" ng-click="pasteClipboard()" ng-class="{'contains-address': clipboardHasAddress, 'contains-content': clipboardHasContent}"> <button class="button button-standard button-primary button-outline button-clipboard-paste" ng-click="pasteClipboard()" ng-class="{'contains-address': clipboardHasAddress}">
<span class="icon"></span><br/> <span class="icon"></span><br/>
<span class="non-address" translate>Paste Clipboard</span> <span class="non-address" translate>Paste Clipboard</span>
<span class="address" translate>Paste Address</span> <span class="address" translate>Paste Address</span>

View file

@ -34,7 +34,7 @@
on-hold="hideToggle()" on-hold="hideToggle()"
ng-style="{'transform': amountScale}" ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}"> ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-36">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong> <strong class="size-25">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong>
<div <div
class="size-14 amount-alternative" class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'" ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
@ -48,7 +48,7 @@
on-hold="hideToggle()" on-hold="hideToggle()"
ng-style="{'transform': amountScale}" ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}"> ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-36">{{status.totalBalanceStr}}</strong> <strong class="size-25">{{status.totalBalanceStr}}</strong>
<div <div
class="size-14 amount-alternative" class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'" ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
@ -91,6 +91,22 @@
</button> </button>
</div> </div>
<div class="send-receive-buttons row" ng-if="(status.availableBalanceSat || status.availableBalanceSat === 0) && (buttonsOpacity > 0 || isAndroid)" ng-style="{opacity: buttonsOpacity}">
<div class="col">
<div class="button button-outline button-white-outline" ng-click="goToReceive()">
<span translate>Receive</span>
</div>
</div>
<div class="col">
<div class="button button-outline button-white-outline" ng-if="!status.availableBalanceSat" ng-click="goToBuy()">
<span translate>Buy Bitcoin</span>
</div>
<div class="button button-outline button-white-outline" ng-if="status.availableBalanceSat>0" ng-click="goToSend()">
<span translate>Send</span>
</div>
</div>
</div>
</div> </div>
<div class="wallet-details-wallet-info" ng-style="{opacity: altAmountOpacity}"> <div class="wallet-details-wallet-info" ng-style="{opacity: altAmountOpacity}">
<span ng-include="'views/includes/walletInfo.html'"></span> <span ng-include="'views/includes/walletInfo.html'"></span>
@ -127,7 +143,7 @@
on-hold="hideToggle()" on-hold="hideToggle()"
ng-style="{'transform': amountScale}" ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}"> ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-36">{{status.totalBalanceStr}}</strong> <strong class="size-25">{{status.totalBalanceStr}}</strong>
<div <div
class="size-14 amount-alternative" class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'" ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
@ -142,9 +158,9 @@
on-hold="hideToggle()" on-hold="hideToggle()"
ng-style="{'transform': amountScale}" ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}"> ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-36">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong> <strong class="size-25">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong>
<div <div
class="size-14 amount-alternative" class="size-16 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'" ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}"> ng-style="{opacity: altAmountOpacity}">
{{status.totalBalanceStr}} {{status.totalBalanceStr}}
@ -156,7 +172,7 @@
ng-show="!updateStatusError && wallet.balanceHidden && !wallet.scanning" ng-show="!updateStatusError && wallet.balanceHidden && !wallet.scanning"
on-hold="hideToggle()"> on-hold="hideToggle()">
<strong class="size-24" translate>[Balance Hidden]</strong> <strong class="size-24" translate>[Balance Hidden]</strong>
<div ng-style="{opacity: altAmountOpacity}" class="size-14 amount-alternative" translate> <div ng-style="{opacity: altAmountOpacity}" class="size-16 amount-alternative" translate>
Tap and hold to show Tap and hold to show
</div> </div>
</div> </div>
@ -166,7 +182,7 @@
class="amount__balance" class="amount__balance"
ng-show="!updateStatusError && wallet.scanning"> ng-show="!updateStatusError && wallet.scanning">
<strong class="size-24" translate>[Scanning Funds]</strong> <strong class="size-24" translate>[Scanning Funds]</strong>
<div ng-style="{opacity: altAmountOpacity}" class="size-14 amount-alternative" translate> <div ng-style="{opacity: altAmountOpacity}" class="size-16 amount-alternative" translate>
Please wait Please wait
</div> </div>
</div> </div>
@ -198,6 +214,22 @@
</button> </button>
</div> </div>
<div class="send-receive-buttons row" ng-if="(status.availableBalanceSat || status.availableBalanceSat === 0) && (buttonsOpacity > 0 || isAndroid)" ng-style="{opacity: buttonsOpacity}">
<div class="col">
<div class="button button-outline button-white-outline" ng-click="goToReceive()">
<span translate>Receive</span>
</div>
</div>
<div class="col">
<div class="button button-outline button-white-outline" ng-if="!status.availableBalanceSat" ng-click="goToBuy()">
<span translate>Buy Bitcoin</span>
</div>
<div class="button button-outline button-white-outline" ng-if="status.availableBalanceSat>0" ng-click="goToSend()">
<span translate>Send</span>
</div>
</div>
</div>
</div> </div>
<div class="wallet-details-wallet-info" ng-style="{opacity: altAmountOpacity}"> <div class="wallet-details-wallet-info" ng-style="{opacity: altAmountOpacity}">
<span ng-include="'views/includes/walletInfo.html'"></span> <span ng-include="'views/includes/walletInfo.html'"></span>