Integration BitAnalytics

This commit is contained in:
Jean-Baptiste Dominguez 2018-07-13 16:15:04 +09:00
commit 4e1ddfe883
10 changed files with 558 additions and 115 deletions

View file

@ -6069,10 +6069,225 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var click_action_1 = __importDefault(require("./actions/click-action"));
var ActionFactory = /** @class */ (function () {
function ActionFactory() {
}
ActionFactory.createAction = function (type, config) {
// Check if the action is available
if (ActionFactory.classDictionary[type] == undefined) {
throw new Error('[BitAnalytics] ' + type + ' is not available.');
}
else {
// Create a action
var action = Object.create(ActionFactory.classDictionary[type].prototype);
action.constructor.apply(action, [config]);
action = action;
return action;
}
};
ActionFactory.classDictionary = {
'click': click_action_1.default
};
return ActionFactory;
}());
exports.default = ActionFactory;
},{"./actions/click-action":5}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ActionHandlers = /** @class */ (function () {
function ActionHandlers() {
this.actions = [];
var self = this;
var callback = function () {
if (self.timeout) {
clearTimeout(self.timeout);
}
self.timeout = setTimeout(function () {
console.log('[BitAnalytics] Content modified, refreshing trackers');
self.refreshTrackers();
self.timeout = undefined;
}, 300);
};
if (MutationObserver) {
var targetNode = document.getElementsByTagName('body');
var config = { attributes: true, childList: true, subtree: true };
// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode[0], config);
}
else {
window.addEventListener("DOMSubtreeModified", callback);
}
}
/**
*
* Public methods
*
*/
ActionHandlers.prototype.refreshTrackers = function () {
this.actions.map(function (action) {
try {
action.stopTracking();
}
catch (err) {
console.log(err);
}
try {
action.startTracking();
}
catch (err) {
console.log(err);
}
});
};
ActionHandlers.prototype.trackAction = function (action) {
this.actions.push(action);
};
return ActionHandlers;
}());
exports.default = ActionHandlers;
},{}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Action = /** @class */ (function () {
function Action(config) {
if (!config.name) {
throw new Error('[BitAnalytics] Action should have a name config : { name : ... }');
}
this.name = config.name;
this.isTracking = false;
}
return Action;
}());
exports.default = Action;
},{}],5:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var action_1 = __importDefault(require("../action"));
var log_event_handlers_1 = __importDefault(require("../log-event-handlers"));
var log_event_1 = __importDefault(require("../log-event"));
var ClickAction = /** @class */ (function (_super) {
__extends(ClickAction, _super);
function ClickAction(config) {
var _this = _super.call(this, config) || this;
_this.params = [];
if (!config.class || !config.channels) {
throw new Error('[BitAnalytics] ClickAction should have a config like this : { class : ..., channels: ... }');
}
if (config.params) {
_this.params = config.params;
}
_this.class = config.class;
_this.channels = config.channels;
var self = _this;
_this.listener = function (event) {
/*console.log('on click');
console.log(event.target.id);
console.log(event.target.outerHTML);
console.log(event.target.outerText);*/
var params = {};
var target = _this.searchTarget(event.srcElement);
// If I found my element, that should happen 100%
if (target) {
self.params.map(function (param) {
var value = target[param];
if (value) {
params[param] = value;
}
else {
var item = target.attributes.getNamedItem(param);
if (item) {
params[param] = item.value;
}
}
});
}
var logEvent = new log_event_1.default(self.name, [params], self.channels);
log_event_handlers_1.default.sharedInstance().postEvent(logEvent);
};
_this.isTracking = false;
return _this;
}
/**
*
* Private methods
*
*/
ClickAction.prototype.searchTarget = function (element) {
if (element && element.classList && element.classList.contains(this.class)) {
return element;
}
else if (element.parentElement) {
return this.searchTarget(element.parentElement);
}
else {
return undefined;
}
};
/**
*
* Public methods
*
*/
ClickAction.prototype.startTracking = function () {
if (this.isTracking) {
throw new Error('[BitAnalytics] The tacking is already started');
}
this.isTracking = true;
var elements = document.getElementsByClassName(this.class);
// Add event listener to all the elements found
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
console.log('init ' + this.name);
element.addEventListener('click', this.listener);
}
};
ClickAction.prototype.stopTracking = function () {
if (!this.isTracking) {
throw new Error('[BitAnalytics] The tacking is already stopped');
}
var elements = document.getElementsByClassName(this.class);
// Add event listener to all the elements found
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.removeEventListener('click', this.listener);
}
this.isTracking = false;
};
return ClickAction;
}(action_1.default));
exports.default = ClickAction;
},{"../action":4,"../log-event":15,"../log-event-handlers":14}],6:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var log_event_handlers_1 = __importDefault(require("./log-event-handlers"));
var log_event_1 = __importDefault(require("./log-event"));
var action_factory_1 = __importDefault(require("./action-factory"));
var adjust_channel_1 = __importDefault(require("./channels/adjust-channel"));
var mixpanel_channel_1 = __importDefault(require("./channels/mixpanel-channel"));
var action_handlers_1 = __importDefault(require("./action-handlers"));
var channels;
(function (channels) {
channels.AdjustChannel = adjust_channel_1.default;
@ -6082,12 +6297,13 @@ var BitAnalytics = /** @class */ (function () {
function BitAnalytics() {
}
BitAnalytics.initialize = function (os, appVersion, channelConfigs) {
if (typeof window === 'undefined') {
console.error('BitAnalytics can be used only in a web browser.');
return;
if (window == undefined) {
console.error('[BitAnalytics] BitAnalytics cannot be integrated in window.');
}
BitAnalytics.LogEventHandlers = new log_event_handlers_1.default(os, appVersion, channelConfigs);
BitAnalytics.ActionHandlers = new action_handlers_1.default();
BitAnalytics.LogEvent = log_event_1.default;
BitAnalytics.ActionFactory = action_factory_1.default;
};
BitAnalytics.main = function () {
if (window) {
@ -6099,42 +6315,43 @@ var BitAnalytics = /** @class */ (function () {
exports.default = BitAnalytics;
BitAnalytics.main();
},{"./channels/adjust-channel":5,"./channels/mixpanel-channel":7,"./log-event":10,"./log-event-handlers":9}],3:[function(require,module,exports){
},{"./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){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var mixpanel_channel_1 = __importDefault(require("./channels/mixpanel-channel"));
var firebase_channel_1 = __importDefault(require("./channels/firebase-channel"));
var adjust_channel_1 = __importDefault(require("./channels/adjust-channel"));
var firebase_channel_1 = __importDefault(require("./channels/firebase-channel"));
var ga_channel_1 = __importDefault(require("./channels/ga-channel"));
var mixpanel_channel_1 = __importDefault(require("./channels/mixpanel-channel"));
var ChannelFactory = /** @class */ (function () {
function ChannelFactory() {
}
ChannelFactory.createChannel = function (name, config) {
// Check if the channel is available
if (ChannelFactory.classDictionary[name] == undefined) {
throw new DOMException(name + ' is not available.');
throw new Error('[BitAnalytics] ' + name + ' is not available.');
}
else {
// Create a channel
var channel = Object.create(ChannelFactory.classDictionary[name].prototype);
channel.constructor.apply(channel, [name, config]);
channel = channel;
console.log(channel);
return channel;
}
};
ChannelFactory.classDictionary = {
'mixpanel': mixpanel_channel_1.default,
'adjust': adjust_channel_1.default,
'firebase': firebase_channel_1.default,
'adjust': adjust_channel_1.default
'ga': ga_channel_1.default,
'mixpanel': mixpanel_channel_1.default
};
return ChannelFactory;
}());
exports.default = ChannelFactory;
},{"./channels/adjust-channel":5,"./channels/firebase-channel":6,"./channels/mixpanel-channel":7}],4:[function(require,module,exports){
},{"./channels/adjust-channel":9,"./channels/firebase-channel":10,"./channels/ga-channel":11,"./channels/mixpanel-channel":12}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Channel = /** @class */ (function () {
@ -6143,14 +6360,6 @@ var Channel = /** @class */ (function () {
this.queue = new Array();
this.name = name;
}
/**
*
* Public methods
*
*/
Channel.prototype.getName = function () {
return this.name;
};
/**
*
* Protected methods
@ -6169,7 +6378,7 @@ var Channel = /** @class */ (function () {
}());
exports.default = Channel;
},{}],5:[function(require,module,exports){
},{}],9:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@ -6185,43 +6394,119 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require('../lib/adjust');
var channel_1 = __importDefault(require("../channel"));
// Loading Adjust websdk
require('../external-libs/adjust');
var AdjustChannel = /** @class */ (function (_super) {
__extends(AdjustChannel, _super);
function AdjustChannel(name, config) {
var _this = _super.call(this, name) || this;
_this.device_ids = {
"gps_adid": "3ea5fac8-cf01-47d5-8aec-9a1354f5e84a"
};
_this.eventTypes = {
"wallet_created": "nd3dg5"
};
if (!config.token) {
throw new DOMException('Config incorrect.');
throw new Error('[BitAnalytics] Adjust config is missing token.');
}
if (Adjust) {
_this.adjust = new Adjust("au1onbhgg5q8", "sandbox", "android");
//this.adjust.trackSession(this.device_ids);
_this.isReady = true;
console.log('Adjust initialised.');
if (!config.eventTypes) {
throw new Error('[BitAnalytics] Adjust config is missing event types.');
}
else {
console.log('Adjust missing.');
if (!Adjust) {
throw new Error('[BitAnalytics] Adjust cordova plugin is not installed correctly.');
}
_this.eventTypes = config.eventTypes;
var os = _this.adjustedOs(config.os);
_this.advertisingId = _this.getAdvertisingId(os);
console.log('Advertising ID for adjust: ' + _this.advertisingId);
// TODO: Different initialisation for Cordova.
var sessionParams = {
app_version: config.appVersion,
app_version_short: config.appVersion,
os_name: os
};
_this.addAdvertisingId(os, sessionParams);
var environment = config.environment || 'production';
_this.adjustInstance = new Adjust(config.token, environment, os);
_this.adjustInstance.trackSession(sessionParams);
_this.isReady = true;
return _this;
}
/**
*
* Public methods
*
*/
AdjustChannel.prototype.postEvent = function (name, params) {
//var result = this.mixpanelInstance.track(logEvent.name);
if (this.isReady) {
this.adjust.trackEvent('nd3dg5', this.device_ids);
var eventType = this.eventTypes[name];
// Each event needs to be added on adjust, and config for adjust.
if (!eventType) {
throw new Error('This event name does not exist on Adjust.');
}
params.os = this.adjustedOs(params.os);
this.addAdvertisingId(params.os, params);
this.adjustInstance.trackEvent(eventType, params);
}
};
/**
*
* Private methods
*
*/
AdjustChannel.prototype.addAdvertisingId = function (os, params) {
if (os === 'ios') {
params.idfa = this.advertisingId;
}
else if (os === 'android') {
params.gps_adid = this.advertisingId;
}
else {
params.win_hwid = this.advertisingId;
params.win_naid = this.advertisingId;
params.win_adid = this.advertisingId;
}
};
// Desktop version will pretend to be Windows
AdjustChannel.prototype.adjustedOs = function (os) {
if (os === 'ios' || os === 'android') {
return os;
}
else {
return 'wstore';
}
};
AdjustChannel.prototype.generateRandomGuid = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
// Example: 107e8ea14329d4a2194ebbb6dc0c0fd7
AdjustChannel.prototype.generateWindowsAdvertisingId = function () {
var id = '';
for (var i = 0; i < 32; i++) {
id += Math.floor(Math.random() * 16).toString(16);
}
return id;
};
// https://docs.adjust.com/en/event-tracking/
AdjustChannel.prototype.getAdvertisingId = function (os) {
var adid = localStorage.getItem('adid');
if (!adid) {
if (os === 'ios') {
adid = this.generateRandomGuid().toUpperCase();
}
else if (os === 'android') {
adid = this.generateRandomGuid();
}
else {
adid = this.generateWindowsAdvertisingId();
}
localStorage.setItem('adid', adid);
}
return adid;
};
return AdjustChannel;
}(channel_1.default));
exports.default = AdjustChannel;
},{"../channel":4,"../lib/adjust":8}],6:[function(require,module,exports){
},{"../channel":8,"../external-libs/adjust":13}],10:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@ -6245,16 +6530,21 @@ var FirebaseChannel = /** @class */ (function (_super) {
/**
* Firebase available only on ios and android
*/
if (config['os'] != 'android' && config['os'] != 'ios') {
throw new DOMException('Firebase is not supported on ' + config['os']);
if (config.os != 'android' && config.os != 'ios') {
throw new Error('[BitAnalytics] Firebase is not supported on ' + config.os);
}
if (!window.FirebasePlugin) {
throw new DOMException('Firebase cordova plugin is not installed correctly.');
throw new Error('[BitAnalytics] Firebase cordova plugin is not installed correctly.');
}
_this.firebaseInstance = window.FirebasePlugin;
_this.isReady = true;
return _this;
}
/**
*
* Public methods
*
*/
FirebaseChannel.prototype.postEvent = function (name, params) {
var _this = this;
if (!this.isReady) {
@ -6268,7 +6558,90 @@ var FirebaseChannel = /** @class */ (function (_super) {
}(channel_1.default));
exports.default = FirebaseChannel;
},{"../channel":4}],7:[function(require,module,exports){
},{"../channel":8}],11:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var channel_1 = __importDefault(require("../channel"));
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.');
}
if (config.eventLabels) {
_this.eventLabels = config.eventLabels;
}
_this.trackingId = config.trackingId;
_this.setUpGa();
return _this;
}
/**
*
* Public methods
*
*/
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;
for (var _i = 0, _a = this.eventLabels; _i < _a.length; _i++) {
var eventLabel = _a[_i];
if (params[eventLabel]) {
params.event_label = params[eventLabel];
break;
}
}
this.gtag('event', name, params);
}
};
/**
*
* 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){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
@ -6291,12 +6664,17 @@ var MixpanelChannel = /** @class */ (function (_super) {
function MixpanelChannel(name, config) {
var _this = _super.call(this, name) || this;
if (!config.token) {
throw new DOMException('Config incorrect.');
throw new DOMException('[BitAnalytics] Config incorrect.');
}
_this.mixpanelInstance = mixpanel;
mixpanel.init(config.token, config.config);
return _this;
}
/**
*
* Public methods
*
*/
MixpanelChannel.prototype.postEvent = function (name, params) {
var result = this.mixpanelInstance.track(name);
};
@ -6304,7 +6682,7 @@ var MixpanelChannel = /** @class */ (function (_super) {
}(channel_1.default));
exports.default = MixpanelChannel;
},{"../channel":4,"mixpanel-browser":1}],8:[function(require,module,exports){
},{"../channel":8,"mixpanel-browser":1}],13:[function(require,module,exports){
"use strict";
(function (window) {
var sendRequest = function (method, url, data, success_cb, error_cb) {
@ -6353,7 +6731,7 @@ exports.default = MixpanelChannel;
window.Adjust = function (app_token, environment, os_name) { this.trackSession = function (device_ids) { var params = cloneObj(device_ids); params.app_token = app_token; params.os_name = os_name; params.environment = environment; sendRequest("GET", "https://app.adjust.com/session?" + encodeQueryString(params)); }; this.trackEvent = function (event_token, device_ids) { var params = cloneObj(device_ids); params.app_token = app_token; params.event_token = event_token; params.os_name = os_name; params.environment = environment; sendRequest("GET", "https://app.adjust.com/event?" + encodeQueryString(params)); }; };
})(window);
},{}],9:[function(require,module,exports){
},{}],14:[function(require,module,exports){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
@ -6366,7 +6744,7 @@ var LogEventHandlers = /** @class */ (function () {
this.appVersion = appVersion;
this.channels = [];
this.isReady = false; // Ready once all channels are ready or one channel is ready?
this.initialize(channelConfigs);
this.initializeChannels(channelConfigs);
LogEventHandlers.instance = this;
}
/**
@ -6379,27 +6757,9 @@ var LogEventHandlers = /** @class */ (function () {
return LogEventHandlers.instance;
}
else {
throw new DOMException('LogEventHandlers need to be initialized');
throw new Error('[BitAnalytics] LogEventHandlers need to be initialized');
}
};
LogEventHandlers.prototype.initialize = function (channelConfigs) {
var _this = this;
// Get the channel names by the keys
var channelNames = Object.keys(channelConfigs);
// Iterate to init the several channels given in the config
channelNames.map(function (channelName) {
var channelConfig = channelConfigs[channelName];
// OS shared to check the availability of this channel on this OS.
channelConfig['os'] = _this.os;
try {
var channel = channel_factory_1.default.createChannel(channelName, channelConfig);
_this.channels.push(channel);
}
catch (error) {
console.log(error.name + ': ' + error.message);
}
});
};
LogEventHandlers.prototype.postEvent = function (logEvent) {
var _this = this;
/**
@ -6408,7 +6768,7 @@ var LogEventHandlers = /** @class */ (function () {
* 2 is second channel
* ...
*/
var logEventParams = logEvent.getParams();
var logEventParams = logEvent.params;
// params
var params = {
'os': this.os,
@ -6417,10 +6777,10 @@ var LogEventHandlers = /** @class */ (function () {
// Concat the shared params
if (logEventParams.length > 0) {
// concat specific params needed
params = Object.assign({}, logEventParams[0], params);
params = this.concatObject(logEventParams[0], params);
}
// Post event depending of the channel
logEvent.getChannelNames().map(function (channelName, i) {
logEvent.channelNames.map(function (channelName, i) {
var channel = _this.getChannelByName(channelName);
if (channel) {
// Real index (first param is shared by all channels)
@ -6428,14 +6788,21 @@ var LogEventHandlers = /** @class */ (function () {
// concat if needed
if (logEventParams.length > index) {
// concat specific params needed
params = Object.assign({}, logEventParams[index], params);
params = _this.concatObject(logEventParams[index], params);
}
console.log('[BitAnalytics] Params: ' + JSON.stringify(params));
try {
channel.postEvent(logEvent.name, params);
console.log('[BitAnalytics] LogEvent "' + logEvent.name + '" sent to ' + channelName + '.');
}
catch (e) {
console.error('[BitAnalytics] LogEvent "' + logEvent.name + '" failed to send with "' + channelName + '. ');
console.log(e);
}
channel.postEvent(logEvent.getName(), params);
console.log('LogEvent "' + logEvent.getName() + '" sent to ' + channelName + '.');
}
else {
// Channel not available
console.log('LogEvent "' + logEvent.getName() + '" cannot send to ' + channelName + ', this channel is not available.');
console.log('[BitAnalytics] LogEvent "' + logEvent.name + '" cannot send to ' + channelName + ', this channel is not available.');
}
});
};
@ -6444,10 +6811,17 @@ var LogEventHandlers = /** @class */ (function () {
* Private methods
*
*/
LogEventHandlers.prototype.concatObject = function (from, to) {
var keys = Object.keys(from);
keys.map(function (key) {
if (!to[key]) {
to[key] = from[key];
}
});
return to;
};
LogEventHandlers.prototype.getChannelByName = function (channelName) {
console.log(channelName);
console.log(this.channels);
var channels = this.channels.filter(function (channel) { return channel.getName() == channelName; });
var channels = this.channels.filter(function (channel) { return channel.name == channelName; });
if (channels.length > 0) {
return channels[0];
}
@ -6455,39 +6829,44 @@ var LogEventHandlers = /** @class */ (function () {
return undefined;
}
};
LogEventHandlers.prototype.initializeChannels = function (channelConfigs) {
var _this = this;
// Get the channel names by the keys
var channelNames = Object.keys(channelConfigs);
// Iterate to init the several channels given in the config
channelNames.map(function (channelName) {
var channelConfig = channelConfigs[channelName];
// OS shared to check the availability of this channel on this OS.
channelConfig.os = _this.os;
channelConfig.appVersion = _this.appVersion;
try {
var channel = channel_factory_1.default.createChannel(channelName, channelConfig);
_this.channels.push(channel);
}
catch (error) {
console.log('[BitAnalytics] ' + error.name + ': ' + error.message);
}
});
};
return LogEventHandlers;
}());
exports.default = LogEventHandlers;
},{"./channel-factory":3}],10:[function(require,module,exports){
},{"./channel-factory":7}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LogEvent = /** @class */ (function () {
function LogEvent(name, params, channelNames) {
if (channelNames.length == 0) {
throw new DOMException('Minimum one channel is needed.');
throw new Error('[BitAnalytics] Minimum one channel is needed.');
}
this.name = name;
this.params = params;
this.channelNames = channelNames;
}
/**
*
* Public methods
*
*/
LogEvent.prototype.getName = function () {
return this.name;
};
LogEvent.prototype.getParams = function () {
return this.params;
};
LogEvent.prototype.getChannelNames = function () {
return this.channelNames;
};
return LogEvent;
}());
exports.default = LogEvent;
},{}]},{},[2])(2)
},{}]},{},[6])(6)
});

View file

@ -1214,8 +1214,65 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
// Init BitAnalytics
var os = platformInfo.isAndroid ? 'android' : platformInfo.isIOS ? 'ios' : 'desktop';
window.BitAnalytics.initialize(os, $window.fullVersion, {"firebase": {}});
window.BitAnalytics.initialize(os, $window.fullVersion, {"firebase": {},
"ga": {
"trackingId": "UA-59964190-23",
"eventLabels": ["id", "icon-off"]
},
"adjust": {
"token": "au1onbhgg5q8",
"environment" : "production",
"eventTypes": {
"banner_click": "sc5i8u",
"buy_bitcoin_click": "t1vcdz",
"transfer_success": "f68evo",
"wallet_created": "nd3dg5",
"wallet_opened": "4n39l7"
}
}
});
var channel = "ga";
if (platformInfo.isNW) {
channel = "ga";
}
// Send a log to test
var log = new window.BitAnalytics.LogEvent("wallet_opened", [], [channel, "adjust"]);
window.BitAnalytics.LogEventHandlers.postEvent(log);
var actionBanner = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'banner_click',
class: 'track_banner_click',
params: ['href-banner', 'id'],
channels: [channel, 'adjust']
});
window.BitAnalytics.ActionHandlers.trackAction(actionBanner);
var actionBuyBitcoin = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'buy_bitcoin_click',
class: 'track_buy_bitcoin_click',
params: ['href', 'id'],
channels: [channel, 'adjust']
});
window.BitAnalytics.ActionHandlers.trackAction(actionBuyBitcoin);
var actionLinkClickOut = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'link_click_out',
class: 'track_link_click_out',
params: ['href', 'id'],
channels: [channel]
});
window.BitAnalytics.ActionHandlers.trackAction(actionLinkClickOut);
var actionTabOpen = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'tab_open',
class: 'track_tab_open',
params: ['href', 'title', 'icon-off'],
channels: [channel]
});
window.BitAnalytics.ActionHandlers.trackAction(actionTabOpen);
// Init language
uxLanguage.init(function (lang) {
@ -1385,7 +1442,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
win.menu = nativeMenuBar;
}
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
if (document.body.classList.contains('keyboard-open')) {
document.body.classList.remove('keyboard-open');

View file

@ -12,7 +12,8 @@
<link rel="stylesheet" type="text/css" href="css/bitcoin.com.css">
<link rel="stylesheet" type="text/css" href="css/icomoon.css">
<title>Bitcoin.com Wallet - Bitcoin.com Wallet</title>
<link rel="shortcut icon" href="img/app/favicon.ico">
<link rel="shortcut icon" href="img/app/favicon.ico">
<script src="https://www.googletagmanager.com/gtag/js?id=UA-59964190-23"></script>
</head>
<body>
@ -30,7 +31,7 @@
<script src="lib/ionic.bundle.min.js"></script>
<script src="lib/angular-components.js"></script>
<script src="lib/bitcoin-cash-js.js"></script>
<script src="lib/bitcoin-cash-js.js"></script>
<script src="lib/bitanalytics.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>

View file

@ -6,14 +6,14 @@
</div>
<div ng-show="!hide">
<div ng-repeat="service in services track by $index">
<a ng-if="service.sref" ui-sref="{{service.sref}}" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="service.sref" ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle theme-circle-community">
<div class="bg {{service.icon}}"></div>
</i>
<span>{{service.title || service.name}}</span>
<i class="icon bp-arrow-right"></i>
</a>
<a ng-if="!service.sref" ng-click="open('{{service.href}}')" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="!service.sref" ng-click="open('{{service.href}}')" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle theme-circle-community">
<div class="bg {{service.icon}}"></div>
</i>
@ -22,7 +22,7 @@
</a>
</div>
<div>
<a ng-if="isCordova" ng-click="share()" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="isCordova" ng-click="share()" title="Share the Wallet App" id="home_{{service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle theme-circle-community">
<div class="bg icon-share"></div>
</i>

View file

@ -6,7 +6,14 @@
</div>
<div ng-show="!hide">
<div ng-repeat="service in services track by $index">
<a ui-sref="{{service.sref}}" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="service.name=='buyandsell'" ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="buy_bitcoin_click item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle">
<div class="bg {{service.icon}}"></div>
</i>
<span>{{service.title || service.name}}</span>
<i class="icon bp-arrow-right"></i>
</a>
<a ng-if="service.name!='buyandsell'" ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle">
<div class="bg {{service.icon}}"></div>
</i>

View file

@ -6,14 +6,14 @@
</div>
<div ng-show="!hide">
<div ng-repeat="service in services track by $index">
<a ng-if="service.sref" ui-sref="{{service.sref}}" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="service.sref" ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle">
<div class="bg {{service.icon}}"></div>
</i>
<span>{{service.title || service.name}}</span>
<i class="icon bp-arrow-right"></i>
</a>
<a ng-if="!service.sref" ng-click="open('{{service.href}}')" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ng-if="!service.sref" ng-click="open('{{service.href}}')" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle">
<div class="bg {{service.icon}}"></div>
</i>

View file

@ -6,7 +6,7 @@
</div>
<div ng-show="!hide">
<div ng-repeat="service in services track by $index">
<a ui-sref="{{service.sref}}" class="item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<a ui-sref="{{service.sref}}" id="home_{{service.name}}" title="{{service.title || service.name}}" class="track_link_click_out item item-sub item-icon-left item-big-icon-left item-icon-right next-step">
<i class="icon big-icon-svg theme-circle theme-circle-services">
<div class="bg {{service.icon}}"></div>
</i>

View file

@ -92,7 +92,7 @@
<div class="list card card-banner">
<ion-spinner ng-if="bannerIsLoading"></ion-spinner>
<a ng-if="!bannerIsLoading" ng-click="openBannerUrl()">
<a id="home_banner" href-banner="{{bannerImageUrl}}" class="track_banner_click" ng-if="!bannerIsLoading" ng-click="openBannerUrl()">
<img class="card-banner__img" ng-src="{{bannerImageUrl}}"/>
</a>

View file

@ -32,7 +32,7 @@
<span ng-show="hasWallets" translate>To get started, buy bitcoin or share your address. You can receive bitcoin from any wallet or service.</span>
<span ng-show="!hasWallets" translate>To get started, you'll need to create a bitcoin wallet and get some bitcoin.</span>
<div class="padding">
<button class="button button-standard button-primary" ng-click="buyBitcoin()" ng-show="hasWallets" translate>Buy Bitcoin</button>
<button class="button button-standard button-primary track_buy_bitcoin_click" id="tab_send_buy_bitcoin" ng-click="buyBitcoin()" ng-show="hasWallets" translate>Buy Bitcoin</button>
<button class="button button-standard button-primary" ng-click="createWallet()" ng-show="!hasWallets" translate>Create bitcoin wallet</button>
<button class="button button-standard button-secondary" ui-sref="tabs.receive" ng-show="hasWallets" translate>Show bitcoin address</button>
</div>

View file

@ -1,22 +1,21 @@
<ion-tabs class="tabs-icon-top tabs-color-active-positive ion-tabs-transparent {{$root.hideTabs}}">
<ion-tab title="{{'Home'|translate}}" icon-off="ico-home" icon-on="ico-home-selected" ui-sref="tabs.home">
<ion-tab class="track_tab_open" id="tab_open_home" title="{{'Home'|translate}}" icon-off="ico-home" icon-on="ico-home-selected" ui-sref="tabs.home">
<ion-nav-view name="tab-home"></ion-nav-view>
</ion-tab>
<ion-tab title="{{'Receive'|translate}}" icon-off="ico-receive" icon-on="ico-receive-selected" ui-sref="tabs.receive">
<ion-tab class="track_tab_open" id="tab_open_receive" title="{{'Receive'|translate}}" icon-off="ico-receive" icon-on="ico-receive-selected" ui-sref="tabs.receive">
<ion-nav-view name="tab-receive"></ion-nav-view>
</ion-tab>
<ion-tab title="{{'Scan'|translate}}" icon-off="ico-scan" icon-on="ico-scan-selected" ng-click="chooseScanner()">
<ion-tab class="track_tab_open" id="tab_open_scan" title="{{'Scan'|translate}}" icon-off="ico-scan" icon-on="ico-scan-selected" ng-click="chooseScanner()">
<ion-nav-view name="tab-scan"></ion-nav-view>
</ion-tab>
<ion-tab title="{{'Send'|translate}}" icon-off="ico-send" icon-on="ico-send-selected" ui-sref="tabs.send">
<ion-tab class="track_tab_open" id="tab_open_send" title="{{'Send'|translate}}" icon-off="ico-send" icon-on="ico-send-selected" ui-sref="tabs.send">
<ion-nav-view name="tab-send"></ion-nav-view>
</ion-tab>
<ion-tab title="{{'Settings'|translate}}" icon-off="ico-settings" icon-on="ico-settings-selected" ui-sref="tabs.settings">
<ion-tab class="track_tab_open" id="tab_open_settings" title="{{'Settings'|translate}}" icon-off="ico-settings" icon-on="ico-settings-selected" ui-sref="tabs.settings">
<ion-nav-view name="tab-settings"></ion-nav-view>
</ion-tab>
</ion-tabs>