diff --git a/Gruntfile.js b/Gruntfile.js
index 342cc85e7..eb4bb2eb0 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -163,7 +163,7 @@ module.exports = function(grunt) {
},
bitanalytics: {
src: [
- 'bitanalytics/bitanalytics-0.1.0.js'
+ 'bitanalytics/bitanalytics.js'
],
dest: 'www/lib/bitanalytics.js'
},
diff --git a/app-template/config-template.xml b/app-template/config-template.xml
index 1c7f5a30a..2f8e3db04 100644
--- a/app-template/config-template.xml
+++ b/app-template/config-template.xml
@@ -72,7 +72,7 @@
-
+
diff --git a/bitanalytics/bitanalytics-0.1.0.js b/bitanalytics/bitanalytics.js
similarity index 97%
rename from bitanalytics/bitanalytics-0.1.0.js
rename to bitanalytics/bitanalytics.js
index db149e481..c8c0d8870 100644
--- a/bitanalytics/bitanalytics-0.1.0.js
+++ b/bitanalytics/bitanalytics.js
@@ -6276,7 +6276,7 @@ var ClickAction = /** @class */ (function (_super) {
}(action_1.default));
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";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -6315,7 +6315,7 @@ var BitAnalytics = /** @class */ (function () {
exports.default = BitAnalytics;
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";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -6560,11 +6560,10 @@ var FirebaseChannel = /** @class */ (function (_super) {
var keys = Object.keys(params);
var keysLength = keys.length;
var sanitized = {};
- for (var i = 0; i < keysLength; i++) {
- var key = keys[i];
+ keys.map(function (key) {
var cleanKey = key.replace('-', '_').replace(/[\W]+/g, '');
sanitized[cleanKey] = params[key];
- }
+ });
return sanitized;
};
return FirebaseChannel;
@@ -6588,13 +6587,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
var channel_1 = __importDefault(require("../channel"));
+var ga_1 = __importDefault(require("../external-libs/ga"));
var GoogleAnalyticsChannel = /** @class */ (function (_super) {
__extends(GoogleAnalyticsChannel, _super);
function GoogleAnalyticsChannel(name, config) {
var _this = _super.call(this, name) || this;
- _this.dataLayer = null;
_this.gaInstance = null;
- _this.trackingId = '';
_this.eventLabels = ['id'];
if (!config.trackingId) {
throw new Error('[BitAnalytics] Google Analytics config is missing tracking ID.');
@@ -6602,8 +6600,12 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
if (config.eventLabels) {
_this.eventLabels = config.eventLabels;
}
- _this.trackingId = config.trackingId;
- _this.setUpGa();
+ _this.gaInstance = new ga_1.default({
+ trackID: config.trackingId,
+ appVersion: config.appVersion,
+ appName: config.appName || 'App'
+ });
+ _this.isReady = true;
return _this;
}
/**
@@ -6612,49 +6614,26 @@ var GoogleAnalyticsChannel = /** @class */ (function (_super) {
*
*/
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) {
- 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++) {
var eventLabel = _a[_i];
if (params[eventLabel]) {
- params.event_label = params[eventLabel];
+ label = params[eventLabel];
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;
}(channel_1.default));
exports.default = GoogleAnalyticsChannel;
-},{"../channel":8}],12:[function(require,module,exports){
+},{"../channel":8,"../external-libs/ga":14}],12:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@@ -6746,6 +6725,207 @@ exports.default = MixpanelChannel;
},{}],14:[function(require,module,exports){
"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) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@@ -6865,7 +7045,7 @@ var LogEventHandlers = /** @class */ (function () {
}());
exports.default = LogEventHandlers;
-},{"./channel-factory":7}],15:[function(require,module,exports){
+},{"./channel-factory":7}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LogEvent = /** @class */ (function () {
diff --git a/i18n/po/template.pot b/i18n/po/template.pot
index 358145a1c..d8281988f 100644
--- a/i18n/po/template.pot
+++ b/i18n/po/template.pot
@@ -201,6 +201,16 @@ msgstr ""
msgid "Price Display"
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
msgid "Amazon.com is not available at this moment. Please try back later."
msgstr ""
@@ -432,6 +442,7 @@ msgid "Buy & Sell Bitcoin"
msgstr ""
#: www/views/tab-send.html:35
+#: src/js/services/buyAndSellService.js:26
msgid "Buy Bitcoin"
msgstr ""
@@ -656,6 +667,7 @@ msgstr ""
#: src/js/controllers/copayers.js:79
#: src/js/controllers/export.js:193
+#: src/js/controllers/confirm.js:41
#: www/views/includes/copyToClipboard.html:4
msgid "Copied to clipboard"
msgstr ""
@@ -2162,6 +2174,10 @@ msgstr ""
msgid "Payment Sent"
msgstr ""
+#: www/views/includes/slideToAcceptSuccess.html:12
+msgid "Share this transaction"
+msgstr ""
+
#: www/views/modals/txp-details.html:32
msgid "Payment accepted, but not yet broadcasted"
msgstr ""
@@ -3725,6 +3741,54 @@ msgstr ""
msgid "{{wallet.m}}-of-{{wallet.n}}"
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
msgid "Address doesn\'t contain currency information, please make sure you are sending the correct currency."
msgstr ""
diff --git a/src/js/controllers/addressbookAdd.js b/src/js/controllers/addressbookAdd.js
index 9529d943e..ff284b234 100644
--- a/src/js/controllers/addressbookAdd.js
+++ b/src/js/controllers/addressbookAdd.js
@@ -21,6 +21,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
$timeout(function() {
var form = addressbookForm;
if (data && form) {
+ if (data.result) {
+ data = data.result;
+ }
data = data.replace(/^bitcoin(cash)?:/, '');
form.address.$setViewValue(data);
form.address.$isValid = true;
@@ -36,9 +39,9 @@ angular.module('copayApp.controllers').controller('addressbookAddController', fu
addressbook.address = translated.legacy;
}
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("contact_created", [{
"coin": $scope.addressbookEntry.coin
diff --git a/src/js/controllers/confirm.js b/src/js/controllers/confirm.js
index 07256c0b2..c98064fcc 100644
--- a/src/js/controllers/confirm.js
+++ b/src/js/controllers/confirm.js
@@ -1,11 +1,12 @@
'use strict';
-angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, gettextCatalog, walletService, platformInfo, lodash, configService, $stateParams, $window, $state, $log, profileService, bitcore, bitcoreCash, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bitcoinCashJsService, bwcError, txConfirmNotification, externalLinkService, firebaseEventsService, soundService) {
+angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $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 FEE_TOO_HIGH_LIMIT_PER = 15;
var tx = {};
+ var lastTxId = "";
// Config Related values
var config = configService.getSync();
@@ -25,6 +26,17 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}, 10);
}
+ $scope.shareTransaction = function() {
+ var explorerTxUrl = 'https://explorer.bitcoin.com/'+tx.coin+'/tx/'+lastTxId;
+ if (platformInfo.isCordova) {
+ var text = 'Take a look at this Bitcoin transaction here: '+explorerTxUrl;
+ window.plugins.socialsharing.share(text, null, null, null);
+ } else {
+ ionicToast.show(gettextCatalog.getString('Copied to clipboard'), 'bottom', false, 3000);
+ clipboardService.copyToClipboard(explorerTxUrl);
+ }
+ };
+
$scope.showWalletSelector = function() {
$scope.walletSelector = true;
refresh();
@@ -652,6 +664,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txConfirmNotification.subscribe(wallet, {
txid: txp.txid
});
+ lastTxId = txp.txid;
}
}, onSendStatusChange);
};
@@ -683,9 +696,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
soundService.play('misc/payment_sent.mp3');
}
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
diff --git a/src/js/controllers/customAmount.js b/src/js/controllers/customAmount.js
index d74ebca30..5d22d40fb 100644
--- a/src/js/controllers/customAmount.js
+++ b/src/js/controllers/customAmount.js
@@ -65,6 +65,14 @@ angular.module('copayApp.controllers').controller('customAmountController', func
var currency = parsedAmount.currency;
$scope.amountUnitStr = parsedAmount.amountUnitStr;
+ configService.whenAvailable(function (config) {
+ $scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
+
+ $timeout(function () {
+ $scope.$apply();
+ });
+ });
+
if (currency != 'BTC' && currency != 'BCH') {
// Convert to BTC or BCH
var config = configService.getSync().wallet.settings;
diff --git a/src/js/controllers/preferencesNotifications.js b/src/js/controllers/preferencesNotifications.js
index edfb983b5..a9a833ff7 100644
--- a/src/js/controllers/preferencesNotifications.js
+++ b/src/js/controllers/preferencesNotifications.js
@@ -76,9 +76,9 @@ angular.module('copayApp.controllers').controller('preferencesNotificationsContr
emailService.updateEmail(opts);
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("settings_email_notification_toggle", [{
"toggle": $scope.emailNotifications.value
diff --git a/src/js/controllers/tab-home.js b/src/js/controllers/tab-home.js
index a04820ebd..07b01b974 100644
--- a/src/js/controllers/tab-home.js
+++ b/src/js/controllers/tab-home.js
@@ -224,6 +224,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
cb();
}
}
+ $scope.walletsWithFunds = profileService.getWallets({hasFunds: true});
});
});
};
diff --git a/src/js/controllers/tab-receive.js b/src/js/controllers/tab-receive.js
index 3c48818b6..190f1b752 100644
--- a/src/js/controllers/tab-receive.js
+++ b/src/js/controllers/tab-receive.js
@@ -144,9 +144,9 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
}
$scope.paymentReceivedCoin = $scope.wallet.coin;
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("transfer_success", [{
"coin": $scope.wallet.coin,
@@ -232,10 +232,14 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
if (!$scope.wallets[0]) return;
- // select first wallet if no wallet selected previously
- var selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
+ var selectedWallet = null;
+ if (data.stateParams.walletId) { // from walletDetails
+ selectedWallet = checkSelectedWallet(profileService.getWallet(data.stateParams.walletId), $scope.wallets);
+ } else {
+ // select first wallet if no wallet selected previously
+ selectedWallet = checkSelectedWallet($scope.wallet, $scope.wallets);
+ }
$scope.onWalletSelect(selectedWallet);
-
$scope.showShareButton = platformInfo.isCordova ? (platformInfo.isIOS ? 'iOS' : 'Android') : null;
listeners = [
diff --git a/src/js/controllers/tab-settings.js b/src/js/controllers/tab-settings.js
index 4d0636d53..494d63cc5 100644
--- a/src/js/controllers/tab-settings.js
+++ b/src/js/controllers/tab-settings.js
@@ -16,7 +16,7 @@ angular.module('copayApp.controllers').controller('tabSettingsController', funct
isoCode: config.wallet.settings.alternativeIsoCode
};
- $scope.selectedPriceDisplay = config.wallet.settings.priceDisplay;
+ $scope.selectedPriceDisplay = config.wallet.settings.priceDisplay === 'crypto' ? gettextCatalog.getString('Cryptocurrency') : gettextCatalog.getString('Fiat');
// TODO move this to a generic service
bitpayAccountService.getAccounts(function(err, data) {
diff --git a/src/js/controllers/walletDetails.js b/src/js/controllers/walletDetails.js
index 24237f6c9..d3308ff1e 100644
--- a/src/js/controllers/walletDetails.js
+++ b/src/js/controllers/walletDetails.js
@@ -12,9 +12,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
$scope.isAndroid = platformInfo.isAndroid;
$scope.isIOS = platformInfo.isIOS;
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_details_open", [], [channel]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
@@ -342,9 +342,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
top = TOP_BALANCE_BUTTON;
}
- var amountTop = ((amountScale - 0.7) / 0.7) * top;
- if (amountTop < -10) {
- amountTop = -10;
+ var amountTop = ((amountScale - 0.80) / 0.80) * top;
+ if (amountTop < -2) {
+ amountTop = -2;
}
if (amountTop > top) {
amountTop = top;
@@ -353,6 +353,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var t = amountTop;
$scope.altAmountOpacity = (amountHeight - 100) / 80;
+ $scope.buttonsOpacity = (amountHeight - 140) / 70;
$window.requestAnimationFrame(function() {
$scope.amountHeight = amountHeight + 'px';
$scope.contentMargin = contentMargin + 'px';
@@ -469,4 +470,30 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function rgbToHex(r, g, 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');
+ });
+ };
});
diff --git a/src/js/directives/slideToAcceptSuccess.js b/src/js/directives/slideToAcceptSuccess.js
index fbd588bfe..ec6321b95 100644
--- a/src/js/directives/slideToAcceptSuccess.js
+++ b/src/js/directives/slideToAcceptSuccess.js
@@ -9,12 +9,12 @@ angular.module('copayApp.directives')
scope: {
isShown: '=slideSuccessShow',
onConfirm: '&slideSuccessOnConfirm',
- hideOnConfirm: '=slideSuccessHideOnConfirm'
+ hideOnConfirm: '=slideSuccessHideOnConfirm',
+ onShare: '=slideSuccessOnShare',
},
link: function(scope, element, attrs) {
-
- scope.isWindowsPhoneApp = platformInfo.isCordova && platformInfo.isWP;
-
+ scope.isCordova = platformInfo.isCordova;
+ scope.hasShareFunction = typeof scope.onShare === 'function';
var elm = element[0];
elm.style.display = 'none';
scope.$watch('isShown', function() {
@@ -32,6 +32,9 @@ angular.module('copayApp.directives')
elm.style.display = 'none';
}
};
+ scope.onShareButtonClick = function() {
+ scope.onShare();
+ }
}
};
});
diff --git a/src/js/routes.js b/src/js/routes.js
index 8a8adc964..dea46a2cf 100644
--- a/src/js/routes.js
+++ b/src/js/routes.js
@@ -236,7 +236,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.receive', {
- url: '/receive',
+ url: '/receive/:walletId',
views: {
'tab-receive': {
controller: 'tabReceiveController',
@@ -1231,9 +1231,9 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
});
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
// Send a log to test
diff --git a/src/js/services/bitcoincomService.js b/src/js/services/bitcoincomService.js
index 051123111..68fd51a8a 100644
--- a/src/js/services/bitcoincomService.js
+++ b/src/js/services/bitcoincomService.js
@@ -1,5 +1,5 @@
'use strict';
-angular.module('copayApp.services').factory('bitcoincomService', function(platformInfo, nextStepsService) {
+angular.module('copayApp.services').factory('bitcoincomService', function(gettextCatalog, nextStepsService, platformInfo) {
var root = {};
var credentials = {};
@@ -19,42 +19,42 @@ angular.module('copayApp.services').factory('bitcoincomService', function(platfo
var cashGamesItem = {
name: 'games',
- title: 'Bitcoin Cash Games',
+ title: gettextCatalog.getString('Bitcoin Cash Games'),
icon: 'icon-games',
href: 'https://cashgames.bitcoin.com'
};
var newsItem = {
name: 'news',
- title: 'News',
+ title: gettextCatalog.getString('News'),
icon: 'icon-news',
href: 'https://news.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=News'
};
var poolItem = {
name: 'pool',
- title: 'Mining Pool',
+ title: gettextCatalog.getString('Mining Pool'),
icon: 'icon-mining',
href: 'https://pool.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Pool'
};
var toolsItem = {
name: 'tools',
- title: 'Tools',
+ title: gettextCatalog.getString('Tools'),
icon: 'icon-tools',
href: 'https://tools.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Tools'
};
var priceChartItem = {
name: 'pricechart',
- title: 'Bitcoin Price Charts',
+ title: gettextCatalog.getString('Bitcoin Price Charts'),
icon: 'icon-chart',
sref: 'tabs.pricechart',
};
var faucetItem = {
name: 'faucet',
- title: 'Free Bitcoin Cash',
+ title: gettextCatalog.getString('Free Bitcoin Cash'),
icon: 'icon-faucet',
href: 'https://free.bitcoin.com/?utm_source=WalletApp&utm_medium=' + os + '&utm_campaign=Faucet'
};
diff --git a/src/js/services/buyAndSellService.js b/src/js/services/buyAndSellService.js
index 65a9a93c7..e35403131 100644
--- a/src/js/services/buyAndSellService.js
+++ b/src/js/services/buyAndSellService.js
@@ -1,6 +1,6 @@
'use strict';
-angular.module('copayApp.services').factory('buyAndSellService', function($log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
+angular.module('copayApp.services').factory('buyAndSellService', function(gettextCatalog, $log, servicesService, lodash, $ionicScrollDelegate, $timeout) {
var root = {};
var services = [];
var linkedServices = [];
@@ -23,7 +23,7 @@ angular.module('copayApp.services').factory('buyAndSellService', function($log,
if (linkedServices.length == 0) {
servicesService.register({
- title: 'Buy Bitcoin',
+ title: gettextCatalog.getString('Buy Bitcoin'),
name: 'buyandsell',
icon: 'icon-buy-bitcoin2',
sref: 'tabs.buyandsell',
diff --git a/src/js/services/clipboardService.js b/src/js/services/clipboardService.js
index ebd30c28c..075cb749a 100644
--- a/src/js/services/clipboardService.js
+++ b/src/js/services/clipboardService.js
@@ -11,10 +11,15 @@ angular.module('copayApp.services').factory('clipboardService', function ($http,
cordova.plugins.clipboard.copy(data);
} else if (platformInfo.isNW) {
nodeWebkitService.writeToClipboard(data);
+ } else if (navigator && navigator.clipboard) {
+ $log.debug("Use navigator clipboard.")
+ navigator.clipboard.writeText(data).catch(err => {
+ $log.debug("Clipboard writing is not supported in your browser..");
+ });
} else if (clipboard.supported) {
clipboard.copyText(data);
} else {
- // No supported
+ // Not supported
return;
}
};
diff --git a/src/js/services/communityService.js b/src/js/services/communityService.js
index 24cc99474..93a4afe5e 100644
--- a/src/js/services/communityService.js
+++ b/src/js/services/communityService.js
@@ -1,5 +1,5 @@
'use strict'
-angular.module('copayApp.services').factory('communityService', function(configService, $log, lodash) {
+angular.module('copayApp.services').factory('communityService', function(configService, gettextCatalog, $log, lodash) {
var root = {};
var services = [];
@@ -37,14 +37,14 @@ angular.module('copayApp.services').factory('communityService', function(configS
var bchRedditItem = {
name: 'bchreddit',
- title: 'Bitcoin Cash Reddit',
+ title: gettextCatalog.getString('Bitcoin Cash Reddit'),
icon: 'icon-reddit-white',
href: 'http://reddit.com/r/btc'
};
var bitcoincomTwitterItem = {
name: 'bitcoincomTwitter',
- title: 'Bitcoin.com Twitter',
+ title: gettextCatalog.getString('Bitcoin.com Twitter'),
icon: 'icon-twitter-white',
href: 'https://twitter.com/BTCTN'
};
diff --git a/src/js/services/profileService.js b/src/js/services/profileService.js
index c86d263f2..113289104 100644
--- a/src/js/services/profileService.js
+++ b/src/js/services/profileService.js
@@ -427,9 +427,9 @@ angular.module('copayApp.services')
}, function(err, secret) {
if (err) return bwcError.cb(err, gettextCatalog.getString('Error creating wallet'), cb);
- var channel = "firebase";
- if (platformInfo.isNW) {
- channel = "ga";
+ var channel = "ga";
+ if (platformInfo.isCordova) {
+ channel = "firebase";
}
var log = new window.BitAnalytics.LogEvent("wallet_created", [{
"coin": opts.coin
diff --git a/src/js/services/shapeshiftService.js b/src/js/services/shapeshiftService.js
index 4a77d8db0..5396f4fa5 100644
--- a/src/js/services/shapeshiftService.js
+++ b/src/js/services/shapeshiftService.js
@@ -1,4 +1,5 @@
'use strict';
+
angular.module('copayApp.services').factory('shapeshiftService', function ($http, $interval, $log, lodash, moment, ongoingProcess, shapeshiftApiService, storageService, configService, incomingData, platformInfo, servicesService) {
var root = {};
root.ShiftState = 'Shift';
@@ -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;
});
diff --git a/src/js/services/txFormatService.js b/src/js/services/txFormatService.js
index ebcb3886a..1932ebd2a 100644
--- a/src/js/services/txFormatService.js
+++ b/src/js/services/txFormatService.js
@@ -201,7 +201,7 @@ angular.module('copayApp.services').factory('txFormatService', function($filter,
var alternativeIsoCode = config.alternativeIsoCode;
// If fiat currency
- if (currency != 'BCH' && currency != 'BTC' && currency != 'sat') {
+ if (currency && currency.toUpperCase() != 'BCH' && currency.toUpperCase() != 'BTC' && currency != 'sat') {
amountUnitStr = $filter('formatFiatAmount')(amount) + ' ' + currency;
amountSat = rateService.fromFiat(amount, currency, coin).toFixed(0);
} else if (currency == 'sat') {
diff --git a/src/sass/buttons.scss b/src/sass/buttons.scss
index a8512ae64..ab066b734 100644
--- a/src/sass/buttons.scss
+++ b/src/sass/buttons.scss
@@ -72,5 +72,17 @@
&.activated {
color: #FFF;
}
+ &-outline {
+ @include button-style(transparent, #FFFFFF, #FAFAFA, #FFF, #FFFFFF);
+ @include button-outline(#FFFFFF);
+ background: none;
+ box-shadow: none;
+ }
+ }
+ &-grey-outline {
+ @include button-style(transparent, #727272, #FAFAFA, #727272, #727272);
+ @include button-outline(#727272);
+ background: none;
+ box-shadow: none;
}
}
\ No newline at end of file
diff --git a/src/sass/qr.scss b/src/sass/qr.scss
index 62fd12eb7..5df26e37b 100644
--- a/src/sass/qr.scss
+++ b/src/sass/qr.scss
@@ -5,8 +5,8 @@ qrcode {
content: "";
background-size: 100% 100%;
display: block;
- left: 88px;
- margin-top: 88px;
+ left: calc(50% - 22px);
+ margin-top: calc(50% - 22px);
width: 44px;
height: 44px;
position:absolute;
diff --git a/src/sass/shame.scss b/src/sass/shame.scss
index 07ac2dedf..5a17c5f1f 100644
--- a/src/sass/shame.scss
+++ b/src/sass/shame.scss
@@ -233,6 +233,10 @@ input[type=number] {
font-size: 24px;
}
+.size-25 {
+ font-size: 25px;
+}
+
.size-28 {
font-size: 28px;
}
diff --git a/src/sass/views/custom-amount.scss b/src/sass/views/custom-amount.scss
index b9bf65459..17973101d 100644
--- a/src/sass/views/custom-amount.scss
+++ b/src/sass/views/custom-amount.scss
@@ -26,16 +26,10 @@
height: 100%;
.qr-code {
text-align: center;
- margin-top: 24vh;
- margin-bottom: 7vh;
- @media(max-height: 800px) {
- margin-top: 18vh;
- }
- @media(max-height: 700px) {
- margin-top: 14vh;
- }
- @media(max-height: 600px) {
- margin-top: 8vh;
+ margin-top: 6px;
+ qrcode canvas {
+ height: 30vh;
+ max-height: 220px;
}
}
.info {
@@ -91,5 +85,34 @@
.address-types {
text-align: center;
}
+
+ .amount {
+ margin-top: 20vh;
+ margin-bottom: 4vh;
+ @media(max-height: 800px) {
+ margin-top: 12vh;
+ margin-bottom: 6vh;
+ }
+ @media(max-height: 700px) {
+ margin-top: 10vh;
+ margin-bottom: 4vh;
+ }
+ @media(max-height: 600px) {
+ margin-top: 6vh;
+ margin-bottom: 2vh;
+
+ }
+ width: 100%;
+ text-align: center;
+ //padding-top: 30px;
+ display: block;
+ align-items: center;
+ justify-content: center;
+
+ &-alternative {
+ line-height: 36px;
+ }
+ }
+
}
}
diff --git a/src/sass/views/includes/slideToAcceptSuccess.scss b/src/sass/views/includes/slideToAcceptSuccess.scss
index 68312c7a4..f64dd6154 100644
--- a/src/sass/views/includes/slideToAcceptSuccess.scss
+++ b/src/sass/views/includes/slideToAcceptSuccess.scss
@@ -12,12 +12,6 @@ slide-to-accept-success {
.slide-success {
$duration: 400ms;
- &__windows-background {
- background: $v-success-bg-color;
- height: 100%;
- width: 100%;
- position: fixed;
- }
&__background {
$start-radius: 5;
$scale-factor: 20;
@@ -40,9 +34,11 @@ slide-to-accept-success {
&__content {
position: relative;
z-index: 1;
- margin-top: -20vh;
+ margin-top: -10vh;
> img {
+ width: 45vw;
+ max-width: 166px;
margin-bottom: 1.8rem;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
@@ -59,7 +55,7 @@ slide-to-accept-success {
&__header {
color: #FFFFFF;
- font-size: 26px;
+ font-size: 29px;
-webkit-transform: translateY(5rem);
transform: translateY(5rem);
opacity: 0;
@@ -72,6 +68,26 @@ slide-to-accept-success {
opacity: 1;
}
}
+ &__share {
+ transition: transform $duration ease, opacity $duration ease;
+ transition-delay: 600ms;
+ opacity: 0;
+ margin-top: 15vh;
+ span {
+ color: #FFF;
+ font-size: 22px;
+ height: 28px;
+ }
+ img {
+ height: 28px;
+ width: auto;
+ vertical-align: bottom;
+ margin-right: 4px;
+ }
+ &.reveal {
+ opacity: 0.79;
+ }
+ }
}
&__footer {
@@ -98,11 +114,11 @@ slide-to-accept-success {
&__btn {
display: block;
color: #FFFFFF;
- font-size: 18px;
+ font-size: 22px;
font-weight: 600;
letter-spacing: 2.86px;
- padding: 1rem 0 1.1rem;
- border-top: 1px solid rgba(255, 255, 255, .45);
+ padding: 2rem 0 2.1rem;
+ border-top: 1px solid rgba(255, 255, 255, 0.25);
cursor: pointer;
}
}
diff --git a/src/sass/views/tab-home.scss b/src/sass/views/tab-home.scss
index 66a2f1d58..708ff4fad 100644
--- a/src/sass/views/tab-home.scss
+++ b/src/sass/views/tab-home.scss
@@ -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 {
vertical-align: middle;
margin-right: 5px;
diff --git a/src/sass/views/walletDetails.scss b/src/sass/views/walletDetails.scss
index 9e651f871..6b760bbc4 100644
--- a/src/sass/views/walletDetails.scss
+++ b/src/sass/views/walletDetails.scss
@@ -135,11 +135,12 @@
&.status-bar {
margin-top: 20px;
+ margin-top: env(safe-area-inset-top);
}
}
.bar-header {
border: 0;
- background: none;
+ background: rgb(238, 182, 64);
.title, .button {
color: #fff;
}
@@ -153,7 +154,7 @@
ion-content {
&.collapsible {
- margin-top: 210px;
+ margin-top: 230px;
}
padding-top: 0;
@@ -190,12 +191,34 @@
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 {
width: 100%;
text-align: center;
color: #fff;
- height: 210px;
+ height: 230px;
padding-top: 40px;
display: block;
align-items: center;
diff --git a/www/img/icon-sent-successful.svg b/www/img/icon-sent-successful.svg
new file mode 100644
index 000000000..070357ddf
--- /dev/null
+++ b/www/img/icon-sent-successful.svg
@@ -0,0 +1,10 @@
+
diff --git a/www/img/icon-share-white.svg b/www/img/icon-share-white.svg
new file mode 100644
index 000000000..eeb3e7b6b
--- /dev/null
+++ b/www/img/icon-share-white.svg
@@ -0,0 +1,17 @@
+
+
+
+
diff --git a/www/views/confirm.html b/www/views/confirm.html
index 1def16389..0ad56e6c4 100644
--- a/www/views/confirm.html
+++ b/www/views/confirm.html
@@ -120,6 +120,7 @@
Payment Sent
Proposal Created
diff --git a/www/views/customAmount.html b/www/views/customAmount.html
index a4f2d57c9..b361a6da9 100644
--- a/www/views/customAmount.html
+++ b/www/views/customAmount.html
@@ -30,8 +30,22 @@
Return To Address
+
+
+
{{amountUnitStr}}
+
+ {{altAmountStr | uppercase}}
+
+
+
+
{{altAmountStr | uppercase}}
+
+ {{amountUnitStr}}
+
+
+
-
+
@@ -57,12 +71,6 @@
{{address}}
-
- Amount
-
- {{amountUnitStr}} - {{altAmountStr}}
-
-
diff --git a/www/views/includes/slideToAcceptSuccess.html b/www/views/includes/slideToAcceptSuccess.html
index 923eab25c..9995001ae 100644
--- a/www/views/includes/slideToAcceptSuccess.html
+++ b/www/views/includes/slideToAcceptSuccess.html
@@ -1,13 +1,16 @@
+ ng-class="{'fill-screen': fillScreen}">
-

+

+
+
Share this transaction
+
+
+
diff --git a/www/views/tab-send.html b/www/views/tab-send.html
index 7bf4d47be..20198c7f0 100644
--- a/www/views/tab-send.html
+++ b/www/views/tab-send.html
@@ -15,7 +15,7 @@