@zoho_apptics/apptics-js-sdk 1.0.1 → 2.0.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/LICENSE +13 -0
- package/README.md +747 -11
- package/dist/apptics.esm.min.js +3 -0
- package/dist/apptics.esm.min.js.map +1 -0
- package/dist/apptics.min.js +3 -0
- package/dist/apptics.min.js.map +1 -0
- package/dist/chunks/batch-BU_mTpm1.min.js +3 -0
- package/dist/chunks/batch-BU_mTpm1.min.js.map +1 -0
- package/dist/chunks/logs-Bea5zUW_.min.js +3 -0
- package/dist/chunks/logs-Bea5zUW_.min.js.map +1 -0
- package/dist/cjs/auto-init.d.ts +8 -0
- package/dist/cjs/auto-init.js +32 -0
- package/dist/cjs/core/attempts.d.ts +28 -0
- package/dist/cjs/core/attempts.js +113 -0
- package/dist/cjs/core/batch.d.ts +32 -0
- package/dist/cjs/core/batch.js +115 -0
- package/dist/cjs/core/callsite.d.ts +28 -0
- package/dist/cjs/core/callsite.js +93 -0
- package/dist/cjs/core/consent.d.ts +23 -0
- package/dist/cjs/core/consent.js +130 -0
- package/dist/cjs/core/constants.d.ts +212 -0
- package/dist/cjs/core/constants.js +299 -0
- package/dist/cjs/core/db.d.ts +40 -0
- package/dist/cjs/core/db.js +334 -0
- package/dist/cjs/core/debug.d.ts +22 -0
- package/dist/cjs/core/debug.js +88 -0
- package/dist/cjs/core/env.d.ts +28 -0
- package/dist/cjs/core/env.js +267 -0
- package/dist/cjs/core/framework-id.d.ts +1 -0
- package/dist/cjs/core/framework-id.js +9 -0
- package/dist/cjs/core/guard.d.ts +2 -0
- package/dist/cjs/core/guard.js +72 -0
- package/dist/cjs/core/hooks.d.ts +41 -0
- package/dist/cjs/core/hooks.js +23 -0
- package/dist/cjs/core/logger.d.ts +16 -0
- package/dist/cjs/core/logger.js +86 -0
- package/dist/cjs/core/state.d.ts +69 -0
- package/dist/cjs/core/state.js +78 -0
- package/dist/cjs/core/storage.d.ts +46 -0
- package/dist/cjs/core/storage.js +229 -0
- package/dist/cjs/core/transport.d.ts +83 -0
- package/dist/cjs/core/transport.js +441 -0
- package/dist/cjs/core/utils.d.ts +26 -0
- package/dist/cjs/core/utils.js +175 -0
- package/dist/cjs/core/validate.d.ts +18 -0
- package/dist/cjs/core/validate.js +233 -0
- package/dist/cjs/device/appversion.d.ts +20 -0
- package/dist/cjs/device/appversion.js +158 -0
- package/dist/cjs/device/index.d.ts +23 -0
- package/dist/cjs/device/index.js +372 -0
- package/dist/cjs/engagement/api-rules.d.ts +84 -0
- package/dist/cjs/engagement/api-rules.js +219 -0
- package/dist/cjs/engagement/auto-api.d.ts +7 -0
- package/dist/cjs/engagement/auto-api.js +200 -0
- package/dist/cjs/engagement/auto-screen.d.ts +16 -0
- package/dist/cjs/engagement/auto-screen.js +241 -0
- package/dist/cjs/engagement/defined-events.d.ts +23 -0
- package/dist/cjs/engagement/defined-events.js +58 -0
- package/dist/cjs/engagement/send.d.ts +6 -0
- package/dist/cjs/engagement/send.js +99 -0
- package/dist/cjs/engagement/session.d.ts +42 -0
- package/dist/cjs/engagement/session.js +327 -0
- package/dist/cjs/engagement/track.d.ts +56 -0
- package/dist/cjs/engagement/track.js +350 -0
- package/dist/cjs/errors/send.d.ts +6 -0
- package/dist/cjs/errors/send.js +73 -0
- package/dist/cjs/errors/track.d.ts +4 -0
- package/dist/cjs/errors/track.js +127 -0
- package/dist/cjs/feedback/controls.d.ts +31 -0
- package/dist/cjs/feedback/controls.js +286 -0
- package/dist/cjs/feedback/index.d.ts +8 -0
- package/dist/cjs/feedback/index.js +37 -0
- package/dist/cjs/feedback/logs.d.ts +40 -0
- package/dist/cjs/feedback/logs.js +202 -0
- package/dist/cjs/feedback/send.d.ts +25 -0
- package/dist/cjs/feedback/send.js +178 -0
- package/dist/cjs/feedback/template.d.ts +2 -0
- package/dist/cjs/feedback/template.js +162 -0
- package/dist/cjs/feedback/ui.d.ts +55 -0
- package/dist/cjs/feedback/ui.js +631 -0
- package/dist/cjs/heatmap/index.d.ts +16 -0
- package/dist/cjs/heatmap/index.js +22 -0
- package/dist/cjs/heatmap/send.d.ts +13 -0
- package/dist/cjs/heatmap/send.js +82 -0
- package/dist/cjs/heatmap/track.d.ts +4 -0
- package/dist/cjs/heatmap/track.js +377 -0
- package/dist/cjs/index.d.ts +68 -0
- package/dist/cjs/index.js +150 -0
- package/dist/cjs/lifecycle.d.ts +14 -0
- package/dist/cjs/lifecycle.js +538 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/remoteconfig/custom.d.ts +10 -0
- package/dist/cjs/remoteconfig/custom.js +78 -0
- package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
- package/dist/cjs/remoteconfig/evaluate.js +171 -0
- package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
- package/dist/cjs/remoteconfig/fetch.js +214 -0
- package/dist/cjs/remoteconfig/index.d.ts +13 -0
- package/dist/cjs/remoteconfig/index.js +90 -0
- package/dist/cjs/remoteconfig/store.d.ts +18 -0
- package/dist/cjs/remoteconfig/store.js +98 -0
- package/dist/cjs/remotelog/gate.d.ts +11 -0
- package/dist/cjs/remotelog/gate.js +54 -0
- package/dist/cjs/remotelog/index.d.ts +25 -0
- package/dist/cjs/remotelog/index.js +55 -0
- package/dist/cjs/remotelog/logger.d.ts +28 -0
- package/dist/cjs/remotelog/logger.js +139 -0
- package/dist/cjs/remotelog/send.d.ts +13 -0
- package/dist/cjs/remotelog/send.js +153 -0
- package/dist/cjs/scheduler.d.ts +8 -0
- package/dist/cjs/scheduler.js +78 -0
- package/dist/cjs/types.d.ts +312 -0
- package/dist/cjs/user/index.d.ts +33 -0
- package/dist/cjs/user/index.js +178 -0
- package/dist/esm/auto-init.d.ts +8 -0
- package/dist/esm/auto-init.js +29 -0
- package/dist/esm/core/attempts.d.ts +28 -0
- package/dist/esm/core/attempts.js +106 -0
- package/dist/esm/core/batch.d.ts +32 -0
- package/dist/esm/core/batch.js +108 -0
- package/dist/esm/core/callsite.d.ts +28 -0
- package/dist/esm/core/callsite.js +89 -0
- package/dist/esm/core/consent.d.ts +23 -0
- package/dist/esm/core/consent.js +120 -0
- package/dist/esm/core/constants.d.ts +212 -0
- package/dist/esm/core/constants.js +277 -0
- package/dist/esm/core/db.d.ts +40 -0
- package/dist/esm/core/db.js +324 -0
- package/dist/esm/core/debug.d.ts +22 -0
- package/dist/esm/core/debug.js +81 -0
- package/dist/esm/core/env.d.ts +28 -0
- package/dist/esm/core/env.js +251 -0
- package/dist/esm/core/framework-id.d.ts +1 -0
- package/dist/esm/core/framework-id.js +7 -0
- package/dist/esm/core/guard.d.ts +2 -0
- package/dist/esm/core/guard.js +70 -0
- package/dist/esm/core/hooks.d.ts +41 -0
- package/dist/esm/core/hooks.js +21 -0
- package/dist/esm/core/logger.d.ts +16 -0
- package/dist/esm/core/logger.js +82 -0
- package/dist/esm/core/state.d.ts +69 -0
- package/dist/esm/core/state.js +73 -0
- package/dist/esm/core/storage.d.ts +46 -0
- package/dist/esm/core/storage.js +219 -0
- package/dist/esm/core/transport.d.ts +83 -0
- package/dist/esm/core/transport.js +425 -0
- package/dist/esm/core/utils.d.ts +26 -0
- package/dist/esm/core/utils.js +161 -0
- package/dist/esm/core/validate.d.ts +18 -0
- package/dist/esm/core/validate.js +226 -0
- package/dist/esm/device/appversion.d.ts +20 -0
- package/dist/esm/device/appversion.js +153 -0
- package/dist/esm/device/index.d.ts +23 -0
- package/dist/esm/device/index.js +362 -0
- package/dist/esm/engagement/api-rules.d.ts +84 -0
- package/dist/esm/engagement/api-rules.js +211 -0
- package/dist/esm/engagement/auto-api.d.ts +7 -0
- package/dist/esm/engagement/auto-api.js +198 -0
- package/dist/esm/engagement/auto-screen.d.ts +16 -0
- package/dist/esm/engagement/auto-screen.js +238 -0
- package/dist/esm/engagement/defined-events.d.ts +23 -0
- package/dist/esm/engagement/defined-events.js +55 -0
- package/dist/esm/engagement/send.d.ts +6 -0
- package/dist/esm/engagement/send.js +96 -0
- package/dist/esm/engagement/session.d.ts +42 -0
- package/dist/esm/engagement/session.js +315 -0
- package/dist/esm/engagement/track.d.ts +56 -0
- package/dist/esm/engagement/track.js +340 -0
- package/dist/esm/errors/send.d.ts +6 -0
- package/dist/esm/errors/send.js +70 -0
- package/dist/esm/errors/track.d.ts +4 -0
- package/dist/esm/errors/track.js +123 -0
- package/dist/esm/feedback/controls.d.ts +31 -0
- package/dist/esm/feedback/controls.js +280 -0
- package/dist/esm/feedback/index.d.ts +8 -0
- package/dist/esm/feedback/index.js +30 -0
- package/dist/esm/feedback/logs.d.ts +40 -0
- package/dist/esm/feedback/logs.js +188 -0
- package/dist/esm/feedback/send.d.ts +25 -0
- package/dist/esm/feedback/send.js +175 -0
- package/dist/esm/feedback/template.d.ts +2 -0
- package/dist/esm/feedback/template.js +159 -0
- package/dist/esm/feedback/ui.d.ts +55 -0
- package/dist/esm/feedback/ui.js +626 -0
- package/dist/esm/heatmap/index.d.ts +16 -0
- package/dist/esm/heatmap/index.js +17 -0
- package/dist/esm/heatmap/send.d.ts +13 -0
- package/dist/esm/heatmap/send.js +79 -0
- package/dist/esm/heatmap/track.d.ts +4 -0
- package/dist/esm/heatmap/track.js +374 -0
- package/dist/esm/index.d.ts +68 -0
- package/dist/esm/index.js +122 -0
- package/dist/esm/lifecycle.d.ts +14 -0
- package/dist/esm/lifecycle.js +534 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/remoteconfig/custom.d.ts +10 -0
- package/dist/esm/remoteconfig/custom.js +74 -0
- package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
- package/dist/esm/remoteconfig/evaluate.js +166 -0
- package/dist/esm/remoteconfig/fetch.d.ts +24 -0
- package/dist/esm/remoteconfig/fetch.js +210 -0
- package/dist/esm/remoteconfig/index.d.ts +13 -0
- package/dist/esm/remoteconfig/index.js +85 -0
- package/dist/esm/remoteconfig/store.d.ts +18 -0
- package/dist/esm/remoteconfig/store.js +91 -0
- package/dist/esm/remotelog/gate.d.ts +11 -0
- package/dist/esm/remotelog/gate.js +48 -0
- package/dist/esm/remotelog/index.d.ts +25 -0
- package/dist/esm/remotelog/index.js +51 -0
- package/dist/esm/remotelog/logger.d.ts +28 -0
- package/dist/esm/remotelog/logger.js +136 -0
- package/dist/esm/remotelog/send.d.ts +13 -0
- package/dist/esm/remotelog/send.js +149 -0
- package/dist/esm/scheduler.d.ts +8 -0
- package/dist/esm/scheduler.js +74 -0
- package/dist/esm/types.d.ts +312 -0
- package/dist/esm/user/index.d.ts +33 -0
- package/dist/esm/user/index.js +170 -0
- package/dist/feedback.esm.min.js +3 -0
- package/dist/feedback.esm.min.js.map +1 -0
- package/dist/heatmap.esm.min.js +3 -0
- package/dist/heatmap.esm.min.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +124 -7
- package/src/appticssdk.js +0 -3817
package/src/appticssdk.js
DELETED
|
@@ -1,3817 +0,0 @@
|
|
|
1
|
-
/*$Id$*/
|
|
2
|
-
(function (window, document) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var APConsole = console;
|
|
6
|
-
'use strict'; // no i18n
|
|
7
|
-
|
|
8
|
-
// Console override
|
|
9
|
-
var Console = {
|
|
10
|
-
/** @type {function(...*)} */
|
|
11
|
-
log: function() {
|
|
12
|
-
if (_config.verbose && APConsole) {
|
|
13
|
-
try {
|
|
14
|
-
APConsole.log.apply(APConsole, arguments);
|
|
15
|
-
} catch (err) {
|
|
16
|
-
each(arguments, function(arg) {
|
|
17
|
-
APConsole.log(arg);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
/** @type {function(...*)} */
|
|
23
|
-
warn: function() {
|
|
24
|
-
if (_config.verbose && APConsole) {
|
|
25
|
-
if (_config.verbose && APConsole) {
|
|
26
|
-
try {
|
|
27
|
-
APConsole.warn.apply(APConsole, arguments);
|
|
28
|
-
} catch (err) {
|
|
29
|
-
each(arguments, function(arg) {
|
|
30
|
-
APConsole.warn(arg);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
/** @type {function(...*)} */
|
|
37
|
-
error: function() {
|
|
38
|
-
if (_config.verbose && APConsole) {
|
|
39
|
-
if (_config.verbose && APConsole) {
|
|
40
|
-
try {
|
|
41
|
-
APConsole.error.apply(APConsole, arguments);
|
|
42
|
-
} catch (err) {
|
|
43
|
-
each(arguments, function(arg) {
|
|
44
|
-
APConsole.error(arg);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
/** @type {function(...*)} */
|
|
51
|
-
info: function() {
|
|
52
|
-
if (_config.verbose && APConsole) {
|
|
53
|
-
if (_config.verbose && APConsole) {
|
|
54
|
-
try {
|
|
55
|
-
APConsole.info.apply(APConsole, arguments);
|
|
56
|
-
} catch (err) {
|
|
57
|
-
each(arguments, function(arg) {
|
|
58
|
-
APConsole.info(arg);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
/** @type {function(...*)} */
|
|
65
|
-
dir: function(arg) {
|
|
66
|
-
if (_config.verbose && APConsole) {
|
|
67
|
-
if (_config.verbose && APConsole) {
|
|
68
|
-
APConsole.dir(arg);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
if (!window.localStorage) {
|
|
75
|
-
Console.warn('apptics: localStorage not supported'); // no i18n
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!window.Promise) {
|
|
80
|
-
Console.warn('apptics: Promise not supported (try adding a polyfill)'); // no i18n
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Function to make an asynchronous request
|
|
85
|
-
function makeRequest(url, method, payload, headers) {
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
let xhr = new XMLHttpRequest();
|
|
88
|
-
xhr.open(method, url);
|
|
89
|
-
if (headers) {
|
|
90
|
-
Object.keys(headers).forEach((key) => {
|
|
91
|
-
xhr.setRequestHeader(key, headers[key]);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
xhr.withCredentials = false;
|
|
95
|
-
xhr.onreadystatechange = function() {
|
|
96
|
-
if (xhr.readyState === 4) { // XMLHttpRequest.DONE == 4, except in safari 4
|
|
97
|
-
if (xhr.status == 200) {
|
|
98
|
-
resolve(xhr.responseText);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
reject(xhr.statusText);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
xhr.onerror = function() {
|
|
106
|
-
reject('makeRequest: Network Error'); // no i18n
|
|
107
|
-
};
|
|
108
|
-
xhr.send(payload);
|
|
109
|
-
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Class to handle synchronous execution of requests
|
|
114
|
-
class RequestQueue {
|
|
115
|
-
constructor() {
|
|
116
|
-
this.queue = [];
|
|
117
|
-
this.currentRequest = Promise.resolve();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Method to add a request to the queue
|
|
121
|
-
addRequest(url, method, payload, headers) {
|
|
122
|
-
const request = () => makeRequest(url, method, payload, headers);
|
|
123
|
-
this.queue.push(request);
|
|
124
|
-
return this;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Method to process the queue
|
|
128
|
-
processQueue() {
|
|
129
|
-
this.currentRequest = this.queue.reduce((prev, curr) => prev.then(curr), Promise.resolve());
|
|
130
|
-
this.queue = [];
|
|
131
|
-
return this.currentRequest;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
var _regDeviceSending = false;
|
|
136
|
-
var _regDeviceResolve = [];
|
|
137
|
-
var _regDeviceReject = [];
|
|
138
|
-
|
|
139
|
-
var _sending = false;
|
|
140
|
-
var _deferSendTimer = null;
|
|
141
|
-
var _breaker = {};
|
|
142
|
-
|
|
143
|
-
var _config = {};
|
|
144
|
-
var _defaultoptions = {};
|
|
145
|
-
|
|
146
|
-
// we add an internal _id to each event object in the format upoc-counter
|
|
147
|
-
// this makes it easier for us to remove successfully sent event from local db
|
|
148
|
-
var _internalEventIdCounter = 0;
|
|
149
|
-
var inactiveduration = 1;
|
|
150
|
-
|
|
151
|
-
// holds a copy of current request properties
|
|
152
|
-
var _token = '';
|
|
153
|
-
var _zak = '';
|
|
154
|
-
var _identifier = '';
|
|
155
|
-
var _zsoid = '';
|
|
156
|
-
var _projectID = '';
|
|
157
|
-
var _frameworkID = 5781;
|
|
158
|
-
var _fwid_local = 5573;
|
|
159
|
-
var _platform = 'Browser'; // no i18n
|
|
160
|
-
var _isanonrequired = true;
|
|
161
|
-
var _devicestatus = 0;
|
|
162
|
-
var _uuid = '';
|
|
163
|
-
var _apid = '';
|
|
164
|
-
var _mapid = '';
|
|
165
|
-
var _device_info = {};
|
|
166
|
-
var _user_info = {};
|
|
167
|
-
var _current_screen = {};
|
|
168
|
-
var _current_session = {};
|
|
169
|
-
var _properties = {};
|
|
170
|
-
var sendingInterval = null;
|
|
171
|
-
var timeoutId = null;
|
|
172
|
-
const requestQueue = new RequestQueue();
|
|
173
|
-
var _navigator = window.navigator;
|
|
174
|
-
var _userAgent = _navigator.userAgent;
|
|
175
|
-
var _ignoreDnt = false;
|
|
176
|
-
var _isGlobalErrorTracking = true;
|
|
177
|
-
|
|
178
|
-
/** @const */ var APPTICS_FRAMEWORK_VERSION = '1.3'; // no i18n
|
|
179
|
-
/** @const */ var APPTICS_INSTANCE_NAME = 'apptics'; // no i18n
|
|
180
|
-
/** @const */ var APPTICS_PAYLOAD_ENCODING_TYPE = 'base64'; // no i18n
|
|
181
|
-
/** @const */ var APPTICS_PAYLOAD_TYPE = 'json'; // no i18n
|
|
182
|
-
|
|
183
|
-
var DEFAULT_API_PATHS = {
|
|
184
|
-
'regdevice': 'device/add', // no i18n
|
|
185
|
-
'reguser': 'user/registerwithorg', // no i18n
|
|
186
|
-
'engagement': 'engagement/add', // no i18n
|
|
187
|
-
'error': 'exception/error', //no i18n
|
|
188
|
-
'feedback': 'feedback/add' //no i18n
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const AP_TRACKING_STATUS = Object.freeze({
|
|
192
|
-
USAGE_TRACKING_WITH_PII: 2,
|
|
193
|
-
USAGE_TRACKING_WITHOUT_PII: 5,
|
|
194
|
-
NO_TRACKING: -1
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const AP_FEEDBACK_TYPE = Object.freeze({
|
|
198
|
-
BUG : 0,
|
|
199
|
-
FEEDBACK : 1,
|
|
200
|
-
HELP : 2,
|
|
201
|
-
REPORT : 3
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
/*
|
|
205
|
-
* Global settings
|
|
206
|
-
*/
|
|
207
|
-
var AP_CONFIG = {
|
|
208
|
-
'endpoint': '/sdk/web/v1/', // no i18n
|
|
209
|
-
'method': 'POST', // no i18n
|
|
210
|
-
'transport': 'XHR', // no i18n
|
|
211
|
-
'mode': 1, // no i18n
|
|
212
|
-
'default_group_name': 'default', // no i18n
|
|
213
|
-
'default_optin_status': AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII, // no i18n
|
|
214
|
-
'enable_pageview_tracking': false, // no i18n
|
|
215
|
-
'save_referrer': true, // no i18n
|
|
216
|
-
'verbose': false, // no i18n
|
|
217
|
-
'track_link_timeout': 300, // no i18n
|
|
218
|
-
'cookie_expiration_days': 365, // no i18n
|
|
219
|
-
'track_by_default': true, // no i18n
|
|
220
|
-
'storage_type': 'localStorage', // no i18n
|
|
221
|
-
'ignore_do_not_track': false, // no i18n
|
|
222
|
-
'enable_batch_requests': true, // no i18n
|
|
223
|
-
'batch_size': 50, // no i18n
|
|
224
|
-
'batch_flush_interval': 30000, // no i18n
|
|
225
|
-
'batch_request_timeout': 7, // no i18n
|
|
226
|
-
'auto_starts_batch': true, // no i18n
|
|
227
|
-
'debug': '',
|
|
228
|
-
'base_domain': '',
|
|
229
|
-
'identifier': '',
|
|
230
|
-
'projectID': '',
|
|
231
|
-
'token': '',
|
|
232
|
-
'zsoid': '',
|
|
233
|
-
'aaID': ''
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
var AP_RESERVED_CONFIG = [
|
|
237
|
-
'endpoint', // no i18n
|
|
238
|
-
'method', // no i18n
|
|
239
|
-
'transport', // no i18n
|
|
240
|
-
'track_link_timeout', // no i18n
|
|
241
|
-
'cookie_expiration_days', // no i18n
|
|
242
|
-
'storage_type', // no i18n
|
|
243
|
-
'enable_batch_requests', // no i18n
|
|
244
|
-
'batch_size', // no i18n
|
|
245
|
-
'batch_request_timeout', // no i18n
|
|
246
|
-
'auto_starts_batch' // no i18n
|
|
247
|
-
];
|
|
248
|
-
|
|
249
|
-
// crawlers reference
|
|
250
|
-
// https://developers.google.com/search/docs/advanced/crawling/overview-google-crawlers
|
|
251
|
-
var BLOCKED_WS = [
|
|
252
|
-
'ahrefsbot', // no i18n
|
|
253
|
-
'ahrefssiteaudit', // no i18n
|
|
254
|
-
'baiduspider', // no i18n
|
|
255
|
-
'bingbot', // no i18n
|
|
256
|
-
'bingpreview', // no i18n
|
|
257
|
-
'chrome-lighthouse', // no i18n
|
|
258
|
-
'facebookexternal', // no i18n
|
|
259
|
-
'petalbot', // no i18n
|
|
260
|
-
'pinterest', // no i18n
|
|
261
|
-
'screaming frog', // no i18n
|
|
262
|
-
'yahoo! slurp', // no i18n
|
|
263
|
-
'yandexbot', // no i18n
|
|
264
|
-
'adsbot-google', // no i18n
|
|
265
|
-
'apis-google', // no i18n
|
|
266
|
-
'duplexweb-google', // no i18n
|
|
267
|
-
'feedfetcher-google', // no i18n
|
|
268
|
-
'google favicon', // no i18n
|
|
269
|
-
'google web preview', // no i18n
|
|
270
|
-
'google-read-aloud', // no i18n
|
|
271
|
-
'googlebot', // no i18n
|
|
272
|
-
'googleweblight', // no i18n
|
|
273
|
-
'mediapartners-google', // no i18n
|
|
274
|
-
'storebot-google' // no i18n
|
|
275
|
-
];
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* local storage helper for saving optin status for users.
|
|
279
|
-
*/
|
|
280
|
-
var tracking_preference = {
|
|
281
|
-
|
|
282
|
-
_key: 'apptics-tracking-preference', // no i18n
|
|
283
|
-
_tracking_status: 'tracking_status', // no i18n
|
|
284
|
-
|
|
285
|
-
all: function () {
|
|
286
|
-
return JSON.parse(localStorage.getItem(tracking_preference._key) || JSON.stringify({}));
|
|
287
|
-
},
|
|
288
|
-
// returns a list of all tracking_preference or empty object.
|
|
289
|
-
opt_in_status: function () {
|
|
290
|
-
var status = tracking_preference.all();
|
|
291
|
-
return status[tracking_preference._tracking_status] || AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII;
|
|
292
|
-
},
|
|
293
|
-
// opting in of tracking for a specific device and updates the preference.
|
|
294
|
-
opt_in_tracking_without_pii: function () {
|
|
295
|
-
var status = tracking_preference.all();
|
|
296
|
-
status[tracking_preference._tracking_status] = AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII;
|
|
297
|
-
// save changes
|
|
298
|
-
localStorage.setItem(tracking_preference._key, JSON.stringify(status));
|
|
299
|
-
},
|
|
300
|
-
// opting in of tracking for a specific device and updates the preference.
|
|
301
|
-
opt_in_tracking_with_pii: function () {
|
|
302
|
-
var status = tracking_preference.all();
|
|
303
|
-
status[tracking_preference._tracking_status] = AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII;
|
|
304
|
-
// save changes
|
|
305
|
-
localStorage.setItem(tracking_preference._key, JSON.stringify(status));
|
|
306
|
-
},
|
|
307
|
-
// opting out of tracking for a specific device and updates the preference.
|
|
308
|
-
opt_out_tracking: function () {
|
|
309
|
-
var status = tracking_preference.all();
|
|
310
|
-
status[tracking_preference._tracking_status] = AP_TRACKING_STATUS.NO_TRACKING;
|
|
311
|
-
// save changes
|
|
312
|
-
localStorage.setItem(tracking_preference._key, JSON.stringify(status));
|
|
313
|
-
},
|
|
314
|
-
// opting out of tracking for a specific device and updates the preference.
|
|
315
|
-
update_status: function (tracking_status) {
|
|
316
|
-
var status = tracking_preference.all();
|
|
317
|
-
status[tracking_preference._tracking_status] = tracking_status;
|
|
318
|
-
// save changes
|
|
319
|
-
localStorage.setItem(tracking_preference._key, JSON.stringify(status));
|
|
320
|
-
},
|
|
321
|
-
// clears any pending tracking_preference.
|
|
322
|
-
clear: function () {
|
|
323
|
-
localStorage.setItem(tracking_preference._key, JSON.stringify({}));
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* local storage helper for saving engagement_transactions in order
|
|
329
|
-
*/
|
|
330
|
-
var engagement_transactions = {
|
|
331
|
-
|
|
332
|
-
_key: 'apptics-engagements-transactions', // no i18n
|
|
333
|
-
|
|
334
|
-
// maximum size of payload allowed before we start sending to server
|
|
335
|
-
_maxSize: 1,
|
|
336
|
-
|
|
337
|
-
// returns a list of all engagement_transactions or empty array
|
|
338
|
-
all: function () {
|
|
339
|
-
return JSON.parse(localStorage.getItem(engagement_transactions._key) || JSON.stringify([]));
|
|
340
|
-
},
|
|
341
|
-
// returns a list of all engagement_transactions or empty array
|
|
342
|
-
payload: function () {
|
|
343
|
-
const targetSize = 1024 * 1024; // 1 MB in bytes
|
|
344
|
-
|
|
345
|
-
let dataSize = 0;
|
|
346
|
-
const result = [];
|
|
347
|
-
var existing = engagement_transactions.all().slice(0,getConfig('batch_size')); // no i18n
|
|
348
|
-
for (const item of existing) {
|
|
349
|
-
const size = sizeof(JSON.stringify(item));
|
|
350
|
-
if (dataSize + size > targetSize) {
|
|
351
|
-
break;
|
|
352
|
-
}
|
|
353
|
-
result.push(item);
|
|
354
|
-
dataSize += size;
|
|
355
|
-
}
|
|
356
|
-
return result;
|
|
357
|
-
},
|
|
358
|
-
// adds an item to the transaction log
|
|
359
|
-
add: function (data) {
|
|
360
|
-
|
|
361
|
-
// get existing engagement_transactions
|
|
362
|
-
var existing = engagement_transactions.all();
|
|
363
|
-
|
|
364
|
-
// increase event _id counter
|
|
365
|
-
_internalEventIdCounter++;
|
|
366
|
-
|
|
367
|
-
// add latest to end of stack
|
|
368
|
-
existing.push(data);
|
|
369
|
-
|
|
370
|
-
// save changes
|
|
371
|
-
localStorage.setItem(engagement_transactions._key, JSON.stringify(existing));
|
|
372
|
-
},
|
|
373
|
-
|
|
374
|
-
// adds an item to the transaction log
|
|
375
|
-
update: function (oldElement, newElement) {
|
|
376
|
-
|
|
377
|
-
// get existing engagement_transactions
|
|
378
|
-
var existing = engagement_transactions.all();
|
|
379
|
-
|
|
380
|
-
// var index = existing.indexOf(oldElement);
|
|
381
|
-
var index = existing.findIndex(function(object) {
|
|
382
|
-
return (object.type === oldElement.type && object.starttime === oldElement.starttime);
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
// add latest to end of stack
|
|
386
|
-
if (index !== -1) {
|
|
387
|
-
existing[index] = newElement;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// save changes
|
|
391
|
-
localStorage.setItem(engagement_transactions._key, JSON.stringify(existing));
|
|
392
|
-
},
|
|
393
|
-
|
|
394
|
-
// removes events from the transaction log
|
|
395
|
-
remove: function (itemsToRemove) {
|
|
396
|
-
|
|
397
|
-
// get array of ids to remove
|
|
398
|
-
var idsToRemove = (itemsToRemove || []).map(function(item) {
|
|
399
|
-
return item.id;
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
// go through existing engagement_transactions, removing items that contain a matching id
|
|
403
|
-
var remaining = engagement_transactions.all().filter(function(item) {
|
|
404
|
-
return idsToRemove.indexOf(item.id) === -1;
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
// save changes
|
|
408
|
-
localStorage.setItem(engagement_transactions._key, JSON.stringify(remaining));
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
// clears any pending engagement_transactions
|
|
412
|
-
clear: function () {
|
|
413
|
-
localStorage.setItem(engagement_transactions._key, JSON.stringify([]));
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* local storage helper for saving error_transactions in order
|
|
419
|
-
*/
|
|
420
|
-
var error_transactions = {
|
|
421
|
-
|
|
422
|
-
_key: 'apptics-errors-transactions', // no i18n
|
|
423
|
-
|
|
424
|
-
// maximum number of items allowed before we start dropping first items
|
|
425
|
-
_maxLength: 100,
|
|
426
|
-
|
|
427
|
-
// returns a list of all error_transactions or empty array
|
|
428
|
-
all: function () {
|
|
429
|
-
return JSON.parse(localStorage.getItem(error_transactions._key) || JSON.stringify([]));
|
|
430
|
-
},
|
|
431
|
-
// returns a list of all error_transactions or empty array
|
|
432
|
-
payload: function () {
|
|
433
|
-
const targetSize = 1024 * 1024; // 1 MB in bytes
|
|
434
|
-
|
|
435
|
-
let dataSize = 0;
|
|
436
|
-
const result = [];
|
|
437
|
-
var existing = error_transactions.all().slice(0,getConfig('batch_size')); // no i18n
|
|
438
|
-
for (const item of existing) {
|
|
439
|
-
const size = sizeof(JSON.stringify(item));
|
|
440
|
-
if (dataSize + size > targetSize) {
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
443
|
-
result.push(item);
|
|
444
|
-
dataSize += size;
|
|
445
|
-
}
|
|
446
|
-
return result;
|
|
447
|
-
},
|
|
448
|
-
// adds an item to the transaction log
|
|
449
|
-
add: function (data) {
|
|
450
|
-
|
|
451
|
-
// get existing error_transactions
|
|
452
|
-
var existing = error_transactions.all();
|
|
453
|
-
|
|
454
|
-
// increase event _id counter
|
|
455
|
-
_internalEventIdCounter++;
|
|
456
|
-
|
|
457
|
-
// add latest to end of stack
|
|
458
|
-
existing.push(data);
|
|
459
|
-
|
|
460
|
-
// save changes
|
|
461
|
-
localStorage.setItem(error_transactions._key, JSON.stringify(existing));
|
|
462
|
-
},
|
|
463
|
-
|
|
464
|
-
// adds an item to the transaction log
|
|
465
|
-
update: function (oldElement, newElement) {
|
|
466
|
-
|
|
467
|
-
// get existing error_transactions
|
|
468
|
-
var existing = error_transactions.all();
|
|
469
|
-
|
|
470
|
-
// var index = existing.indexOf(oldElement);
|
|
471
|
-
var index = existing.findIndex(function(object) {
|
|
472
|
-
return (object.type === oldElement.type && object.starttime === oldElement.starttime);
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
// add latest to end of stack
|
|
476
|
-
if (index !== -1) {
|
|
477
|
-
existing[index] = newElement;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// save changes
|
|
481
|
-
localStorage.setItem(error_transactions._key, JSON.stringify(existing));
|
|
482
|
-
},
|
|
483
|
-
|
|
484
|
-
// removes events from the transaction log
|
|
485
|
-
remove: function (itemsToRemove) {
|
|
486
|
-
|
|
487
|
-
// get array of ids to remove
|
|
488
|
-
var idsToRemove = (itemsToRemove || []).map(function(item) {
|
|
489
|
-
return item._id;
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
// go through existing error_transactions, removing items that contain a matching id
|
|
493
|
-
var remaining = error_transactions.all().filter(function(item) {
|
|
494
|
-
return idsToRemove.indexOf(item._id) === -1;
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
// save changes
|
|
498
|
-
localStorage.setItem(error_transactions._key, JSON.stringify(remaining));
|
|
499
|
-
},
|
|
500
|
-
|
|
501
|
-
// clears any pending error_transactions
|
|
502
|
-
clear: function () {
|
|
503
|
-
localStorage.setItem(error_transactions._key, JSON.stringify([]));
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
/**
|
|
509
|
-
* local storage helper for saving user_defaults in order
|
|
510
|
-
*/
|
|
511
|
-
var user_defaults = {
|
|
512
|
-
|
|
513
|
-
_key: 'apptics-device-info', // no i18n
|
|
514
|
-
|
|
515
|
-
// maximum number of items allowed before we start dropping first items
|
|
516
|
-
_maxLength: 100,
|
|
517
|
-
|
|
518
|
-
// returns a list of all user_defaults or empty array
|
|
519
|
-
all: function () {
|
|
520
|
-
return JSON.parse(localStorage.getItem(user_defaults._key) || JSON.stringify({}));
|
|
521
|
-
},
|
|
522
|
-
|
|
523
|
-
item: function (key) {
|
|
524
|
-
// get existing user_defaults
|
|
525
|
-
|
|
526
|
-
var items = user_defaults.all();
|
|
527
|
-
|
|
528
|
-
return items[key];
|
|
529
|
-
|
|
530
|
-
},
|
|
531
|
-
|
|
532
|
-
// adds an item to the transaction log
|
|
533
|
-
add: function (key,value) {
|
|
534
|
-
|
|
535
|
-
// get existing user_defaults
|
|
536
|
-
var existing = user_defaults.all();
|
|
537
|
-
|
|
538
|
-
//add/update the value
|
|
539
|
-
existing[key]=value;
|
|
540
|
-
|
|
541
|
-
// // save changes
|
|
542
|
-
localStorage.setItem(user_defaults._key, JSON.stringify(existing));
|
|
543
|
-
},
|
|
544
|
-
|
|
545
|
-
// add or update an item to the devivce info transaction log
|
|
546
|
-
addorupdatedeviceinfo: function (key,value) {
|
|
547
|
-
|
|
548
|
-
var deviceinfokey = 'device_info';
|
|
549
|
-
// get existing user_defaults device info
|
|
550
|
-
var existing = user_defaults.item(deviceinfokey) || {};
|
|
551
|
-
|
|
552
|
-
//add/update the value
|
|
553
|
-
existing[key]=value;
|
|
554
|
-
|
|
555
|
-
// // save changes
|
|
556
|
-
user_defaults.add(deviceinfokey, existing); // no i18n
|
|
557
|
-
},
|
|
558
|
-
|
|
559
|
-
// removes events from the transaction log
|
|
560
|
-
remove: function (key) {
|
|
561
|
-
|
|
562
|
-
// get existing user_defaults
|
|
563
|
-
var existing = user_defaults.all();
|
|
564
|
-
|
|
565
|
-
//add/update the value
|
|
566
|
-
delete existing[key];
|
|
567
|
-
|
|
568
|
-
// // save changes
|
|
569
|
-
localStorage.setItem(user_defaults._key, JSON.stringify(existing));
|
|
570
|
-
},
|
|
571
|
-
|
|
572
|
-
// clears any pending user_defaults
|
|
573
|
-
clear: function () {
|
|
574
|
-
localStorage.setItem(user_defaults._key, JSON.stringify({}));
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
|
|
578
|
-
function isBlockedWS(ua) {
|
|
579
|
-
var i;
|
|
580
|
-
ua = ua.toLowerCase();
|
|
581
|
-
for (i = 0; i < BLOCKED_WS.length; i++) {
|
|
582
|
-
if (ua.indexOf(BLOCKED_WS[i]) !== -1) {
|
|
583
|
-
return true;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
return false;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
function is_apptics_disabled() {
|
|
590
|
-
return isBlockedWS(_userAgent);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
function hasDoNotTrackEnabled() {
|
|
594
|
-
if (_ignoreDnt) {
|
|
595
|
-
return false;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
var navigator = window.navigator || {};
|
|
599
|
-
var hasDntOn = false;
|
|
600
|
-
|
|
601
|
-
each([
|
|
602
|
-
navigator.doNotTrack, // default
|
|
603
|
-
navigator.msDoNotTrack, // MS
|
|
604
|
-
window.doNotTrack
|
|
605
|
-
], function(dntValue) {
|
|
606
|
-
if (includes([true, 1, '1', 'yes'], dntValue)) {
|
|
607
|
-
hasDntOn = true;
|
|
608
|
-
setTrackingStatus(AP_TRACKING_STATUS.NO_TRACKING);
|
|
609
|
-
}
|
|
610
|
-
});
|
|
611
|
-
return hasDntOn;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
function getConfig(key){
|
|
615
|
-
return _config[key];
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
function getHeaderParams(key){
|
|
619
|
-
if (key == 'zak'){ // no i18n
|
|
620
|
-
return _zak;
|
|
621
|
-
}
|
|
622
|
-
else if (key == 'uuid'){ // no i18n
|
|
623
|
-
return _uuid;
|
|
624
|
-
}
|
|
625
|
-
else if (key == 'apid'){ // no i18n
|
|
626
|
-
return _apid || getKeyFromDeviceInfo(key);
|
|
627
|
-
}
|
|
628
|
-
else if (key == 'mapid'){ // no i18n
|
|
629
|
-
return _mapid || getKeyFromDeviceInfo(key);
|
|
630
|
-
}
|
|
631
|
-
else{
|
|
632
|
-
return '';
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
function getParameters(path){
|
|
637
|
-
let returnVal = '';
|
|
638
|
-
if (path == 'regdevice'){ // no i18n
|
|
639
|
-
// Device
|
|
640
|
-
returnVal = '?identifier='+_identifier+'&platform='+_platform+'&appversion='+APPTICS_FRAMEWORK_VERSION+'&isanonrequired='+_isanonrequired+'&devicestatus='+_devicestatus; // no i18n
|
|
641
|
-
if(_isanonrequired && !isEmpty(_device_info.anonymousid)){
|
|
642
|
-
returnVal += '&anondeviceid='+_device_info.anonymousid; // no i18n
|
|
643
|
-
}
|
|
644
|
-
if(!_isanonrequired && !isEmpty(_device_info.deviceid)){
|
|
645
|
-
returnVal += '&deviceid='+_device_info.deviceid; // no i18n
|
|
646
|
-
}
|
|
647
|
-
return returnVal;
|
|
648
|
-
}
|
|
649
|
-
else{
|
|
650
|
-
if(isEmpty(_device_info.deviceid) || isEmpty(_device_info.anonymousid)){
|
|
651
|
-
checkAndUpdateDeviceInfo();
|
|
652
|
-
return returnVal;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
if(!_isanonrequired && !isEmpty(_device_info.deviceid) || path == 'reguser'){ // no i18n
|
|
656
|
-
returnVal = '?deviceid='+_device_info.deviceid; // no i18n
|
|
657
|
-
if(opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII && path == 'reguser'){ // no i18n
|
|
658
|
-
if(_user_info.hasOwnProperty('userid') && !isEmpty(_user_info.userid)){ // no i18n
|
|
659
|
-
returnVal += '&userid='+ _user_info.userid; // no i18n
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
else if(_isanonrequired && !isEmpty(_device_info.anonymousid)){
|
|
664
|
-
returnVal = '?anondeviceid='+_device_info.anonymousid; // no i18n
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
if(path != 'reguser'){
|
|
668
|
-
if(opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII){
|
|
669
|
-
if(_user_info.hasOwnProperty('userid') && !isEmpty(_user_info.userid)){ // no i18n
|
|
670
|
-
returnVal += '&userid='+ _user_info.userid; // no i18n
|
|
671
|
-
}
|
|
672
|
-
if(_user_info.hasOwnProperty('groupid') && !isEmpty(_user_info.groupid)){ // no i18n
|
|
673
|
-
returnVal += '&customergroupid='+ _user_info.groupid; // no i18n
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
return returnVal;
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
function getUrlWithParams(path){
|
|
682
|
-
return _defaultoptions.base_domain + getConfig('endpoint') +_zsoid+'/'+_projectID+'/'+DEFAULT_API_PATHS[path]+getParameters(path); // no i18n
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
function validateEventOrGroup(str) {
|
|
686
|
-
if (!str || str === ''){
|
|
687
|
-
return false;
|
|
688
|
-
}
|
|
689
|
-
// Define the regular expression pattern
|
|
690
|
-
const pattern = /^[a-zA-Z][a-zA-Z0-9_]{0,99}$/;
|
|
691
|
-
|
|
692
|
-
// Test if the string matches the pattern
|
|
693
|
-
return pattern.test(str);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
function validateJSON(jsonObj) {
|
|
697
|
-
if(isEmpty(jsonObj) || isEmptyObj(jsonObj)){
|
|
698
|
-
return {};
|
|
699
|
-
}
|
|
700
|
-
let maxKeys = 25;
|
|
701
|
-
let maxLength = 7666;
|
|
702
|
-
// Check if the number of keys in the JSON object exceeds the max limit
|
|
703
|
-
if (Object.keys(jsonObj).length >= maxKeys) {
|
|
704
|
-
// Number of keys exceeds the limit
|
|
705
|
-
Console.warn('validateJSON: Property limit exceeds, you can add only a maximum of 25 key-value pairs to the jsonObject'); // no i18n
|
|
706
|
-
return {'isvalid': false, 'message': {'code': 102}}; // no i18n
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
// Convert the JSON object to a string
|
|
710
|
-
const jsonString = JSON.stringify(jsonObj);
|
|
711
|
-
|
|
712
|
-
// Check if the string length exceeds the max limit
|
|
713
|
-
if (jsonString.length > maxLength) {
|
|
714
|
-
// String length exceeds the limit
|
|
715
|
-
Console.warn('validateJSON: Property limit exceeds, the overall length should be below 7666 characters'); // no i18n
|
|
716
|
-
return {'isvalid': false, 'message': {'code': 101}}; // no i18n
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// If both checks pass, return true
|
|
720
|
-
return jsonKeyvalueValidation(jsonObj);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
function jsonKeyvalueValidation(dictionary) {
|
|
724
|
-
let finalDict = {};
|
|
725
|
-
|
|
726
|
-
let dict = dictionary;
|
|
727
|
-
|
|
728
|
-
let result = {
|
|
729
|
-
isvalid: false,
|
|
730
|
-
message: {
|
|
731
|
-
code: [],
|
|
732
|
-
keys: [],
|
|
733
|
-
valuekeys: []
|
|
734
|
-
}
|
|
735
|
-
};
|
|
736
|
-
|
|
737
|
-
let pattern = /^[a-zA-Z][a-zA-Z0-9_]{0,49}$/;
|
|
738
|
-
|
|
739
|
-
for (let key in dict) {
|
|
740
|
-
let matches = key.match(pattern);
|
|
741
|
-
if (!matches) {
|
|
742
|
-
let trimmedKey = key.substring(0, 50);
|
|
743
|
-
result.message.keys.push(trimmedKey);
|
|
744
|
-
Console.warn('jsonKeyvalueValidation: Invalid property, the key \''+key+'\' does not comply with the requirements, please refer to our SDK guide.'); // no i18n
|
|
745
|
-
if (!result.message.code.includes(103)) {
|
|
746
|
-
result.message.code.push(103);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
let value = dict[key];
|
|
751
|
-
let stringValue = JSON.stringify(value);
|
|
752
|
-
if (stringValue.length > 250) {
|
|
753
|
-
Console.warn('jsonKeyvalueValidation: Property limit exceeds, \''+key+'\' value length should be below 250'); // no i18n
|
|
754
|
-
result.message.valuekeys.push(key);
|
|
755
|
-
if (!result.message.code.includes(104)) {
|
|
756
|
-
result.message.code.push(104);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
let areBothArraysEmpty = (result.message.keys.length === 0) && (result.message.valuekeys.length === 0);
|
|
762
|
-
if (areBothArraysEmpty) {
|
|
763
|
-
finalDict = checkForJsonRegex(dict);
|
|
764
|
-
} else {
|
|
765
|
-
finalDict = result;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
return finalDict;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
function checkForJsonRegex(inputDict) {
|
|
772
|
-
|
|
773
|
-
let FinalvalidDictionary = {};
|
|
774
|
-
let regex = /^[a-zA-Z][a-zA-Z0-9_]{0,49}$/;
|
|
775
|
-
let validData = {};
|
|
776
|
-
let validDataType = {};
|
|
777
|
-
let invalidKeys = [];
|
|
778
|
-
for (let key in inputDict) {
|
|
779
|
-
let matchCount = key.match(regex) ? key.match(regex).length : 0;
|
|
780
|
-
let dataType;
|
|
781
|
-
|
|
782
|
-
let obj = inputDict[key];
|
|
783
|
-
|
|
784
|
-
if (typeof obj === 'number') { // no i18n
|
|
785
|
-
dataType = 'Number'; // no i18n
|
|
786
|
-
if (obj === 1 || obj === 0) {
|
|
787
|
-
dataType = 'Boolean'; // no i18n
|
|
788
|
-
}
|
|
789
|
-
} else if (typeof obj === 'string') { // no i18n
|
|
790
|
-
dataType = 'String'; // no i18n
|
|
791
|
-
} else {
|
|
792
|
-
dataType = 'Unkown'; // no i18n
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
if (matchCount > 0) {
|
|
796
|
-
if (dataType === 'Unkown') { // no i18n
|
|
797
|
-
let stringRepresentation = JSON.stringify(obj);
|
|
798
|
-
validData[key] = stringRepresentation;
|
|
799
|
-
validDataType[key] = 'String'; // no i18n
|
|
800
|
-
} else {
|
|
801
|
-
validData[key] = obj;
|
|
802
|
-
validDataType[key] = dataType;
|
|
803
|
-
}
|
|
804
|
-
} else {
|
|
805
|
-
Console.warn('checkForJsonRegex: Invalid property, the key \''+key+'\' does not comply with the requirements, please refer to our SDK guide.'); // no i18n
|
|
806
|
-
invalidKeys.push(key);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
let validResponse = {
|
|
811
|
-
data: validData,
|
|
812
|
-
datatype: validDataType,
|
|
813
|
-
isvalid: true
|
|
814
|
-
};
|
|
815
|
-
|
|
816
|
-
let invalidResponse = {
|
|
817
|
-
isvalid: false,
|
|
818
|
-
message: {
|
|
819
|
-
code: [103],
|
|
820
|
-
keys: invalidKeys
|
|
821
|
-
}
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
if (invalidKeys.length > 0) {
|
|
825
|
-
FinalvalidDictionary = invalidResponse;
|
|
826
|
-
} else {
|
|
827
|
-
if (Object.keys(validData).length > 0) {
|
|
828
|
-
FinalvalidDictionary = validResponse;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
return FinalvalidDictionary;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
function validateScreenName(str) {
|
|
836
|
-
if (!str || str === ''){
|
|
837
|
-
return false;
|
|
838
|
-
}
|
|
839
|
-
// Define the regular expression pattern
|
|
840
|
-
//^[a-zA-Z][\\w\\s]{1,100}$
|
|
841
|
-
const pattern = /^[\w\s.\-_&/:]{0,99}$/;
|
|
842
|
-
|
|
843
|
-
// Test if the string matches the pattern
|
|
844
|
-
return pattern.test(str);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* Returns value of the given super property
|
|
849
|
-
* @param {string} propertyName - name of the property to retrieve
|
|
850
|
-
* @returns {any} value of property
|
|
851
|
-
*/
|
|
852
|
-
function getProperty(propertyName) {
|
|
853
|
-
return _device_info[propertyName];
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
function getProperty() {
|
|
857
|
-
return _device_info;
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Attempt to get the network connection type from w3c NetworkInformation or cordova-plugin-network-information
|
|
861
|
-
* @returns {string} connection type or empty
|
|
862
|
-
*/
|
|
863
|
-
function getConnectionType() {
|
|
864
|
-
var connection = (navigator.connection || navigator.mozConnection || navigator.webkitConnection || {});
|
|
865
|
-
|
|
866
|
-
return connection.effectiveType || connection.type || '';
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
/**
|
|
870
|
-
* clear engagements and error transactions
|
|
871
|
-
* @returns {void}
|
|
872
|
-
*/
|
|
873
|
-
function clear() {
|
|
874
|
-
engagement_transactions.clear();
|
|
875
|
-
error_transactions.clear();
|
|
876
|
-
Console.log('apptics.clear()'); // no i18n
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
/**
|
|
880
|
-
* clear current identity
|
|
881
|
-
* @returns {void}
|
|
882
|
-
*/
|
|
883
|
-
function reset() {
|
|
884
|
-
user_defaults.clear();
|
|
885
|
-
engagement_transactions.clear();
|
|
886
|
-
error_transactions.clear();
|
|
887
|
-
tracking_preference.clear();
|
|
888
|
-
init(_token, _defaultoptions);
|
|
889
|
-
Console.log('apptics.reset()'); // no i18n
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* Track an event.
|
|
894
|
-
* @param {String} eventName The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', 'Item Purchased', etc.
|
|
895
|
-
* @param {String} groupName The name of the group. This can be any group or module name that the event belongs - 'quickstart', 'dashboard', 'store-reviews', 'flow', 'funnel' ,'pricing', etc.
|
|
896
|
-
* @param {Object} [jsonObj] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
897
|
-
* @returns {void}
|
|
898
|
-
*/
|
|
899
|
-
function trackEvent(eventName, groupName, jsonObj) {
|
|
900
|
-
if (!_token) {
|
|
901
|
-
Console.warn('apptics.trackEvent: You must call apptics.init() first'); // no i18n
|
|
902
|
-
return;
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
if (is_apptics_disabled()){
|
|
906
|
-
return;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
if (!shouldTrackOrSendData()){
|
|
910
|
-
return;
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
if (!validateEventOrGroup(eventName)){
|
|
914
|
-
Console.warn('apptics.trackEvent: Invalid eventName'); // no i18n
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
groupName = validateEventOrGroup(groupName) ? groupName : AP_CONFIG.default_group_name;
|
|
919
|
-
jsonObj = jsonObj || {};
|
|
920
|
-
var _jsonObj = validateJSON(jsonObj);
|
|
921
|
-
|
|
922
|
-
//setTimeout((()=>{
|
|
923
|
-
// epoch time in seconds
|
|
924
|
-
var time = Math.round((new Date()).getTime());
|
|
925
|
-
var eventData = {
|
|
926
|
-
id:getNewUUID(),
|
|
927
|
-
type:'event', // no i18n
|
|
928
|
-
group:groupName,
|
|
929
|
-
event: eventName,
|
|
930
|
-
starttime:time,
|
|
931
|
-
endtime:time,
|
|
932
|
-
edge:_device_info.connectionType || getConnectionType(),
|
|
933
|
-
networkstatus: getNetworkStatus(),
|
|
934
|
-
screen:_current_screen.screen || '',
|
|
935
|
-
sessionstarttime:_current_session.starttime || time,
|
|
936
|
-
customproperties: _jsonObj
|
|
937
|
-
};
|
|
938
|
-
|
|
939
|
-
// save the event
|
|
940
|
-
engagement_transactions.add(eventData);
|
|
941
|
-
|
|
942
|
-
Console.log('apptics.trackEvent(\'' + eventName + '\',\'' + groupName + '\',' + JSON.stringify(_jsonObj || {}) + ')'); // no i18n
|
|
943
|
-
Console.dir(eventData);
|
|
944
|
-
//}), 500);
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
/**
|
|
948
|
-
* Track the screen.
|
|
949
|
-
* @param {String} screenName The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', 'Item Purchased', etc.
|
|
950
|
-
* @param {Object} [data] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
951
|
-
* @returns {void}
|
|
952
|
-
*/
|
|
953
|
-
function trackScreen(screenName, jsonObj) {
|
|
954
|
-
|
|
955
|
-
if (!_token) {
|
|
956
|
-
Console.warn('apptics.trackScreen: You must call apptics.init(token) first'); // no i18n
|
|
957
|
-
return;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
if (is_apptics_disabled()){
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
if (!shouldTrackOrSendData()){
|
|
965
|
-
return;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
if (!validateScreenName(screenName)) {
|
|
969
|
-
Console.warn('apptics.trackScreen: Invalid screenName'); // no i18n
|
|
970
|
-
return;
|
|
971
|
-
}
|
|
972
|
-
jsonObj = jsonObj || {};
|
|
973
|
-
var _jsonObj = validateJSON(jsonObj);
|
|
974
|
-
|
|
975
|
-
//setTimeout((()=>{
|
|
976
|
-
// epoch time in seconds
|
|
977
|
-
var time = Math.round((new Date()).getTime());
|
|
978
|
-
var screenData = {
|
|
979
|
-
id:getNewUUID(),
|
|
980
|
-
type:'screen', // no i18n
|
|
981
|
-
screen: screenName,
|
|
982
|
-
starttime:time,
|
|
983
|
-
endtime:time, // need to check
|
|
984
|
-
edge:_device_info.connectionType || getConnectionType(),
|
|
985
|
-
networkstatus: getNetworkStatus(),
|
|
986
|
-
orientation:getOrientation(),
|
|
987
|
-
sessionstarttime:_current_session.starttime || time,
|
|
988
|
-
customproperties: _jsonObj
|
|
989
|
-
};
|
|
990
|
-
|
|
991
|
-
// save the screen
|
|
992
|
-
engagement_transactions.add(screenData);
|
|
993
|
-
_current_screen = screenData;
|
|
994
|
-
|
|
995
|
-
Console.log('apptics.trackScreen(\'' + screenName + '\',' + JSON.stringify(_jsonObj || {}) + ')'); // no i18n
|
|
996
|
-
Console.dir(screenData);
|
|
997
|
-
|
|
998
|
-
//}), 500);
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
/**
|
|
1002
|
-
* Track an api.
|
|
1003
|
-
* * @param {Object} [data] A set of properties to include with the api you're sending. These describe the user who did the api or details about the event itself.
|
|
1004
|
-
* @returns {void}
|
|
1005
|
-
*/
|
|
1006
|
-
function trackApi(jsonObj) {
|
|
1007
|
-
if (!_token) {
|
|
1008
|
-
Console.warn('apptics.trackApi: You must call apptics.init() first'); // no i18n
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
if (is_apptics_disabled()){
|
|
1013
|
-
return;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
if (!shouldTrackOrSendData()){
|
|
1017
|
-
return;
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
jsonObj = jsonObj || {};
|
|
1021
|
-
var _jsonObj = validateJSON(jsonObj);
|
|
1022
|
-
|
|
1023
|
-
//setTimeout((()=>{
|
|
1024
|
-
// epoch time in seconds
|
|
1025
|
-
var time = Math.round((new Date()).getTime());
|
|
1026
|
-
var apiData = {
|
|
1027
|
-
id:getNewUUID(),
|
|
1028
|
-
type:'api', // no i18n
|
|
1029
|
-
starttime:time,
|
|
1030
|
-
endtime:time,
|
|
1031
|
-
edge:_device_info.connectionType || getConnectionType(),
|
|
1032
|
-
networkstatus: getNetworkStatus(),
|
|
1033
|
-
screen:_current_screen.screen || '',
|
|
1034
|
-
sessionstarttime:_current_session.starttime || time,
|
|
1035
|
-
customproperties: _jsonObj
|
|
1036
|
-
};
|
|
1037
|
-
// save the api
|
|
1038
|
-
//engagement_transactions.add(apiData);
|
|
1039
|
-
|
|
1040
|
-
Console.log('apptics.trackApi(\'' + JSON.stringify(_jsonObj || {}) + ')'); // no i18n
|
|
1041
|
-
Console.dir(apiData);
|
|
1042
|
-
//}), 500);
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
function currentScreen() {
|
|
1046
|
-
|
|
1047
|
-
// get all items waiting to be sent
|
|
1048
|
-
var items = engagement_transactions.all();
|
|
1049
|
-
|
|
1050
|
-
// if we have nothing to send, exit
|
|
1051
|
-
if (items.length === -1) {
|
|
1052
|
-
return null;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
// go through existing engagement_transactions, removing items that contain a matching id
|
|
1056
|
-
var screenData = items.filter(function(item) {
|
|
1057
|
-
|
|
1058
|
-
if (item.type == 'screen' && item.endtime === 0) {
|
|
1059
|
-
// Return the item
|
|
1060
|
-
return item;
|
|
1061
|
-
}
|
|
1062
|
-
});
|
|
1063
|
-
|
|
1064
|
-
screenData = screenData.sort(function (a, b){
|
|
1065
|
-
return b.starttime - a.starttime;
|
|
1066
|
-
});
|
|
1067
|
-
|
|
1068
|
-
var _screen = screenData[0];
|
|
1069
|
-
|
|
1070
|
-
if (_screen) {
|
|
1071
|
-
Console.log('currentScreen: (' + JSON.stringify(_screen || {}) + ')'); // no i18n
|
|
1072
|
-
}
|
|
1073
|
-
Console.dir(_screen);
|
|
1074
|
-
|
|
1075
|
-
return _screen;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
function updateScreenWithEndtime() {
|
|
1079
|
-
var time = Math.round((new Date()).getTime());
|
|
1080
|
-
var _currentScreen = currentScreen();
|
|
1081
|
-
if (_currentScreen && _currentScreen.endtime == 0){
|
|
1082
|
-
var _oldScreen = _currentScreen;
|
|
1083
|
-
var _newScreen = Object.assign({}, _oldScreen)
|
|
1084
|
-
_newScreen.endtime=time;
|
|
1085
|
-
engagement_transactions.update(_oldScreen,_newScreen);
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
/**
|
|
1090
|
-
* Track the session.
|
|
1091
|
-
* @param {Object} [sessionData] A set of properties belongs to the session.
|
|
1092
|
-
* @returns {void}
|
|
1093
|
-
*/
|
|
1094
|
-
function trackSession(sessionData) {
|
|
1095
|
-
|
|
1096
|
-
if (!_token) {
|
|
1097
|
-
Console.warn('apptics.trackScreen: You must call apptics.init(token) first'); // no i18n
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
if (is_apptics_disabled()){
|
|
1102
|
-
return;
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
if (!shouldTrackOrSendData()){
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
if (sessionData && typeof sessionData !== 'object') {
|
|
1111
|
-
Console.warn('apptics.trackSession: sessionData param must be an object'); // no i18n
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
engagement_transactions.add(sessionData);
|
|
1117
|
-
|
|
1118
|
-
if (sessionData) {
|
|
1119
|
-
Console.log('apptics.trackSession(' + JSON.stringify(sessionData || {}) + ')'); // no i18n
|
|
1120
|
-
}
|
|
1121
|
-
Console.dir(sessionData);
|
|
1122
|
-
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
|
-
function currentSession() {
|
|
1126
|
-
|
|
1127
|
-
// get all items waiting to be sent
|
|
1128
|
-
var items = engagement_transactions.all();
|
|
1129
|
-
|
|
1130
|
-
// if we have nothing to send, exit
|
|
1131
|
-
if (items.length === -1) {
|
|
1132
|
-
return null;
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
// go through existing engagement_transactions, removing items that contain a matching id
|
|
1136
|
-
var sessionData = items.filter(function(item) {
|
|
1137
|
-
|
|
1138
|
-
if (item.type == 'session' && item.endtime === 0) {
|
|
1139
|
-
// Return the item
|
|
1140
|
-
return item;
|
|
1141
|
-
}
|
|
1142
|
-
});
|
|
1143
|
-
|
|
1144
|
-
sessionData = sessionData.sort(function (a, b){
|
|
1145
|
-
return b.starttime - a.starttime;
|
|
1146
|
-
});
|
|
1147
|
-
|
|
1148
|
-
var _session = sessionData[0];
|
|
1149
|
-
|
|
1150
|
-
if (_session) {
|
|
1151
|
-
Console.log('currentSession: (' + JSON.stringify(_session || {}) + ')'); // no i18n
|
|
1152
|
-
Console.dir(_session);
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
return _session;
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
function startNewSession(time){
|
|
1159
|
-
var storage = calculateLocalStorageSize();
|
|
1160
|
-
_current_session={
|
|
1161
|
-
id:getNewUUID(),
|
|
1162
|
-
type:'session', // no i18n
|
|
1163
|
-
starttime:time,
|
|
1164
|
-
endtime:0,
|
|
1165
|
-
edge:getConnectionType(),
|
|
1166
|
-
orientation:getOrientation(),
|
|
1167
|
-
firstsession:'false', // no i18n //need to check
|
|
1168
|
-
networkstatus:getNetworkStatus(),
|
|
1169
|
-
//startlocalstoragesize:storage.totalSizeKB, //need to check
|
|
1170
|
-
//endlocalstoragesize:storage.totalSizeKB, //need to check
|
|
1171
|
-
lastactivetime:time
|
|
1172
|
-
};
|
|
1173
|
-
trackSession(_current_session);
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
/**
|
|
1177
|
-
* Track an error.
|
|
1178
|
-
* @param {Object} [error] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
1179
|
-
* @param {Object} [data] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
1180
|
-
* @returns {void}
|
|
1181
|
-
*/
|
|
1182
|
-
function trackError(errorEvent, jsonObj) {
|
|
1183
|
-
|
|
1184
|
-
if (!_token) {
|
|
1185
|
-
Console.warn('apptics.trackScreen: You must call apptics.init(token) first'); // no i18n
|
|
1186
|
-
return;
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
if (is_apptics_disabled()){
|
|
1190
|
-
return;
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
if (!shouldTrackOrSendData()){
|
|
1194
|
-
return;
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
if (isEmpty(errorEvent)) {
|
|
1198
|
-
Console.warn('apptics.trackError: Invalid error'); // no i18n
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
var _jsonObj = validateJSON(jsonObj);
|
|
1203
|
-
|
|
1204
|
-
var stack = errorEvent.error?.stack || "";
|
|
1205
|
-
var methodName = extractMethodNameFromStackTrace(stack);
|
|
1206
|
-
var issuetype = errorEvent.type || "";
|
|
1207
|
-
var message = isEmpty(stack) ? errorEvent.toString() : errorEvent.message + ' at ' + methodName;
|
|
1208
|
-
|
|
1209
|
-
// epoch time in seconds
|
|
1210
|
-
var time = Math.round((new Date()).getTime());
|
|
1211
|
-
var errorData = {
|
|
1212
|
-
id:getNewUUID(),
|
|
1213
|
-
type:'error', // no i18n
|
|
1214
|
-
edge:_device_info.connectionType || getConnectionType(),
|
|
1215
|
-
networkstatus:getNetworkStatus(),
|
|
1216
|
-
happenedat:time,
|
|
1217
|
-
issuename:message,
|
|
1218
|
-
message:stack,
|
|
1219
|
-
screenname:_current_screen.screen || window.location.pathname,
|
|
1220
|
-
sessionstarttime:_current_session.starttime || time,
|
|
1221
|
-
customproperties: _jsonObj
|
|
1222
|
-
};
|
|
1223
|
-
|
|
1224
|
-
// save the error
|
|
1225
|
-
error_transactions.add(errorData);
|
|
1226
|
-
|
|
1227
|
-
Console.log('apptics.trackError(\'' + issuetype + '\',\'' + message + '\',' + JSON.stringify(_jsonObj || {}) + ')'); // no i18n
|
|
1228
|
-
Console.dir(errorData);
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
function enableGlobalErrorHandler(status){
|
|
1233
|
-
_isGlobalErrorTracking = typeof status === "boolean" ? status : true;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
/**
|
|
1237
|
-
* Feedback
|
|
1238
|
-
* @returns {void}
|
|
1239
|
-
*/
|
|
1240
|
-
|
|
1241
|
-
function feedbackOpen(){
|
|
1242
|
-
feedback.init();
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
function feedbackClose(){
|
|
1246
|
-
feedback.close();
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
function sendFeedback(feedbackType, feedbackMessage, attachments){
|
|
1250
|
-
dataobj = {
|
|
1251
|
-
type : !isEmpty(feedbackType) ? feedbackType : 1,
|
|
1252
|
-
message : feedbackMessage || '',
|
|
1253
|
-
attachment : attachments || null,
|
|
1254
|
-
quartzid : ''
|
|
1255
|
-
}
|
|
1256
|
-
sendFeedbackData(dataobj);
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
/**
|
|
1260
|
-
* setUser a user with a unique ID instead of a apptics randomly generated distinct_id.
|
|
1261
|
-
* If the method is never called, unique visitors will be identified by a UUID generated the first time they visit the site.
|
|
1262
|
-
* @param {String} [userid] A string that uniquely identifies a user.
|
|
1263
|
-
* * @param {String} [groupid] A string that uniquely identifies a user group.
|
|
1264
|
-
* @returns {void}
|
|
1265
|
-
*/
|
|
1266
|
-
function setUser(userid, groupid, jsonObj) {
|
|
1267
|
-
|
|
1268
|
-
if (!_token) {
|
|
1269
|
-
Console.warn('apptics.setUser: You must call apptics.init(token) first'); // no i18n
|
|
1270
|
-
return;
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
if (is_apptics_disabled()){
|
|
1274
|
-
return;
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
if (!shouldTrackOrSendData()){
|
|
1278
|
-
return;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
if (isEmpty(userid)) {
|
|
1283
|
-
Console.warn('apptics.setUser: Invalid userid'); // no i18n
|
|
1284
|
-
return;
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
if(isEmpty(groupid)){
|
|
1288
|
-
Console.warn('apptics.setUser: Invalid groupid'); // no i18n
|
|
1289
|
-
return;
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
jsonObj = jsonObj || {};
|
|
1293
|
-
let _jsonObj = validateJSON(jsonObj);
|
|
1294
|
-
|
|
1295
|
-
//setTimeout((()=>{
|
|
1296
|
-
|
|
1297
|
-
var user_info={
|
|
1298
|
-
mam: userid,
|
|
1299
|
-
customergroupid: groupid,
|
|
1300
|
-
appversionid: _device_info.appversionid || '', // no i18n
|
|
1301
|
-
status: 1,
|
|
1302
|
-
happendat: Math.round((new Date()).getTime())
|
|
1303
|
-
};
|
|
1304
|
-
|
|
1305
|
-
if(_jsonObj.hasOwnProperty('isvalid') || _jsonObj.isvalid == true){ // no i18n
|
|
1306
|
-
user_info.userproperties = _jsonObj;
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
registerUserWithApptics(user_info).then(function (user_info) {
|
|
1310
|
-
Console.log('setUser: ' + JSON.stringify(user_info)); // no i18n
|
|
1311
|
-
}).catch(function (err){
|
|
1312
|
-
Console.log(err);
|
|
1313
|
-
});
|
|
1314
|
-
|
|
1315
|
-
//}), 500);
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
function addOrUpdateUser(user_info) {
|
|
1319
|
-
|
|
1320
|
-
if (!shouldTrackOrSendData()){
|
|
1321
|
-
return;
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
var users = user_defaults.item('users') || []; // no i18n
|
|
1325
|
-
|
|
1326
|
-
var index = users.findIndex(function(item) {
|
|
1327
|
-
return item.userid === user_info.userid;
|
|
1328
|
-
});
|
|
1329
|
-
|
|
1330
|
-
// If the object with the matching id is found, replace it with the new object
|
|
1331
|
-
if (index !== -1) {
|
|
1332
|
-
users[index]=user_info;
|
|
1333
|
-
}
|
|
1334
|
-
else{
|
|
1335
|
-
users = [user_info];
|
|
1336
|
-
}
|
|
1337
|
-
|
|
1338
|
-
user_defaults.add('users', users); // no i18n
|
|
1339
|
-
|
|
1340
|
-
}
|
|
1341
|
-
|
|
1342
|
-
function getUserInfo(id) {
|
|
1343
|
-
|
|
1344
|
-
if (!id || id.trim() === '') {
|
|
1345
|
-
Console.warn('getUserInfo: Invalid id'); // no i18n
|
|
1346
|
-
return;
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
Console.log('getUserInfo: (\'' + id + '\')'); // no i18n
|
|
1350
|
-
|
|
1351
|
-
var users = user_defaults.item('users') || []; // no i18n
|
|
1352
|
-
|
|
1353
|
-
var index = users.findIndex(function(item) {
|
|
1354
|
-
return item.id === id;
|
|
1355
|
-
});
|
|
1356
|
-
|
|
1357
|
-
// If the object with the matching id is found, replace it with the new object
|
|
1358
|
-
if (index !== -1) {
|
|
1359
|
-
var user_info = users[index];
|
|
1360
|
-
return user_info;
|
|
1361
|
-
}
|
|
1362
|
-
else {
|
|
1363
|
-
Console.log('Object with the specified ID \''+id+'\' not found while updating the user info'); // no i18n
|
|
1364
|
-
return null;
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
/**
|
|
1369
|
-
* Register a set of super properties, which are included with all events
|
|
1370
|
-
* @param {object} data - JSON key/value pair
|
|
1371
|
-
* @returns {void}
|
|
1372
|
-
*/
|
|
1373
|
-
function flush() {
|
|
1374
|
-
|
|
1375
|
-
if (!_token) {
|
|
1376
|
-
Console.warn('apptics.flush: You must call apptics.init(token) first'); // no i18n
|
|
1377
|
-
return;
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
if (is_apptics_disabled()){
|
|
1381
|
-
return;
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
if (!shouldTrackOrSendData()){
|
|
1385
|
-
return;
|
|
1386
|
-
}
|
|
1387
|
-
_sending = false;
|
|
1388
|
-
sendEngagementData();
|
|
1389
|
-
sendErrorData();
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
/**
|
|
1394
|
-
* Sends pending events to apptics API
|
|
1395
|
-
* @returns {void}
|
|
1396
|
-
*/
|
|
1397
|
-
function sendEngagementData() {
|
|
1398
|
-
|
|
1399
|
-
if (is_apptics_disabled()){
|
|
1400
|
-
return;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
if (!shouldTrackOrSendData()){
|
|
1404
|
-
return;
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
if (navigator.onLine == false){
|
|
1408
|
-
Console.warn('sendEngagementData: No Network'); // no i18n
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
// if we're busy sending
|
|
1412
|
-
if (_sending) {
|
|
1413
|
-
// clear defer timeout if it exists
|
|
1414
|
-
if (_deferSendTimer) {
|
|
1415
|
-
clearTimeout(_deferSendTimer);
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
// set a new timer to recall send in .5s
|
|
1419
|
-
_deferSendTimer = setTimeout(sendEngagementData, 500);
|
|
1420
|
-
|
|
1421
|
-
// exit
|
|
1422
|
-
return;
|
|
1423
|
-
}
|
|
1424
|
-
// get all items waiting to be sent
|
|
1425
|
-
var engagement_items = engagement_transactions.payload().filter(function (item){
|
|
1426
|
-
|
|
1427
|
-
if (item.endtime != 0) {
|
|
1428
|
-
var todaytime = Math.round((new Date()).getTime());
|
|
1429
|
-
var batch_timeout = todaytime - (getConfig('batch_request_timeout') * 24 * 60 * 60 * 1000);
|
|
1430
|
-
if(item.starttime >= batch_timeout && item.starttime <= todaytime){
|
|
1431
|
-
// Return the item
|
|
1432
|
-
return item;
|
|
1433
|
-
}
|
|
1434
|
-
else{
|
|
1435
|
-
//Remove the item
|
|
1436
|
-
engagement_transactions.remove([item]);
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
});
|
|
1440
|
-
|
|
1441
|
-
// if we have nothing to send, exit
|
|
1442
|
-
if (engagement_items.length == 0) {
|
|
1443
|
-
return;
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// otherwise, flag sending as started
|
|
1447
|
-
_sending = true;
|
|
1448
|
-
|
|
1449
|
-
// clear defer timeout if it exists
|
|
1450
|
-
if (_deferSendTimer) {
|
|
1451
|
-
clearTimeout(_deferSendTimer);
|
|
1452
|
-
_deferSendTimer = null;
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
// convert each pending transaction into a request promise
|
|
1456
|
-
let sessionObj = [], screenObj = [], eventObj = [];
|
|
1457
|
-
var _payload = {},
|
|
1458
|
-
removepayloadids = [],
|
|
1459
|
-
removepayload = cloneObject(engagement_items).filter(function (item) {
|
|
1460
|
-
|
|
1461
|
-
const itemWithId = { ...item };
|
|
1462
|
-
|
|
1463
|
-
if(item.type == 'event'){ // no i18n
|
|
1464
|
-
eventObj.push(item);
|
|
1465
|
-
removepayloadids.push(itemWithId);
|
|
1466
|
-
}
|
|
1467
|
-
else if(item.type == 'screen'){ // no i18n
|
|
1468
|
-
screenObj.push(item);
|
|
1469
|
-
removepayloadids.push(itemWithId);
|
|
1470
|
-
}
|
|
1471
|
-
else if(item.type == 'session'){
|
|
1472
|
-
sessionObj.push(item);
|
|
1473
|
-
removepayloadids.push(itemWithId);
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
delete item.id;
|
|
1477
|
-
delete item.type;
|
|
1478
|
-
|
|
1479
|
-
return item;
|
|
1480
|
-
});
|
|
1481
|
-
|
|
1482
|
-
eventObj.length > 0 ? _payload.events = eventObj : [];
|
|
1483
|
-
screenObj.length > 0 ? _payload.screens = screenObj : [];
|
|
1484
|
-
sessionObj.length > 0 ? _payload.sessions = sessionObj : [];
|
|
1485
|
-
|
|
1486
|
-
if (isEmptyObj(_payload)){
|
|
1487
|
-
return;
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
requestToSendEngagements(_payload).then(function (result){
|
|
1491
|
-
if (result && result.result == 'success'){ // no i18n
|
|
1492
|
-
engagement_transactions.remove(removepayloadids);
|
|
1493
|
-
_sending = false;
|
|
1494
|
-
}
|
|
1495
|
-
}).catch(function (err){
|
|
1496
|
-
Console.log('sendEngagementData:' + err);
|
|
1497
|
-
// something went wrong, allow this method to be recalled
|
|
1498
|
-
_sending = false;
|
|
1499
|
-
});
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
/**
|
|
1503
|
-
* Sends pending error to apptics API
|
|
1504
|
-
* @returns {void}
|
|
1505
|
-
*/
|
|
1506
|
-
function sendErrorData() {
|
|
1507
|
-
|
|
1508
|
-
if (is_apptics_disabled()){
|
|
1509
|
-
return;
|
|
1510
|
-
}
|
|
1511
|
-
|
|
1512
|
-
if (!shouldTrackOrSendData()){
|
|
1513
|
-
return;
|
|
1514
|
-
}
|
|
1515
|
-
|
|
1516
|
-
if (navigator.onLine == false){
|
|
1517
|
-
Console.warn('sendErrorData: No Network'); // no i18n
|
|
1518
|
-
return;
|
|
1519
|
-
}
|
|
1520
|
-
// if we're busy sending
|
|
1521
|
-
if (_sending) {
|
|
1522
|
-
// clear defer timeout if it exists
|
|
1523
|
-
if (_deferSendTimer) {
|
|
1524
|
-
clearTimeout(_deferSendTimer);
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
// set a new timer to recall send in .5s
|
|
1528
|
-
_deferSendTimer = setTimeout(sendErrorData, 500);
|
|
1529
|
-
|
|
1530
|
-
// exit
|
|
1531
|
-
return;
|
|
1532
|
-
}
|
|
1533
|
-
// get all items waiting to be sent
|
|
1534
|
-
var error_items = error_transactions.payload().filter(function (item){
|
|
1535
|
-
if (item.happenedat != 0) {
|
|
1536
|
-
var todaytime = Math.round((new Date()).getTime());
|
|
1537
|
-
var batch_timeout = todaytime - (getConfig('batch_request_timeout') * 24 * 60 * 60 * 1000);
|
|
1538
|
-
if(item.happenedat >= batch_timeout && item.happenedat <= todaytime){
|
|
1539
|
-
// Return the item
|
|
1540
|
-
return item;
|
|
1541
|
-
}
|
|
1542
|
-
else{
|
|
1543
|
-
// Remove the item
|
|
1544
|
-
error_transactions.remove([item]);
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
});
|
|
1548
|
-
|
|
1549
|
-
// if we have nothing to send, exit
|
|
1550
|
-
if (error_items.length == 0) {
|
|
1551
|
-
return;
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
// otherwise, flag sending as started
|
|
1555
|
-
_sending = true;
|
|
1556
|
-
|
|
1557
|
-
// clear defer timeout if it exists
|
|
1558
|
-
if (_deferSendTimer) {
|
|
1559
|
-
clearTimeout(_deferSendTimer);
|
|
1560
|
-
_deferSendTimer = null;
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
// convert each pending transaction into a request promise
|
|
1564
|
-
let exceptiondetails = [];
|
|
1565
|
-
var _payload = {},
|
|
1566
|
-
removepayloadids = [],
|
|
1567
|
-
errorpayload = cloneObject(error_items).filter(function (item) {
|
|
1568
|
-
|
|
1569
|
-
const itemWithId = { ...item };
|
|
1570
|
-
|
|
1571
|
-
if(!item.hasOwnProperty('screenname')){
|
|
1572
|
-
item.screenname = '';
|
|
1573
|
-
}
|
|
1574
|
-
exceptiondetails.push(item);
|
|
1575
|
-
removepayloadids.push(itemWithId);
|
|
1576
|
-
delete item.id;
|
|
1577
|
-
delete item.type;
|
|
1578
|
-
return item;
|
|
1579
|
-
});
|
|
1580
|
-
|
|
1581
|
-
exceptiondetails.length > 0 ? _payload.exceptiondetails = exceptiondetails : [];
|
|
1582
|
-
|
|
1583
|
-
if (isEmptyObj(_payload)){
|
|
1584
|
-
return;
|
|
1585
|
-
}
|
|
1586
|
-
requestToSendErrors(_payload).then(function (result){
|
|
1587
|
-
if (result && result.result == 'success'){ // no i18n
|
|
1588
|
-
error_transactions.remove(removepayloadids);
|
|
1589
|
-
_sending = false;
|
|
1590
|
-
}
|
|
1591
|
-
}).catch(function (err){
|
|
1592
|
-
Console.log('sendErrorData:' + err);
|
|
1593
|
-
// something went wrong, allow this method to be recalled
|
|
1594
|
-
_sending = false;
|
|
1595
|
-
});
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
/**
|
|
1600
|
-
* Sends feedback to apptics API
|
|
1601
|
-
* @returns {void}
|
|
1602
|
-
*/
|
|
1603
|
-
function sendFeedbackData(obj) {
|
|
1604
|
-
if (is_apptics_disabled()){
|
|
1605
|
-
return;
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
// if (!shouldTrackOrSendData()){
|
|
1609
|
-
// return;
|
|
1610
|
-
// }
|
|
1611
|
-
|
|
1612
|
-
if (navigator.onLine == false){
|
|
1613
|
-
Console.warn('sendFeedbackData: No Network'); // no i18n
|
|
1614
|
-
return;
|
|
1615
|
-
}
|
|
1616
|
-
// if we're busy sending
|
|
1617
|
-
// if (_sending) {
|
|
1618
|
-
// // clear defer timeout if it exists
|
|
1619
|
-
// if (_deferSendTimer) {
|
|
1620
|
-
// clearTimeout(_deferSendTimer);
|
|
1621
|
-
// }
|
|
1622
|
-
|
|
1623
|
-
// // set a new timer to recall send in .5s
|
|
1624
|
-
// _deferSendTimer = setTimeout(sendFeedbackData, 500);
|
|
1625
|
-
|
|
1626
|
-
// // exit
|
|
1627
|
-
// return;
|
|
1628
|
-
// }
|
|
1629
|
-
|
|
1630
|
-
// // otherwise, flag sending as started
|
|
1631
|
-
// _sending = true;
|
|
1632
|
-
|
|
1633
|
-
// // clear defer timeout if it exists
|
|
1634
|
-
// if (_deferSendTimer) {
|
|
1635
|
-
// clearTimeout(_deferSendTimer);
|
|
1636
|
-
// _deferSendTimer = null;
|
|
1637
|
-
// }
|
|
1638
|
-
|
|
1639
|
-
// convert each pending transaction into a request promise
|
|
1640
|
-
var _payload = {};
|
|
1641
|
-
var _attachment = obj?.attachment || null;
|
|
1642
|
-
var _attachment_count = obj?.attachment?.length || 0;
|
|
1643
|
-
var time = Math.round((new Date()).getTime());
|
|
1644
|
-
var sendformdata = new FormData();
|
|
1645
|
-
var feedinfoObj = {
|
|
1646
|
-
networkstatus : getNetworkStatus(),
|
|
1647
|
-
orientation : getOrientation(),
|
|
1648
|
-
//battery : getBattery(),
|
|
1649
|
-
edge: getConnectionType(),
|
|
1650
|
-
ram : '',
|
|
1651
|
-
screenname : _current_screen.screenName || '',
|
|
1652
|
-
sessionstarttime : _current_session.starttime || time,
|
|
1653
|
-
report : obj.message,
|
|
1654
|
-
type : obj.type,
|
|
1655
|
-
source : 0,
|
|
1656
|
-
attachmentcount : _attachment_count || 0,
|
|
1657
|
-
logfilecount : 0,
|
|
1658
|
-
tag : '',
|
|
1659
|
-
happendat : time,
|
|
1660
|
-
quartzid : obj.quartzid
|
|
1661
|
-
};
|
|
1662
|
-
var feedinfoSendObj = {feedinfo: feedinfoObj, meta : getMetaObj()}
|
|
1663
|
-
sendformdata.append('feedinfo', JSON.stringify(feedinfoSendObj));
|
|
1664
|
-
|
|
1665
|
-
if(!isEmpty(_attachment) && _attachment_count > 0 && _attachment_count <= 5){
|
|
1666
|
-
// var modal = document.getElementById("zasdkFeedbackModal");
|
|
1667
|
-
// const inputElement = modal.querySelector('#zasdkFileInput');
|
|
1668
|
-
// const fileList = inputElement.files;
|
|
1669
|
-
let filecounter = 0;
|
|
1670
|
-
const fileList = _attachment;
|
|
1671
|
-
|
|
1672
|
-
for (let i = 0; i < fileList.length; i++) {
|
|
1673
|
-
|
|
1674
|
-
const reader = new FileReader();
|
|
1675
|
-
var file = fileList[i];
|
|
1676
|
-
reader.readAsArrayBuffer(file);
|
|
1677
|
-
reader.onload = function(event) {
|
|
1678
|
-
const fileContent = event.target.result;
|
|
1679
|
-
const newFileName = "image_" + (i+1);
|
|
1680
|
-
|
|
1681
|
-
const newFile = new File([fileContent], newFileName, { type: file.type });
|
|
1682
|
-
|
|
1683
|
-
sendformdata.append('attachment', newFile);
|
|
1684
|
-
filecounter++;
|
|
1685
|
-
if(filecounter === fileList.length){
|
|
1686
|
-
readyToSendFeedback(sendformdata)
|
|
1687
|
-
|
|
1688
|
-
}
|
|
1689
|
-
};
|
|
1690
|
-
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
else{
|
|
1694
|
-
readyToSendFeedback(sendformdata)
|
|
1695
|
-
}
|
|
1696
|
-
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
function readyToSendFeedback(data){
|
|
1700
|
-
requestToSendFeedback(data).then(function (result){
|
|
1701
|
-
if (result && result.result == 'success'){ // no i18n
|
|
1702
|
-
_sending = false;
|
|
1703
|
-
|
|
1704
|
-
feedback.handleStatusmsg(true, 'Feedback sent successfully'); // no i18n
|
|
1705
|
-
setTimeout(() => {
|
|
1706
|
-
feedback.close();
|
|
1707
|
-
}, 2000);
|
|
1708
|
-
//
|
|
1709
|
-
}
|
|
1710
|
-
else{
|
|
1711
|
-
feedback.handleStatusmsg(false, 'Something went wrong. Send feedback again'); // no i18n
|
|
1712
|
-
_sending = false;
|
|
1713
|
-
Console.log('sendFeedbackData:' + result);
|
|
1714
|
-
}
|
|
1715
|
-
}).catch(function (err){
|
|
1716
|
-
feedback.handleStatusmsg(false, 'Something went wrong. Send feedback again'); // no i18n
|
|
1717
|
-
_sending = false;
|
|
1718
|
-
Console.log('sendFeedbackData:' + err);
|
|
1719
|
-
});
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
/* #region Helpers */
|
|
1723
|
-
|
|
1724
|
-
/**
|
|
1725
|
-
* Clones a JSON object
|
|
1726
|
-
* @param {object} obj - object to clone
|
|
1727
|
-
* @returns {object} cloned object
|
|
1728
|
-
*/
|
|
1729
|
-
function cloneObject(obj) {
|
|
1730
|
-
return JSON.parse(JSON.stringify(obj));
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
/**
|
|
1734
|
-
* Executes an array of function that return a promise in sequence
|
|
1735
|
-
* @param {Array} promises - array of functions that return a promise
|
|
1736
|
-
* @returns {Promise} executes .then if all resolve otherwise .catch
|
|
1737
|
-
*/
|
|
1738
|
-
function promisesInSequence(promises) {
|
|
1739
|
-
var result = Promise.resolve();
|
|
1740
|
-
|
|
1741
|
-
promises.forEach(function (promise) {
|
|
1742
|
-
result = result.then(promise);
|
|
1743
|
-
});
|
|
1744
|
-
|
|
1745
|
-
return result;
|
|
1746
|
-
}
|
|
1747
|
-
|
|
1748
|
-
// Function to calculate the size of a JavaScript object in bytes
|
|
1749
|
-
function sizeof(obj) {
|
|
1750
|
-
let bytes = 0;
|
|
1751
|
-
|
|
1752
|
-
function sizeOf(obj) {
|
|
1753
|
-
if (obj !== null && typeof obj === 'object') { // no i18n
|
|
1754
|
-
for (const key in obj) {
|
|
1755
|
-
if (obj.hasOwnProperty(key)) {
|
|
1756
|
-
bytes += key.length * 2; // 2 bytes per character
|
|
1757
|
-
sizeOf(obj[key]);
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
else if (typeof obj === 'string') { // no i18n
|
|
1762
|
-
bytes += obj.length * 2; // 2 bytes per character
|
|
1763
|
-
}
|
|
1764
|
-
else if (typeof obj === 'number') { // no i18n
|
|
1765
|
-
bytes += 8; // 8 bytes for a number
|
|
1766
|
-
}
|
|
1767
|
-
else if (typeof obj === 'boolean') { // no i18n
|
|
1768
|
-
bytes += 4; // 4 bytes for a boolean
|
|
1769
|
-
}
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
sizeOf(obj);
|
|
1773
|
-
return bytes;
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
/**
|
|
1777
|
-
* Gets the NetworkStatus like online, offline etc
|
|
1778
|
-
* @returns {int} networkstatus
|
|
1779
|
-
*/
|
|
1780
|
-
function getNetworkStatus(){
|
|
1781
|
-
return window.navigator.onLine ? 0 : -1;
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1784
|
-
/**
|
|
1785
|
-
* Gets the Orientation like portrait, landscape etc
|
|
1786
|
-
* @returns {int} Orientation
|
|
1787
|
-
*/
|
|
1788
|
-
function getOrientation() {
|
|
1789
|
-
var orientation = window.screen.orientation.type;
|
|
1790
|
-
if (includes(orientation, 'portrait-primary')) { // no i18n
|
|
1791
|
-
return 0;
|
|
1792
|
-
}
|
|
1793
|
-
if (includes(orientation, 'landscape-primary')) { // no i18n
|
|
1794
|
-
return 1;
|
|
1795
|
-
}
|
|
1796
|
-
if (includes(orientation, 'landscape-secondary')) { // no i18n
|
|
1797
|
-
return 2;
|
|
1798
|
-
}
|
|
1799
|
-
if (includes(orientation, 'portrait-secondary')) { // no i18n
|
|
1800
|
-
return 3;
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
return -1;
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
/**
|
|
1807
|
-
* Gets the device type iPad, iPhone etc
|
|
1808
|
-
* @returns {string} device name
|
|
1809
|
-
*/
|
|
1810
|
-
function getDevice() {
|
|
1811
|
-
|
|
1812
|
-
var ua = navigator.userAgent;
|
|
1813
|
-
|
|
1814
|
-
if (/Windows/i.test(ua)) {
|
|
1815
|
-
return (/Phone/.test(ua) || /WPDesktop/.test(ua)) ? 'Windows Phone' : 'Windows'; // no i18n
|
|
1816
|
-
}
|
|
1817
|
-
if (/iPad/.test(ua)) {
|
|
1818
|
-
return 'iPad'; // no i18n
|
|
1819
|
-
}
|
|
1820
|
-
if (/iPod/.test(ua)) {
|
|
1821
|
-
return 'iPod Touch'; // no i18n
|
|
1822
|
-
}
|
|
1823
|
-
if (/iPhone/.test(ua)) {
|
|
1824
|
-
return 'iPhone'; // no i18n
|
|
1825
|
-
}
|
|
1826
|
-
if (/(BlackBerry|PlayBook|BB10)/i.test(ua)) {
|
|
1827
|
-
return 'BlackBerry'; // no i18n
|
|
1828
|
-
}
|
|
1829
|
-
if (/Android/.test(ua)) {
|
|
1830
|
-
return 'Android'; // no i18n
|
|
1831
|
-
}
|
|
1832
|
-
if (/Mac/i.test(ua)) {
|
|
1833
|
-
return 'Mac'; // no i18n
|
|
1834
|
-
}
|
|
1835
|
-
if (/Linux/.test(ua)) {
|
|
1836
|
-
return 'Linux'; // no i18n
|
|
1837
|
-
}
|
|
1838
|
-
if (/CrOS/.test(ua)) {
|
|
1839
|
-
return 'Chrome'; // no i18n
|
|
1840
|
-
}
|
|
1841
|
-
return '';
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
/**
|
|
1845
|
-
* Gets the Operating System
|
|
1846
|
-
* @returns {string} os name
|
|
1847
|
-
*/
|
|
1848
|
-
function getOS() {
|
|
1849
|
-
|
|
1850
|
-
var ua = navigator.userAgent;
|
|
1851
|
-
|
|
1852
|
-
if (/Windows/i.test(ua)) {
|
|
1853
|
-
return (/Phone/.test(ua) || /WPDesktop/.test(ua)) ? 'Windows Phone' : 'Windows'; // no i18n
|
|
1854
|
-
}
|
|
1855
|
-
if (/(iPhone|iPad|iPod)/.test(ua)) {
|
|
1856
|
-
return 'iOS'; // no i18n
|
|
1857
|
-
}
|
|
1858
|
-
if (/Android/.test(ua)) {
|
|
1859
|
-
return 'Android'; // no i18n
|
|
1860
|
-
}
|
|
1861
|
-
if (/(BlackBerry|PlayBook|BB10)/i.test(ua)) {
|
|
1862
|
-
return 'BlackBerry'; // no i18n
|
|
1863
|
-
}
|
|
1864
|
-
if (/Mac/i.test(ua)) {
|
|
1865
|
-
return 'Mac OS X'; // no i18n
|
|
1866
|
-
}
|
|
1867
|
-
if (/Linux/.test(ua)) {
|
|
1868
|
-
return 'Linux'; // no i18n
|
|
1869
|
-
}
|
|
1870
|
-
if (/CrOS/.test(ua)) {
|
|
1871
|
-
return 'Chrome OS'; // no i18n
|
|
1872
|
-
}
|
|
1873
|
-
return '';
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
/**
|
|
1877
|
-
* This function detects which browser is running this script.
|
|
1878
|
-
* The order of the checks are important since many user agents
|
|
1879
|
-
* include key words used in later checks.
|
|
1880
|
-
* @returns {string} browser name
|
|
1881
|
-
*/
|
|
1882
|
-
function getBrowser() {
|
|
1883
|
-
|
|
1884
|
-
var ua = navigator.userAgent;
|
|
1885
|
-
var vendor = navigator.vendor || ''; // vendor is undefined for at least IE9
|
|
1886
|
-
var opera = window.opera;
|
|
1887
|
-
|
|
1888
|
-
if (opera || includes(ua, ' OPR/')) { // no i18n
|
|
1889
|
-
return (includes(ua, 'Mini')) ? 'Opera Mini' : 'Opera'; // no i18n
|
|
1890
|
-
}
|
|
1891
|
-
if (/(BlackBerry|PlayBook|BB10)/i.test(ua)) {
|
|
1892
|
-
return 'BlackBerry'; // no i18n
|
|
1893
|
-
}
|
|
1894
|
-
if (includes(ua, 'IEMobile') || includes(ua, 'WPDesktop')) { // no i18n
|
|
1895
|
-
return 'Internet Explorer Mobile'; // no i18n
|
|
1896
|
-
}
|
|
1897
|
-
if (includes(ua, 'SamsungBrowser/')) { // no i18n
|
|
1898
|
-
return 'Samsung Internet'; // no i18n
|
|
1899
|
-
}
|
|
1900
|
-
if (includes(ua, 'Edge') || includes(ua, 'Edg/')) { // no i18n
|
|
1901
|
-
return 'Microsoft Edge'; // no i18n
|
|
1902
|
-
}
|
|
1903
|
-
if (includes(ua, 'FBIOS')) { // no i18n
|
|
1904
|
-
return 'Facebook Mobile'; // no i18n
|
|
1905
|
-
}
|
|
1906
|
-
if (includes(ua, 'Chrome')) { // no i18n
|
|
1907
|
-
if(typeof ulaa == 'object'){
|
|
1908
|
-
return 'Ulaa'; // no i18n
|
|
1909
|
-
}
|
|
1910
|
-
else if(window.navigator.brave != undefined && window.navigator.brave.isBrave.name == "isBrave"){
|
|
1911
|
-
return 'Brave'; // no i18n
|
|
1912
|
-
}
|
|
1913
|
-
else{
|
|
1914
|
-
return 'Chrome'; // no i18n
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
if (includes(ua, 'CriOS')) { // no i18n
|
|
1918
|
-
return 'Chrome iOS'; // no i18n
|
|
1919
|
-
}
|
|
1920
|
-
if (includes(ua, 'UCWEB') || includes(ua, 'UCBrowser')) { // no i18n
|
|
1921
|
-
return 'UC Browser'; // no i18n
|
|
1922
|
-
}
|
|
1923
|
-
if (includes(ua, 'FxiOS')) { // no i18n
|
|
1924
|
-
return 'Firefox iOS'; // no i18n
|
|
1925
|
-
}
|
|
1926
|
-
if (includes(vendor, 'Apple')) { // no i18n
|
|
1927
|
-
return (includes(ua, 'Mobile')) ? 'Mobile Safari' : 'Safari'; // no i18n
|
|
1928
|
-
}
|
|
1929
|
-
if (includes(ua, 'Android')) { // no i18n
|
|
1930
|
-
return 'Android Mobile'; // no i18n
|
|
1931
|
-
}
|
|
1932
|
-
if (includes(ua, 'Konqueror')) { // no i18n
|
|
1933
|
-
return 'Konqueror'; // no i18n
|
|
1934
|
-
}
|
|
1935
|
-
if (includes(ua, 'Firefox')) { // no i18n
|
|
1936
|
-
return 'Firefox'; // no i18n
|
|
1937
|
-
}
|
|
1938
|
-
if (includes(ua, 'MSIE') || includes(ua, 'Trident/')) { // no i18n
|
|
1939
|
-
return 'Internet Explorer'; // no i18n
|
|
1940
|
-
}
|
|
1941
|
-
if (includes(ua, 'Gecko')) { // no i18n
|
|
1942
|
-
return 'Mozilla'; // no i18n
|
|
1943
|
-
}
|
|
1944
|
-
return '';
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
/**
|
|
1948
|
-
* This function detects which browser version is running this script,
|
|
1949
|
-
* parsing major and minor version (e.g., 42.1). User agent strings from:
|
|
1950
|
-
* http://www.useragentstring.com/pages/useragentstring.php
|
|
1951
|
-
* @returns {number} browser version
|
|
1952
|
-
*/
|
|
1953
|
-
function getBrowserVersion() {
|
|
1954
|
-
|
|
1955
|
-
var browser = getBrowser();
|
|
1956
|
-
var ua = navigator.userAgent;
|
|
1957
|
-
|
|
1958
|
-
var versionRegexs = {
|
|
1959
|
-
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/, // no i18n
|
|
1960
|
-
'Microsoft Edge': /Edg\/(\d+(\.\d+)?)/, // no i18n
|
|
1961
|
-
'Chrome': /Chrome\/(\d+(\.\d+)?)/,
|
|
1962
|
-
'Brave': /Chrome\/(\d+(\.\d+)?)/,
|
|
1963
|
-
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/, // no i18n
|
|
1964
|
-
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/, // no i18n
|
|
1965
|
-
'Safari': /Version\/(\d+(\.\d+)?)/,
|
|
1966
|
-
'Mobile Safari': /Version\/(\d+(\.\d+)?)/, // no i18n
|
|
1967
|
-
'Opera': /(Opera|OPR)\/(\d+(\.\d+)?)/,
|
|
1968
|
-
'Firefox': /Firefox\/(\d+(\.\d+)?)/,
|
|
1969
|
-
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/, // no i18n
|
|
1970
|
-
'Konqueror': /Konqueror:(\d+(\.\d+)?)/,
|
|
1971
|
-
'BlackBerry': /BlackBerry (\d+(\.\d+)?)/,
|
|
1972
|
-
'Android Mobile': /android\s(\d+(\.\d+)?)/, // no i18n
|
|
1973
|
-
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/, // no i18n
|
|
1974
|
-
'Mozilla': /rv:(\d+(\.\d+)?)/
|
|
1975
|
-
};
|
|
1976
|
-
// Check for Ulaa browser version
|
|
1977
|
-
if (browser === 'Ulaa' && typeof ulaa === 'object') {
|
|
1978
|
-
return ulaa.getVersion();
|
|
1979
|
-
}
|
|
1980
|
-
|
|
1981
|
-
var regex = versionRegexs[browser];
|
|
1982
|
-
if (regex === undefined) {
|
|
1983
|
-
return '';
|
|
1984
|
-
}
|
|
1985
|
-
var matches = ua.match(regex);
|
|
1986
|
-
if (!matches) {
|
|
1987
|
-
return '';
|
|
1988
|
-
}
|
|
1989
|
-
return parseFloat(matches[matches.length - 2]);
|
|
1990
|
-
}
|
|
1991
|
-
|
|
1992
|
-
/**
|
|
1993
|
-
* Gets the referring domain
|
|
1994
|
-
* @returns {string} domain or empty string
|
|
1995
|
-
*/
|
|
1996
|
-
function getReferringURL() {
|
|
1997
|
-
var split = String(window.location.href || '').split(window.location.pathname);
|
|
1998
|
-
if(split.length >= 2){
|
|
1999
|
-
return split[1].length > 500 ? split[1].substring(0,500) : split[1];
|
|
2000
|
-
}
|
|
2001
|
-
return '';
|
|
2002
|
-
}
|
|
2003
|
-
|
|
2004
|
-
/**
|
|
2005
|
-
* Checks if a value exists within a string
|
|
2006
|
-
* @param {string} str - value to search
|
|
2007
|
-
* @param {string} needle - value to find
|
|
2008
|
-
* @returns {boolean} true if found, otherwise false
|
|
2009
|
-
*/
|
|
2010
|
-
function includes(str, needle) {
|
|
2011
|
-
return str.indexOf(needle) !== -1;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
/**
|
|
2015
|
-
* @param {*=} obj
|
|
2016
|
-
* @param {function(...*)=} iterator
|
|
2017
|
-
* @param {Object=} context
|
|
2018
|
-
*/
|
|
2019
|
-
function each(obj, iterator, context) {
|
|
2020
|
-
if (obj === null || obj === undefined) {
|
|
2021
|
-
return;
|
|
2022
|
-
}
|
|
2023
|
-
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
|
|
2024
|
-
obj.forEach(iterator, context);
|
|
2025
|
-
}
|
|
2026
|
-
else if (obj.length === +obj.length) {
|
|
2027
|
-
for (var i = 0, l = obj.length; i < l; i++) {
|
|
2028
|
-
if (i in obj && iterator.call(context, obj[i], i, obj) === _breaker) {
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
2033
|
-
else {
|
|
2034
|
-
for (var key in obj) {
|
|
2035
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
2036
|
-
if (iterator.call(context, obj[key], key, obj) === _breaker) {
|
|
2037
|
-
return;
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
};
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
/**
|
|
2046
|
-
* Executes a HTTP GET request within a promise
|
|
2047
|
-
* @param {string} url - url to get
|
|
2048
|
-
* @returns {Promise} executes .then if successful otherwise .catch
|
|
2049
|
-
*/
|
|
2050
|
-
function httpGet(url) {
|
|
2051
|
-
|
|
2052
|
-
return new Promise(function (resolve, reject) {
|
|
2053
|
-
|
|
2054
|
-
var xhr = new XMLHttpRequest();
|
|
2055
|
-
|
|
2056
|
-
xhr.open('GET', url); // no i18n
|
|
2057
|
-
xhr.withCredentials = false;
|
|
2058
|
-
xhr.onreadystatechange = function () {
|
|
2059
|
-
if (xhr.readyState === 4) {
|
|
2060
|
-
if (xhr.status === 200) {
|
|
2061
|
-
resolve({
|
|
2062
|
-
url: url,
|
|
2063
|
-
status: 200,
|
|
2064
|
-
body: xhr.responseText || ''
|
|
2065
|
-
});
|
|
2066
|
-
}
|
|
2067
|
-
else {
|
|
2068
|
-
reject({
|
|
2069
|
-
url: url,
|
|
2070
|
-
status: xhr.status,
|
|
2071
|
-
body: xhr.responseText || ''
|
|
2072
|
-
});
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
};
|
|
2076
|
-
|
|
2077
|
-
xhr.send();
|
|
2078
|
-
});
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
|
-
/**
|
|
2082
|
-
* Generates a new distinct_id (code lifted from apptics js)
|
|
2083
|
-
* @returns {string} new UUID (example 16ee796360f641-0900a3aecd5282-3963720f-13c680-16ee7963610a3a)
|
|
2084
|
-
*/
|
|
2085
|
-
function getNewUUID() {
|
|
2086
|
-
|
|
2087
|
-
// Time/ticks information
|
|
2088
|
-
// 1*new Date() is a cross browser version of Date.now()
|
|
2089
|
-
var T = function () {
|
|
2090
|
-
var d = 1 * new Date(),
|
|
2091
|
-
i = 0;
|
|
2092
|
-
|
|
2093
|
-
// this while loop figures how many browser ticks go by
|
|
2094
|
-
// before 1*new Date() returns a new number, ie the amount
|
|
2095
|
-
// of ticks that go by per millisecond
|
|
2096
|
-
while (d == 1 * new Date()) {
|
|
2097
|
-
i++;
|
|
2098
|
-
}
|
|
2099
|
-
|
|
2100
|
-
return d.toString(16) + i.toString(16);
|
|
2101
|
-
};
|
|
2102
|
-
|
|
2103
|
-
// Math.Random entropy
|
|
2104
|
-
var R = function () {
|
|
2105
|
-
return Math.random().toString(16).replace('.', '');
|
|
2106
|
-
};
|
|
2107
|
-
|
|
2108
|
-
// User agent entropy
|
|
2109
|
-
// This function takes the user agent string, and then xors
|
|
2110
|
-
// together each sequence of 8 bytes. This produces a final
|
|
2111
|
-
// sequence of 8 bytes which it returns as hex.
|
|
2112
|
-
var UA = function () {
|
|
2113
|
-
var ua = navigator.userAgent,
|
|
2114
|
-
i, ch, buffer = [],
|
|
2115
|
-
ret = 0;
|
|
2116
|
-
|
|
2117
|
-
function xor(result, byte_array) {
|
|
2118
|
-
var j, tmp = 0;
|
|
2119
|
-
for (j = 0; j < byte_array.length; j++) {
|
|
2120
|
-
tmp |= (buffer[j] << j * 8);
|
|
2121
|
-
}
|
|
2122
|
-
return result ^ tmp;
|
|
2123
|
-
}
|
|
2124
|
-
|
|
2125
|
-
for (i = 0; i < ua.length; i++) {
|
|
2126
|
-
ch = ua.charCodeAt(i);
|
|
2127
|
-
buffer.unshift(ch & 0xFF);
|
|
2128
|
-
if (buffer.length >= 4) {
|
|
2129
|
-
ret = xor(ret, buffer);
|
|
2130
|
-
buffer = [];
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
|
|
2134
|
-
if (buffer.length > 0) {
|
|
2135
|
-
ret = xor(ret, buffer);
|
|
2136
|
-
}
|
|
2137
|
-
|
|
2138
|
-
return ret.toString(16);
|
|
2139
|
-
};
|
|
2140
|
-
|
|
2141
|
-
var se = (screen.height * screen.width).toString(16);
|
|
2142
|
-
return (T() + '-' + R() + '-' + UA() + '-' + se + '-' + T());
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
/**
|
|
2146
|
-
* Base 64 encodes a string using btoa
|
|
2147
|
-
* @param {string} str - string to encode
|
|
2148
|
-
* @returns {string} containing padded base64 value
|
|
2149
|
-
*/
|
|
2150
|
-
function base64Encode(str) {
|
|
2151
|
-
return window.btoa(unescape(encodeURIComponent(str)));
|
|
2152
|
-
}
|
|
2153
|
-
|
|
2154
|
-
function getTimeZone(){
|
|
2155
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
2156
|
-
}
|
|
2157
|
-
|
|
2158
|
-
function getKeyFromDeviceInfo(key){
|
|
2159
|
-
var returnVal = null; // no i18n
|
|
2160
|
-
var current_device_info = user_defaults.item('device_info'); // no i18n
|
|
2161
|
-
if(!isEmpty(current_device_info) && !isEmpty(current_device_info[key])){
|
|
2162
|
-
returnVal = current_device_info[key];
|
|
2163
|
-
}
|
|
2164
|
-
return returnVal;
|
|
2165
|
-
}
|
|
2166
|
-
|
|
2167
|
-
function calculateLocalStorageSize() {
|
|
2168
|
-
var totalSize = 0;
|
|
2169
|
-
|
|
2170
|
-
for (var i = 0; i < localStorage.length; i++) {
|
|
2171
|
-
var key = localStorage.key(i);
|
|
2172
|
-
var value = localStorage.getItem(key);
|
|
2173
|
-
;
|
|
2174
|
-
totalSize += sizeof(key) + sizeof(value);
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
// Convert to KB or MB for better readability
|
|
2178
|
-
var totalSizeKB = totalSize / 1024;
|
|
2179
|
-
var totalSizeMB = totalSizeKB / 1024;
|
|
2180
|
-
|
|
2181
|
-
return {
|
|
2182
|
-
totalSize: totalSize, // Total size in bytes
|
|
2183
|
-
totalSizeKB: totalSizeKB.toFixed(2) + ' KB', // no i18n
|
|
2184
|
-
totalSizeMB: totalSizeMB.toFixed(2) + ' MB' // no i18n
|
|
2185
|
-
};
|
|
2186
|
-
}
|
|
2187
|
-
|
|
2188
|
-
/* #endregion */
|
|
2189
|
-
|
|
2190
|
-
// no operation interface, exposes method that do nothing
|
|
2191
|
-
var mutedInterface = {
|
|
2192
|
-
trackEvent: function (eventName, groupName, data) {
|
|
2193
|
-
Console.log('apptics.trackEvent(\'' + eventName + '\',\'' + groupName || _config.default_group_name + '\',' + JSON.stringify(data || {}) + ')'); // no i18n
|
|
2194
|
-
},
|
|
2195
|
-
trackScreen: function (screenName, data) {
|
|
2196
|
-
Console.log('apptics.trackScreen(\'' + screenName + '\',' + JSON.stringify(data || {}) + ')'); // no i18n
|
|
2197
|
-
},
|
|
2198
|
-
enableGlobalErrorHandler: function(status){
|
|
2199
|
-
Console.log('apptics.enableGlobalErrorHandler(\'' + status + ')'); // no i18n
|
|
2200
|
-
},
|
|
2201
|
-
trackError: function (error, data) {
|
|
2202
|
-
Console.log('apptics.trackError(\'' + error + '\',' + JSON.stringify(data || {}) + ')'); // no i18n
|
|
2203
|
-
},
|
|
2204
|
-
feedbackOpen: function () {
|
|
2205
|
-
Console.log('apptics.feedbackOpen()'); // no i18n
|
|
2206
|
-
},
|
|
2207
|
-
feedbackClose: function () {
|
|
2208
|
-
Console.log('apptics.feedbackClose()'); // no i18n
|
|
2209
|
-
},
|
|
2210
|
-
sendFeedback: function(){
|
|
2211
|
-
Console.log('apptics.sendFeedback()'); // no i18n
|
|
2212
|
-
},
|
|
2213
|
-
setUser: function (userid, groupid, data) {
|
|
2214
|
-
Console.log('apptics.setUser(\'' + userid + '\',\'' + groupid + '\',' + JSON.stringify(data || {}) + ')'); // no i18n
|
|
2215
|
-
},
|
|
2216
|
-
getTrackingStatus: function () {
|
|
2217
|
-
Console.log('apptics.getTrackingStatus()'); // no i18n
|
|
2218
|
-
},
|
|
2219
|
-
setTrackingStatus: function (trackingid) {
|
|
2220
|
-
Console.log('apptics.setTrackingStatus(\'' + trackingid + '\')'); // no i18n
|
|
2221
|
-
},
|
|
2222
|
-
flush: function() {
|
|
2223
|
-
Console.log('apptics.flush()'); // no i18n
|
|
2224
|
-
},
|
|
2225
|
-
reset: function () {
|
|
2226
|
-
Console.log('apptics.reset()'); // no i18n
|
|
2227
|
-
},
|
|
2228
|
-
mute: mute,
|
|
2229
|
-
unmute: unmute,
|
|
2230
|
-
muted: true,
|
|
2231
|
-
AP_TRACKING_STATUS,
|
|
2232
|
-
AP_FEEDBACK_TYPE
|
|
2233
|
-
};
|
|
2234
|
-
|
|
2235
|
-
// operational interface, exposes methods that talk to apptics
|
|
2236
|
-
var unmutedInterface = {
|
|
2237
|
-
trackEvent: trackEvent,
|
|
2238
|
-
trackScreen: trackScreen,
|
|
2239
|
-
enableGlobalErrorHandler: enableGlobalErrorHandler,
|
|
2240
|
-
trackError: trackError,
|
|
2241
|
-
feedbackOpen: feedbackOpen,
|
|
2242
|
-
feedbackClose: feedbackClose,
|
|
2243
|
-
sendFeedback: sendFeedback,
|
|
2244
|
-
setUser: setUser,
|
|
2245
|
-
setTrackingStatus: setTrackingStatus,
|
|
2246
|
-
getTrackingStatus: getTrackingStatus,
|
|
2247
|
-
flush: flush,
|
|
2248
|
-
reset: reset,
|
|
2249
|
-
clear: clear,
|
|
2250
|
-
AP_TRACKING_STATUS,
|
|
2251
|
-
AP_FEEDBACK_TYPE
|
|
2252
|
-
};
|
|
2253
|
-
/**
|
|
2254
|
-
* Mutes apptics by overriding public methods with empty functions
|
|
2255
|
-
* @returns {void}
|
|
2256
|
-
*/
|
|
2257
|
-
function mute() {
|
|
2258
|
-
_config.verbose = false;
|
|
2259
|
-
apptics.muted = true;
|
|
2260
|
-
}
|
|
2261
|
-
|
|
2262
|
-
/**
|
|
2263
|
-
* Restores apptics function after a call to apptics.mute allowing data to be sent to apptics
|
|
2264
|
-
* @returns {void}
|
|
2265
|
-
*/
|
|
2266
|
-
function unmute() {
|
|
2267
|
-
_config.verbose = true;
|
|
2268
|
-
apptics.muted = false;
|
|
2269
|
-
}
|
|
2270
|
-
// expose apptics methods by default
|
|
2271
|
-
window.apptics = unmutedInterface;
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
_defaultoptions = window.appticssettings._defaultoptions;
|
|
2275
|
-
_token = window.appticssettings._defaultoptions.aaID;
|
|
2276
|
-
if(!isEmpty(_token) && !isEmpty(_defaultoptions)){
|
|
2277
|
-
init(_token, _defaultoptions);
|
|
2278
|
-
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
/**
|
|
2282
|
-
* Sets up in memory properties to be sent with each request
|
|
2283
|
-
* @param {string} token - apptics token
|
|
2284
|
-
* @param {object} opts - options { debug: true }
|
|
2285
|
-
* @returns {void}
|
|
2286
|
-
*/
|
|
2287
|
-
function init(token, opts) {
|
|
2288
|
-
opts = opts || {};
|
|
2289
|
-
|
|
2290
|
-
_config = AP_CONFIG;
|
|
2291
|
-
|
|
2292
|
-
each(opts, function( value, key ) {
|
|
2293
|
-
if (_config.hasOwnProperty(key)){
|
|
2294
|
-
if (!AP_RESERVED_CONFIG.includes(key)){
|
|
2295
|
-
_config[key]=value;
|
|
2296
|
-
}
|
|
2297
|
-
else{
|
|
2298
|
-
Console.warn('apptics.init: Reserved key \''+key+'\' cannot be overridden'); // no i18n
|
|
2299
|
-
}
|
|
2300
|
-
}
|
|
2301
|
-
else{
|
|
2302
|
-
Console.warn('apptics.init: unsupported key \''+key+'\''); // no i18n
|
|
2303
|
-
}
|
|
2304
|
-
});
|
|
2305
|
-
|
|
2306
|
-
if (token && token !== '') {
|
|
2307
|
-
_token = token;
|
|
2308
|
-
_frameworkID = _defaultoptions.base_domain.includes('local') ? _fwid_local : _frameworkID;
|
|
2309
|
-
//check if localstorage _token is empty or fw_id is empty
|
|
2310
|
-
var stored_token = user_defaults.item('token'); // no i18n
|
|
2311
|
-
var stored_fwid = user_defaults.item('fw_id'); // no i18n
|
|
2312
|
-
if (isEmpty(stored_token) || isEmpty(stored_fwid)){
|
|
2313
|
-
user_defaults.add('token', _token); // no i18n
|
|
2314
|
-
user_defaults.add('fw_id', _frameworkID); // no i18n
|
|
2315
|
-
stored_token = user_defaults.item('token'); // no i18n
|
|
2316
|
-
stored_fwid = user_defaults.item('fw_id'); // no i18n
|
|
2317
|
-
}
|
|
2318
|
-
if(stored_token != _token || stored_fwid != _frameworkID){
|
|
2319
|
-
reset();
|
|
2320
|
-
return;
|
|
2321
|
-
}
|
|
2322
|
-
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
if (opts.token && opts.token !== '') {
|
|
2326
|
-
_zak = opts.token;
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
|
-
if (opts.zsoid && opts.zsoid !== '') {
|
|
2330
|
-
_zsoid = opts.zsoid;
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
if (opts.projectID && opts.projectID !== '') {
|
|
2334
|
-
_projectID = opts.projectID;
|
|
2335
|
-
}
|
|
2336
|
-
|
|
2337
|
-
if (opts.identifier && opts.identifier !== '') {
|
|
2338
|
-
_identifier = opts.identifier;
|
|
2339
|
-
}
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
if (opts.base_domain && opts.base_domain !== '') {
|
|
2343
|
-
_base_domain = opts.base_domain;
|
|
2344
|
-
}
|
|
2345
|
-
|
|
2346
|
-
if (_token === '') {
|
|
2347
|
-
Console.warn('apptics.init: invalid token'); // no i18n
|
|
2348
|
-
return;
|
|
2349
|
-
}
|
|
2350
|
-
|
|
2351
|
-
_isanonrequired = true;
|
|
2352
|
-
_ignoreDnt = _config.ignore_do_not_track;
|
|
2353
|
-
|
|
2354
|
-
_devicestatus = _config.default_optin_status;
|
|
2355
|
-
tracking_preference.update_status(_devicestatus);
|
|
2356
|
-
|
|
2357
|
-
//check if uuid is empty
|
|
2358
|
-
var uuid = user_defaults.item('uuid'); // no i18n
|
|
2359
|
-
if (uuid == null || uuid == ''){
|
|
2360
|
-
uuid = getNewUUID();
|
|
2361
|
-
user_defaults.add('uuid',uuid); // no i18n
|
|
2362
|
-
}
|
|
2363
|
-
|
|
2364
|
-
_uuid = uuid;
|
|
2365
|
-
|
|
2366
|
-
checkAndUpdateDeviceInfo();
|
|
2367
|
-
|
|
2368
|
-
// attempt to resolve connection type
|
|
2369
|
-
_device_info.connectionType = getConnectionType();
|
|
2370
|
-
|
|
2371
|
-
// listen for connection change events (only available in w3c implementation)
|
|
2372
|
-
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
2373
|
-
|
|
2374
|
-
if (connection && connection.addEventListener) {
|
|
2375
|
-
// update connection when it changes
|
|
2376
|
-
connection.addEventListener('change', function () { // no i18n
|
|
2377
|
-
_device_info.connectionType = getConnectionType();
|
|
2378
|
-
});
|
|
2379
|
-
}
|
|
2380
|
-
_properties.orientation = getOrientation();
|
|
2381
|
-
|
|
2382
|
-
checkAndUpdateSession(); // need to check
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
window.appticsReadyStatus = true;
|
|
2387
|
-
if(typeof window.appticsReady == 'function'){
|
|
2388
|
-
window.appticsReady();
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
|
-
scheduleToSendDataToServer();
|
|
2392
|
-
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
|
-
function opt_in_tracking_without_pii(){
|
|
2396
|
-
let should_update = false;
|
|
2397
|
-
if (tracking_preference.opt_in_status() != AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII){
|
|
2398
|
-
should_update = true;
|
|
2399
|
-
}
|
|
2400
|
-
tracking_preference.opt_in_tracking_without_pii();
|
|
2401
|
-
if (should_update){
|
|
2402
|
-
// update device info
|
|
2403
|
-
_devicestatus = tracking_preference.opt_in_status();
|
|
2404
|
-
updateDeviceWithApptics(_device_info);
|
|
2405
|
-
}
|
|
2406
|
-
}
|
|
2407
|
-
|
|
2408
|
-
function opt_in_tracking_with_pii(){
|
|
2409
|
-
let should_update = false;
|
|
2410
|
-
if (tracking_preference.opt_in_status() != AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII){
|
|
2411
|
-
should_update = true;
|
|
2412
|
-
}
|
|
2413
|
-
tracking_preference.opt_in_tracking_with_pii();
|
|
2414
|
-
if (should_update){
|
|
2415
|
-
// update device info
|
|
2416
|
-
_devicestatus = tracking_preference.opt_in_status();
|
|
2417
|
-
updateDeviceWithApptics(_device_info);
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
|
|
2421
|
-
function opt_out_tracking(){
|
|
2422
|
-
let should_update = false;
|
|
2423
|
-
if (tracking_preference.opt_in_status() != AP_TRACKING_STATUS.NO_TRACKING){
|
|
2424
|
-
should_update = true;
|
|
2425
|
-
}
|
|
2426
|
-
tracking_preference.opt_out_tracking();
|
|
2427
|
-
if (should_update){
|
|
2428
|
-
// update device info
|
|
2429
|
-
_devicestatus = tracking_preference.opt_in_status();
|
|
2430
|
-
updateDeviceWithApptics(_device_info);
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
|
|
2434
|
-
function opt_in_status(){
|
|
2435
|
-
if (hasDoNotTrackEnabled()){
|
|
2436
|
-
Console.warn('opt_in_status: It seems "Do Not Track" is enabled in this browser. To ignore the "Do Not Track" browser setting, init Apptics with the config "ignore_do_not_track: true"'); // no i18n
|
|
2437
|
-
return AP_TRACKING_STATUS.NO_TRACKING;
|
|
2438
|
-
}
|
|
2439
|
-
var opt_in_status = tracking_preference.opt_in_status();
|
|
2440
|
-
if (opt_in_status == -1){
|
|
2441
|
-
Console.warn('opt_in_status: You are opted out of Apptics tracking. This will prevent the our SDK from sending no data to our server.'); // no i18n
|
|
2442
|
-
}
|
|
2443
|
-
return opt_in_status;
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
function shouldTrackOrSendData(){
|
|
2447
|
-
var optInStatus = opt_in_status();
|
|
2448
|
-
return (optInStatus > -1);
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
function clear_opt_in_status(){
|
|
2452
|
-
tracking_preference.clear();
|
|
2453
|
-
}
|
|
2454
|
-
|
|
2455
|
-
function setTrackingStatus(trackingState){
|
|
2456
|
-
if(isEmpty(trackingState)){
|
|
2457
|
-
Console.log('setTrackingStatus: trackingStatus is Empty'); // no i18n
|
|
2458
|
-
return;
|
|
2459
|
-
}
|
|
2460
|
-
|
|
2461
|
-
let should_update = false;
|
|
2462
|
-
if (tracking_preference.opt_in_status() != trackingState){
|
|
2463
|
-
should_update = true;
|
|
2464
|
-
}
|
|
2465
|
-
if (should_update){
|
|
2466
|
-
tracking_preference.update_status(trackingState);
|
|
2467
|
-
_devicestatus = tracking_preference.opt_in_status();
|
|
2468
|
-
_isanonrequired = tracking_preference.opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII ? false : _isanonrequired;
|
|
2469
|
-
if(tracking_preference.opt_in_status() != AP_TRACKING_STATUS.NO_TRACKING){
|
|
2470
|
-
updateDeviceWithApptics(_device_info);
|
|
2471
|
-
}
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
|
|
2475
|
-
function getTrackingStatus(){
|
|
2476
|
-
return opt_in_status();
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
function scheduleToSendDataToServer(){
|
|
2480
|
-
// Set up periodic sending of events
|
|
2481
|
-
sendingInterval = setInterval((()=>{
|
|
2482
|
-
Console.log('scheduleToSendDataToServer: Scheduling to send engagement data to the server after sometime'); // no i18n
|
|
2483
|
-
sendEngagementData();
|
|
2484
|
-
sendErrorData();
|
|
2485
|
-
}), getConfig('batch_flush_interval')); // no i18n
|
|
2486
|
-
// Send events every 60 seconds (adjust as needed)
|
|
2487
|
-
}
|
|
2488
|
-
|
|
2489
|
-
// Function to stop periodic sending (if needed)
|
|
2490
|
-
function checkAndScheduleToSendData() {
|
|
2491
|
-
if (!_token) {
|
|
2492
|
-
Console.warn('checkAndScheduleToSendData: You must call apptics.init(token) first'); // no i18n
|
|
2493
|
-
return;
|
|
2494
|
-
}
|
|
2495
|
-
if (sendingInterval == null){
|
|
2496
|
-
//clearInterval(sendingInterval);
|
|
2497
|
-
scheduleToSendDataToServer();
|
|
2498
|
-
}
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
|
-
function isEmpty( val ){
|
|
2502
|
-
// Check if val is empty
|
|
2503
|
-
if( val === undefined || val === null || val === "" )
|
|
2504
|
-
{
|
|
2505
|
-
return true;
|
|
2506
|
-
}
|
|
2507
|
-
else
|
|
2508
|
-
{
|
|
2509
|
-
return false;
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
|
|
2513
|
-
function isEmptyObj(obj){
|
|
2514
|
-
return (
|
|
2515
|
-
obj &&
|
|
2516
|
-
Object.keys(obj).length === 0 &&
|
|
2517
|
-
obj.constructor === Object
|
|
2518
|
-
);
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2521
|
-
function compareTwoObjects(_newmap, _oldmap) {
|
|
2522
|
-
// Check if the number of keys is the same.
|
|
2523
|
-
if (Object.keys(_newmap).length !== Object.keys(_oldmap).length) {
|
|
2524
|
-
return false;
|
|
2525
|
-
}
|
|
2526
|
-
|
|
2527
|
-
// Check if keys are the same
|
|
2528
|
-
for (let key in _newmap) {
|
|
2529
|
-
if (!_oldmap.hasOwnProperty(key)) {
|
|
2530
|
-
return false;
|
|
2531
|
-
}
|
|
2532
|
-
}
|
|
2533
|
-
|
|
2534
|
-
// Check if objects associated with each key are the same
|
|
2535
|
-
for (let key in _newmap) {
|
|
2536
|
-
if (!objectsAreEqual(_newmap[key], _oldmap[key])) {
|
|
2537
|
-
return false;
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
|
|
2541
|
-
// Hash maps have the same keys and objects
|
|
2542
|
-
return true;
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
|
-
function objectsAreEqual(obj1, obj2) {
|
|
2546
|
-
// Compare the objects' properties
|
|
2547
|
-
return JSON.stringify(obj1) === JSON.stringify(obj2);
|
|
2548
|
-
}
|
|
2549
|
-
|
|
2550
|
-
function checkAndUpdateSession(){
|
|
2551
|
-
|
|
2552
|
-
if (!_token) {
|
|
2553
|
-
Console.warn('checkAndUpdateSession: You must call apptics.init(token) first'); // no i18n
|
|
2554
|
-
return;
|
|
2555
|
-
}
|
|
2556
|
-
|
|
2557
|
-
if (is_apptics_disabled()){
|
|
2558
|
-
return;
|
|
2559
|
-
}
|
|
2560
|
-
|
|
2561
|
-
if (!shouldTrackOrSendData()){
|
|
2562
|
-
return;
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
var time = Math.round((new Date()).getTime());
|
|
2566
|
-
var _currentSession = currentSession();
|
|
2567
|
-
if (_currentSession){
|
|
2568
|
-
// Check if the user is inactive for the past 30 minutes
|
|
2569
|
-
_current_session = _currentSession;
|
|
2570
|
-
if ((time - _currentSession.lastactivetime) > (inactiveduration * 1000 * 60)){
|
|
2571
|
-
Console.log('checkAndUpdateSession: User is inactive for the past '+inactiveduration+' minutes so starting a new session'); // no i18n
|
|
2572
|
-
var _oldSession = _currentSession;
|
|
2573
|
-
var _newSession = Object.assign({}, _oldSession)
|
|
2574
|
-
_newSession.endtime=time;
|
|
2575
|
-
var storage = calculateLocalStorageSize();
|
|
2576
|
-
//_newSession.endlocalstoragesize=storage.totalSizeKB; // need to check
|
|
2577
|
-
|
|
2578
|
-
if (_newSession) {
|
|
2579
|
-
Console.log('checkAndUpdateSession: (' + JSON.stringify(_newSession || {}) + ')'); // no i18n
|
|
2580
|
-
}
|
|
2581
|
-
Console.dir(_newSession);
|
|
2582
|
-
|
|
2583
|
-
engagement_transactions.update(_oldSession,_newSession);
|
|
2584
|
-
startNewSession(time);
|
|
2585
|
-
|
|
2586
|
-
}
|
|
2587
|
-
else{
|
|
2588
|
-
Console.log('checkAndUpdateSession: User is back before '+inactiveduration+' minutes so updating the lastactivitytime - ' + time); // no i18n
|
|
2589
|
-
var _oldSession = _currentSession;
|
|
2590
|
-
var _newSession = Object.assign({}, _oldSession)
|
|
2591
|
-
_newSession.lastactivetime=time;
|
|
2592
|
-
_current_session=_newSession;
|
|
2593
|
-
engagement_transactions.update(_oldSession,_newSession);
|
|
2594
|
-
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2597
|
-
else{
|
|
2598
|
-
startNewSession(time);
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
|
|
2602
|
-
function updateLastActiveTimeOfSession(){
|
|
2603
|
-
clearTimeout(timeoutId);
|
|
2604
|
-
var time = Math.round((new Date()).getTime());
|
|
2605
|
-
var _currentSession = currentSession();
|
|
2606
|
-
if (_currentSession){
|
|
2607
|
-
Console.log('updateLastActiveTimeOfSession: Updating the lastactivitytime - ' + time); // no i18n
|
|
2608
|
-
var _oldSession = _currentSession;
|
|
2609
|
-
var _newSession = Object.assign({}, _oldSession)
|
|
2610
|
-
_newSession.lastactivetime=time;
|
|
2611
|
-
_current_session=_newSession;
|
|
2612
|
-
engagement_transactions.update(_oldSession,_newSession);
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
|
|
2616
|
-
// Schedule the method to execute after 3 seconds
|
|
2617
|
-
function scheduleToCheckAndUpdateSession() {
|
|
2618
|
-
|
|
2619
|
-
if (!_token) {
|
|
2620
|
-
Console.warn('scheduleToCheckAndUpdateSession: You must call apptics.init(token) first'); // no i18n
|
|
2621
|
-
return;
|
|
2622
|
-
}
|
|
2623
|
-
|
|
2624
|
-
if (is_apptics_disabled()){
|
|
2625
|
-
return;
|
|
2626
|
-
}
|
|
2627
|
-
|
|
2628
|
-
if (!shouldTrackOrSendData()){
|
|
2629
|
-
return;
|
|
2630
|
-
}
|
|
2631
|
-
|
|
2632
|
-
// Clear any previously scheduled executions
|
|
2633
|
-
clearTimeout(timeoutId);
|
|
2634
|
-
|
|
2635
|
-
// Schedule the method to execute after 3 seconds
|
|
2636
|
-
timeoutId = setTimeout(checkAndUpdateSession, 10);
|
|
2637
|
-
}
|
|
2638
|
-
|
|
2639
|
-
function cloneMapExcludingKeys(originalObj, excludeKeys) {
|
|
2640
|
-
const clonedObj = {};
|
|
2641
|
-
for (let key in originalObj) {
|
|
2642
|
-
if (!excludeKeys.includes(key)) {
|
|
2643
|
-
clonedObj[key] = originalObj[key];
|
|
2644
|
-
}
|
|
2645
|
-
}
|
|
2646
|
-
return clonedObj;
|
|
2647
|
-
}
|
|
2648
|
-
|
|
2649
|
-
function getMetaObj(){
|
|
2650
|
-
var returnObj = {
|
|
2651
|
-
frameworkid: getKeyFromDeviceInfo('frameworkid'), // no i18n
|
|
2652
|
-
aaid: getKeyFromDeviceInfo('aaid'), // no i18n
|
|
2653
|
-
apid: getKeyFromDeviceInfo('apid'), // no i18n
|
|
2654
|
-
appversionid: getKeyFromDeviceInfo('appversionid'), // no i18n
|
|
2655
|
-
osversionid: getKeyFromDeviceInfo('osversionid'), // no i18n
|
|
2656
|
-
timezoneid: getKeyFromDeviceInfo('timezoneid'), // no i18n
|
|
2657
|
-
platformid: getKeyFromDeviceInfo('platformid'), // no i18n
|
|
2658
|
-
devicetypeid: getKeyFromDeviceInfo('devicetypeid') // no i18n
|
|
2659
|
-
}
|
|
2660
|
-
return returnObj;
|
|
2661
|
-
}
|
|
2662
|
-
|
|
2663
|
-
function checkAndUpdateDeviceInfo(){
|
|
2664
|
-
// params -> https://help.apptics.com/hc/en-us/articles/115004613766-Default-Properties-Collected-by-apptics
|
|
2665
|
-
_device_info = {
|
|
2666
|
-
osversion: getOS(),
|
|
2667
|
-
browser: getBrowser(),
|
|
2668
|
-
browserversion: String(getBrowserVersion()),
|
|
2669
|
-
donottrackenabled: hasDoNotTrackEnabled() ? 1 : 0, // no i18n
|
|
2670
|
-
devicetype: getDevice(),
|
|
2671
|
-
screenheight: screen.height,
|
|
2672
|
-
screenwidth: screen.width,
|
|
2673
|
-
referrer: getReferringURL(),
|
|
2674
|
-
connectionType: getConnectionType(),
|
|
2675
|
-
referringdomain: window.location.hostname || '', // no i18n
|
|
2676
|
-
deviceid: getKeyFromDeviceInfo('deviceid'), // no i18n
|
|
2677
|
-
anonymousid: getKeyFromDeviceInfo('anonymousid'), // no i18n
|
|
2678
|
-
frameworkid: getKeyFromDeviceInfo('frameworkid'), // no i18n
|
|
2679
|
-
mapid: getKeyFromDeviceInfo('mapid'), // no i18n
|
|
2680
|
-
aaid: getKeyFromDeviceInfo('aaid'), // no i18n
|
|
2681
|
-
apid: getKeyFromDeviceInfo('apid'), // no i18n
|
|
2682
|
-
appversionid: getKeyFromDeviceInfo('appversionid'), // no i18n
|
|
2683
|
-
platformid: getKeyFromDeviceInfo('platformid'), // no i18n
|
|
2684
|
-
devicetypeid: getKeyFromDeviceInfo('devicetypeid'), // no i18n
|
|
2685
|
-
osversionid: getKeyFromDeviceInfo('osversionid'), // no i18n
|
|
2686
|
-
timezoneid: getKeyFromDeviceInfo('timezoneid'), // no i18n
|
|
2687
|
-
timezone:getTimeZone()
|
|
2688
|
-
};
|
|
2689
|
-
|
|
2690
|
-
user_defaults.add('device_info', _device_info); // no i18n
|
|
2691
|
-
|
|
2692
|
-
addOrUpdateDeviceID(_device_info);
|
|
2693
|
-
|
|
2694
|
-
}
|
|
2695
|
-
|
|
2696
|
-
//
|
|
2697
|
-
function addOrUpdateDeviceID(_device_info){
|
|
2698
|
-
var _old_device_info = user_defaults.item('device_info'); // no i18n
|
|
2699
|
-
_frameworkID = _defaultoptions.base_domain.includes('local') ? _fwid_local : _frameworkID;
|
|
2700
|
-
// Compare the old and new device infos and update the server if anything changed in the new.
|
|
2701
|
-
if (_device_info.deviceid == null || _device_info.frameworkid == null || _device_info.anonymousid == null){
|
|
2702
|
-
_device_info.frameworkid = _frameworkID;
|
|
2703
|
-
Console.log('addOrUpdateDeviceID: Register the device'); // no i18n
|
|
2704
|
-
registerDeviceWithApptics().then(function (result_device_info){
|
|
2705
|
-
Console.log('addOrUpdateDeviceID: ' + JSON.stringify(result_device_info.data)); // no i18n
|
|
2706
|
-
Console.dir(result_device_info.data);
|
|
2707
|
-
}).catch(function (err){
|
|
2708
|
-
Console.log(err);
|
|
2709
|
-
});
|
|
2710
|
-
}
|
|
2711
|
-
else if (!compareTwoObjects(_device_info, _old_device_info)){
|
|
2712
|
-
// Both the info are not the same, so update device info
|
|
2713
|
-
updateDeviceWithApptics(_device_info);
|
|
2714
|
-
Console.log('addOrUpdateDeviceID: Device info changed, so updating new changes'); // no i18n
|
|
2715
|
-
Console.dir(_device_info);
|
|
2716
|
-
}
|
|
2717
|
-
}
|
|
2718
|
-
|
|
2719
|
-
// Function to register the device
|
|
2720
|
-
function registerDeviceWithApptics() {
|
|
2721
|
-
if (is_apptics_disabled()){
|
|
2722
|
-
return;
|
|
2723
|
-
}
|
|
2724
|
-
|
|
2725
|
-
if (!_token) {
|
|
2726
|
-
Console.warn('registerDeviceWithApptics: You must call apptics.init(token) first'); // no i18n
|
|
2727
|
-
return new Promise((resolve, reject) => {
|
|
2728
|
-
reject('registerDeviceWithApptics: You must call apptics.init(token) first');
|
|
2729
|
-
});
|
|
2730
|
-
}
|
|
2731
|
-
|
|
2732
|
-
if (navigator.onLine == false){
|
|
2733
|
-
Console.warn('registerDeviceWithApptics: No Network'); // no i18n
|
|
2734
|
-
return new Promise((resolve, reject) => {
|
|
2735
|
-
reject('registerDeviceWithApptics: No Network');
|
|
2736
|
-
});
|
|
2737
|
-
}
|
|
2738
|
-
if (_device_info.deviceid && _device_info.anonymousid){
|
|
2739
|
-
return new Promise((resolve, reject) => {
|
|
2740
|
-
resolve(_device_info);
|
|
2741
|
-
});
|
|
2742
|
-
}
|
|
2743
|
-
else{
|
|
2744
|
-
// Perform device registration here (e.g., make an API call)
|
|
2745
|
-
return new Promise((resolve, reject) => {
|
|
2746
|
-
|
|
2747
|
-
if (_regDeviceSending == false){
|
|
2748
|
-
_regDeviceSending = true;
|
|
2749
|
-
let device_info = cloneMapExcludingKeys(_device_info, ['deviceid', 'anonymousid', 'aaid', 'apid', 'mapid', 'devicetypeid', 'osversionid', 'platformid', 'appversionid', 'timezoneid', 'connectionType']); // no i18n
|
|
2750
|
-
var payload = JSON.stringify(device_info);
|
|
2751
|
-
var headers = {zak:getHeaderParams('zak'), uuid:getHeaderParams('uuid')}; // no i18n
|
|
2752
|
-
|
|
2753
|
-
requestQueue.addRequest(getUrlWithParams('regdevice'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
2754
|
-
var _result = JSON.parse(response);
|
|
2755
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
2756
|
-
var data = _result.data;
|
|
2757
|
-
_device_info.anonymousid = data.anonymousid;
|
|
2758
|
-
_device_info.deviceid = data.deviceid;
|
|
2759
|
-
_device_info.aaid = data.aaid;
|
|
2760
|
-
_device_info.apid = data.apid;
|
|
2761
|
-
_device_info.mapid = data.mapid;
|
|
2762
|
-
|
|
2763
|
-
_apid = data.apid;
|
|
2764
|
-
_mapid = data.mapid;
|
|
2765
|
-
|
|
2766
|
-
_device_info.appversionid = data.appversionid;
|
|
2767
|
-
_device_info.osversionid = data.osversionid;
|
|
2768
|
-
_device_info.timezoneid = data.timezoneid;
|
|
2769
|
-
_device_info.platformid = data.platformid;
|
|
2770
|
-
_device_info.devicetypeid = data.devicetypeid;
|
|
2771
|
-
//need to write function to update device info
|
|
2772
|
-
|
|
2773
|
-
// Update the new device info into the localstorage
|
|
2774
|
-
user_defaults.add('device_info', _device_info); // no i18n
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
_regDeviceResolve.forEach(function (_resolve) {
|
|
2778
|
-
_resolve(_result);
|
|
2779
|
-
});
|
|
2780
|
-
resolve(_result);
|
|
2781
|
-
}
|
|
2782
|
-
else{
|
|
2783
|
-
_regDeviceReject.forEach(function (_reject) {
|
|
2784
|
-
_reject('registerDeviceWithApptics: '+ _result.result);
|
|
2785
|
-
});
|
|
2786
|
-
reject('registerDeviceWithApptics: '+ _result.result);
|
|
2787
|
-
}
|
|
2788
|
-
_regDeviceSending = false;
|
|
2789
|
-
}).catch(err => {
|
|
2790
|
-
_regDeviceReject.forEach(function (_reject) {
|
|
2791
|
-
_reject('registerDeviceWithApptics: '+ err);
|
|
2792
|
-
});
|
|
2793
|
-
reject('registerDeviceWithApptics: '+ err);
|
|
2794
|
-
_regDeviceSending = false;
|
|
2795
|
-
});
|
|
2796
|
-
}
|
|
2797
|
-
else{
|
|
2798
|
-
_regDeviceSending = false;
|
|
2799
|
-
_regDeviceResolve.push(resolve);
|
|
2800
|
-
_regDeviceReject.push(reject);
|
|
2801
|
-
}
|
|
2802
|
-
});
|
|
2803
|
-
}
|
|
2804
|
-
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
// Function to update the device
|
|
2808
|
-
function updateDeviceWithApptics(_device_info) {
|
|
2809
|
-
|
|
2810
|
-
if (is_apptics_disabled()){
|
|
2811
|
-
return;
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
|
-
if (navigator.onLine == false){
|
|
2815
|
-
Console.warn('updateDeviceWithApptics: No Network'); // no i18n
|
|
2816
|
-
return new Promise((resolve, reject) => {
|
|
2817
|
-
reject('updateDeviceWithApptics: No Network');
|
|
2818
|
-
});
|
|
2819
|
-
}
|
|
2820
|
-
|
|
2821
|
-
// Perform device registration here (e.g., make an API call)
|
|
2822
|
-
return new Promise((resolve, reject) => {
|
|
2823
|
-
|
|
2824
|
-
let device_info_exclude = cloneMapExcludingKeys(_device_info, ['deviceid', 'anonymousid', 'aaid', 'apid', 'mapid', 'appversionid', 'devicetypeid', 'osversionid', 'platformid', 'timezoneid', 'connectionType']); // no i18n
|
|
2825
|
-
var payload = JSON.stringify(device_info_exclude);
|
|
2826
|
-
var headers = {zak:getHeaderParams('zak'), uuid:getHeaderParams('uuid'), apid:getHeaderParams('apid'), mapid:getHeaderParams('mapid')}; // no i18n
|
|
2827
|
-
|
|
2828
|
-
requestQueue.addRequest(getUrlWithParams('regdevice'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
2829
|
-
var _result = JSON.parse(response);
|
|
2830
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
2831
|
-
var data = _result.data;
|
|
2832
|
-
_device_info.deviceid = data.deviceid;
|
|
2833
|
-
if(data.hasOwnProperty('anonymousid') && !isEmpty(data.anonymousid)){
|
|
2834
|
-
_device_info.anonymousid = data.anonymousid;
|
|
2835
|
-
}
|
|
2836
|
-
|
|
2837
|
-
_device_info.aaid = data.aaid;
|
|
2838
|
-
_device_info.apid = data.apid;
|
|
2839
|
-
_device_info.mapid = data.mapid;
|
|
2840
|
-
|
|
2841
|
-
_apid = data.apid;
|
|
2842
|
-
_mapid = data.mapid;
|
|
2843
|
-
|
|
2844
|
-
_device_info.appversionid = data.appversionid;
|
|
2845
|
-
_device_info.osversionid = data.osversionid;
|
|
2846
|
-
_device_info.timezoneid = data.timezoneid;
|
|
2847
|
-
_device_info.platformid = data.platformid;
|
|
2848
|
-
_device_info.devicetypeid = data.devicetypeid;
|
|
2849
|
-
|
|
2850
|
-
//need to write function to update device info
|
|
2851
|
-
|
|
2852
|
-
user_defaults.add('device_info', _device_info); // no i18n
|
|
2853
|
-
resolve(_device_info);
|
|
2854
|
-
}
|
|
2855
|
-
else{
|
|
2856
|
-
reject('updateDeviceWithApptics: '+ _result.result);
|
|
2857
|
-
}
|
|
2858
|
-
|
|
2859
|
-
}).catch(err => {
|
|
2860
|
-
reject('updateDeviceWithApptics: '+ err);
|
|
2861
|
-
});
|
|
2862
|
-
});
|
|
2863
|
-
}
|
|
2864
|
-
|
|
2865
|
-
// Function to register the device
|
|
2866
|
-
function registerUserWithApptics(user_info) {
|
|
2867
|
-
|
|
2868
|
-
if (is_apptics_disabled()){
|
|
2869
|
-
return;
|
|
2870
|
-
}
|
|
2871
|
-
|
|
2872
|
-
if (!shouldTrackOrSendData()){
|
|
2873
|
-
return;
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2876
|
-
if (navigator.onLine == false){
|
|
2877
|
-
Console.warn('registerUserWithApptics: No Network'); // no i18n
|
|
2878
|
-
return new Promise((resolve, reject) => {
|
|
2879
|
-
reject('registerUserWithApptics: No Network');
|
|
2880
|
-
});
|
|
2881
|
-
|
|
2882
|
-
}
|
|
2883
|
-
if(isEmptyObj(user_info)){
|
|
2884
|
-
return;
|
|
2885
|
-
}
|
|
2886
|
-
|
|
2887
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))){
|
|
2888
|
-
checkAndUpdateDeviceInfo();
|
|
2889
|
-
return new Promise((resolve, reject) => {
|
|
2890
|
-
reject('registerUserWithApptics: You must call apptics.init() first');
|
|
2891
|
-
});
|
|
2892
|
-
}
|
|
2893
|
-
|
|
2894
|
-
// Perform user registration here (e.g., make an API call)
|
|
2895
|
-
return new Promise((resolve, reject) => {
|
|
2896
|
-
|
|
2897
|
-
let payload_user_info = cloneMapExcludingKeys(user_info, ['userid', 'groupid', 'happendat']); // no i18n
|
|
2898
|
-
var payload = JSON.stringify(payload_user_info);
|
|
2899
|
-
|
|
2900
|
-
var headers = {apid:getHeaderParams('apid'), mapid:getHeaderParams('mapid')}; // no i18n
|
|
2901
|
-
|
|
2902
|
-
requestQueue.addRequest(getUrlWithParams('reguser'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
2903
|
-
var _result = JSON.parse(response);
|
|
2904
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
2905
|
-
var data = _result.data;
|
|
2906
|
-
|
|
2907
|
-
user_info.userid = data.userid;
|
|
2908
|
-
user_info.groupid = data.customergroupid;
|
|
2909
|
-
_user_info = user_info;
|
|
2910
|
-
setTrackingStatus(AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII);
|
|
2911
|
-
addOrUpdateUser(user_info);
|
|
2912
|
-
resolve(data);
|
|
2913
|
-
}
|
|
2914
|
-
else{
|
|
2915
|
-
reject('registerUserWithApptics: '+ _result.result);
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
}).catch(err => {
|
|
2919
|
-
reject('registerUserWithApptics: '+ err);
|
|
2920
|
-
});
|
|
2921
|
-
});
|
|
2922
|
-
|
|
2923
|
-
}
|
|
2924
|
-
|
|
2925
|
-
// Function to send engagement data to server
|
|
2926
|
-
function requestToSendEngagements(_payload) {
|
|
2927
|
-
if (is_apptics_disabled()){
|
|
2928
|
-
return;
|
|
2929
|
-
}
|
|
2930
|
-
|
|
2931
|
-
if (!shouldTrackOrSendData()){
|
|
2932
|
-
return;
|
|
2933
|
-
}
|
|
2934
|
-
|
|
2935
|
-
if (isEmptyObj(_payload)){
|
|
2936
|
-
return;
|
|
2937
|
-
}
|
|
2938
|
-
|
|
2939
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))){
|
|
2940
|
-
checkAndUpdateDeviceInfo();
|
|
2941
|
-
return new Promise((resolve, reject) => {
|
|
2942
|
-
reject('requestToSendEngagements: You must call apptics.init() first');
|
|
2943
|
-
});
|
|
2944
|
-
}
|
|
2945
|
-
|
|
2946
|
-
if(!_payload.hasOwnProperty('meta')){ // no i18n
|
|
2947
|
-
_payload.meta = getMetaObj();
|
|
2948
|
-
}
|
|
2949
|
-
|
|
2950
|
-
let dataSize = sizeof(_payload);
|
|
2951
|
-
Console.log('requestToSendEngagements: Engagement Payload size : ' + (dataSize / 1024)); // no i18n
|
|
2952
|
-
|
|
2953
|
-
return new Promise((resolve, reject) => {
|
|
2954
|
-
// Perform to send engagement data here (e.g., make an API call)
|
|
2955
|
-
var payload = JSON.stringify(_payload);
|
|
2956
|
-
var headers = {apid:getHeaderParams('apid'), mapid:getHeaderParams('mapid')}; // no i18n
|
|
2957
|
-
|
|
2958
|
-
requestQueue.addRequest(getUrlWithParams('engagement'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
2959
|
-
var _result = JSON.parse(response);
|
|
2960
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
2961
|
-
var data = _result;
|
|
2962
|
-
resolve(data);
|
|
2963
|
-
}
|
|
2964
|
-
else{
|
|
2965
|
-
reject('requestToSendEngagements: '+ _result.result);
|
|
2966
|
-
}
|
|
2967
|
-
|
|
2968
|
-
}).catch(err => {
|
|
2969
|
-
reject('requestToSendEngagements: '+ err);
|
|
2970
|
-
});
|
|
2971
|
-
});
|
|
2972
|
-
|
|
2973
|
-
}
|
|
2974
|
-
|
|
2975
|
-
// Function to send error data to server
|
|
2976
|
-
function requestToSendErrors(_payload) {
|
|
2977
|
-
if (is_apptics_disabled()){
|
|
2978
|
-
return;
|
|
2979
|
-
}
|
|
2980
|
-
|
|
2981
|
-
if (!shouldTrackOrSendData()){
|
|
2982
|
-
return;
|
|
2983
|
-
}
|
|
2984
|
-
|
|
2985
|
-
if (isEmptyObj(_payload)){
|
|
2986
|
-
return;
|
|
2987
|
-
}
|
|
2988
|
-
|
|
2989
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))){
|
|
2990
|
-
checkAndUpdateDeviceInfo();
|
|
2991
|
-
return new Promise((resolve, reject) => {
|
|
2992
|
-
reject('requestToSendErrors: You must call apptics.init() first');
|
|
2993
|
-
});
|
|
2994
|
-
}
|
|
2995
|
-
|
|
2996
|
-
if(!_payload.hasOwnProperty('meta')){ // no i18n
|
|
2997
|
-
_payload.meta = getMetaObj();
|
|
2998
|
-
}
|
|
2999
|
-
|
|
3000
|
-
let dataSize = sizeof(_payload);
|
|
3001
|
-
Console.log('requestToSendErrors: Error Payload size : ' + (dataSize / 1024)); // no i18n
|
|
3002
|
-
|
|
3003
|
-
return new Promise((resolve, reject) => {
|
|
3004
|
-
// Perform to send error data here (e.g., make an API call)
|
|
3005
|
-
var payload = JSON.stringify(_payload);
|
|
3006
|
-
var headers = {apid:getHeaderParams('apid'), mapid:getHeaderParams('mapid')}; // no i18n
|
|
3007
|
-
|
|
3008
|
-
requestQueue.addRequest(getUrlWithParams('error'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
3009
|
-
var _result = JSON.parse(response);
|
|
3010
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
3011
|
-
var data = _result;
|
|
3012
|
-
resolve(data);
|
|
3013
|
-
}
|
|
3014
|
-
else{
|
|
3015
|
-
reject('requestToSendErrors: '+ _result.result);
|
|
3016
|
-
}
|
|
3017
|
-
|
|
3018
|
-
}).catch(err => {
|
|
3019
|
-
reject('requestToSendErrors: '+ err);
|
|
3020
|
-
});
|
|
3021
|
-
});
|
|
3022
|
-
|
|
3023
|
-
}
|
|
3024
|
-
|
|
3025
|
-
// Function to send feedback data to server
|
|
3026
|
-
function requestToSendFeedback(_payload) {
|
|
3027
|
-
if (is_apptics_disabled()){
|
|
3028
|
-
return;
|
|
3029
|
-
}
|
|
3030
|
-
|
|
3031
|
-
if (isEmptyObj(_payload)){
|
|
3032
|
-
return;
|
|
3033
|
-
}
|
|
3034
|
-
|
|
3035
|
-
if (isEmpty(getHeaderParams('apid')) && isEmpty(getHeaderParams('mapid'))){
|
|
3036
|
-
checkAndUpdateDeviceInfo();
|
|
3037
|
-
return new Promise((resolve, reject) => {
|
|
3038
|
-
reject('requestToFeedback: You must call apptics.init() first');
|
|
3039
|
-
});
|
|
3040
|
-
}
|
|
3041
|
-
|
|
3042
|
-
let dataSize = sizeof(_payload);
|
|
3043
|
-
Console.log('requestToFeedback: Feedback Payload size : ' + (dataSize / 1024)); // no i18n
|
|
3044
|
-
|
|
3045
|
-
return new Promise((resolve, reject) => {
|
|
3046
|
-
// Perform to send feedback data here (e.g., make an API call)
|
|
3047
|
-
var payload = _payload;
|
|
3048
|
-
var headers = {apid:getHeaderParams('apid'), mapid:getHeaderParams('mapid')}; // no i18n
|
|
3049
|
-
|
|
3050
|
-
requestQueue.addRequest(getUrlWithParams('feedback'), getConfig('method'), payload, headers).processQueue().then(response => { // no i18n
|
|
3051
|
-
var _result = JSON.parse(response);
|
|
3052
|
-
if (_result && _result.result == 'success'){ // no i18n
|
|
3053
|
-
var data = _result;
|
|
3054
|
-
resolve(data);
|
|
3055
|
-
}
|
|
3056
|
-
else{
|
|
3057
|
-
reject('requestToFeedback: '+ _result.result);
|
|
3058
|
-
}
|
|
3059
|
-
|
|
3060
|
-
}).catch(err => {
|
|
3061
|
-
reject('requestToFeedback: '+ err);
|
|
3062
|
-
});
|
|
3063
|
-
});
|
|
3064
|
-
|
|
3065
|
-
}
|
|
3066
|
-
|
|
3067
|
-
function extractMethodNameFromStackTrace(stackTrace) {
|
|
3068
|
-
let methodName = '';
|
|
3069
|
-
if(isEmpty(stackTrace)){
|
|
3070
|
-
return methodName;
|
|
3071
|
-
}
|
|
3072
|
-
const lines = stackTrace.split('\n'); // no i18n
|
|
3073
|
-
if (lines.length < 2) {
|
|
3074
|
-
return methodName; // Not enough information in the stack trace
|
|
3075
|
-
}
|
|
3076
|
-
// The method name is typically included in the second line
|
|
3077
|
-
const methodNamePattern1 = /at (\S+) \(/;
|
|
3078
|
-
const methodNamePattern2 = /^(\w+)@/;
|
|
3079
|
-
|
|
3080
|
-
for (let line of lines){
|
|
3081
|
-
|
|
3082
|
-
const match1 = line.match(methodNamePattern1);
|
|
3083
|
-
const match2 = line.match(methodNamePattern2);
|
|
3084
|
-
// For browsers like Chrome, Ula
|
|
3085
|
-
if (match1 && match1[1]) {
|
|
3086
|
-
// Return the method name
|
|
3087
|
-
const urlRegex = /\((.*)\)/;
|
|
3088
|
-
// Extract the URL from the error string
|
|
3089
|
-
const urlMatch = urlRegex.exec(line);
|
|
3090
|
-
// Extracted URL
|
|
3091
|
-
const url = urlMatch ? urlMatch[1] : 'Unknown URL'; // no i18n
|
|
3092
|
-
methodName = match1[1];
|
|
3093
|
-
fileNameAndLine = url.split('/').pop(); // no i18n
|
|
3094
|
-
methodName = methodName;// + '@'+ fileNameAndLine;
|
|
3095
|
-
break;
|
|
3096
|
-
}
|
|
3097
|
-
|
|
3098
|
-
// For browsers like Safari
|
|
3099
|
-
if (match2 && match2[1]) {
|
|
3100
|
-
|
|
3101
|
-
// Return the method name
|
|
3102
|
-
methodName = match2[1];
|
|
3103
|
-
fileNameAndLine = line.split('@')[1].split('/').pop(); // no i18n
|
|
3104
|
-
methodName = methodName;// + '@'+ fileNameAndLine; // no i18n
|
|
3105
|
-
break;
|
|
3106
|
-
}
|
|
3107
|
-
}
|
|
3108
|
-
|
|
3109
|
-
return methodName;
|
|
3110
|
-
}
|
|
3111
|
-
|
|
3112
|
-
// Function to format duration conditionally
|
|
3113
|
-
function formatDuration(ms) {
|
|
3114
|
-
if (ms < 1000) { // Less than 1 second, show in milliseconds
|
|
3115
|
-
return `${ms.toFixed(2)} ms`;
|
|
3116
|
-
}
|
|
3117
|
-
const seconds = (ms / 1000).toFixed(2); // If seconds are meaningful
|
|
3118
|
-
if (ms < 60000) { // Less than 1 minute, show in seconds
|
|
3119
|
-
return `${seconds} s`;
|
|
3120
|
-
}
|
|
3121
|
-
const minutes = Math.floor(ms / 60000);
|
|
3122
|
-
const remainingSeconds = ((ms % 60000) / 1000).toFixed(2);
|
|
3123
|
-
if (minutes < 60) { // Less than 1 hour, show in minutes
|
|
3124
|
-
return `${minutes} m ${remainingSeconds} s`;
|
|
3125
|
-
}
|
|
3126
|
-
const hours = Math.floor(ms / (1000 * 60 * 60));
|
|
3127
|
-
return `${hours} h ${minutes % 60} m`; // Show in hours and minutes
|
|
3128
|
-
}
|
|
3129
|
-
|
|
3130
|
-
// Function to format size conditionally
|
|
3131
|
-
function formatSize(bytes) {
|
|
3132
|
-
if (bytes < 1024) { // Less than 1 KB
|
|
3133
|
-
return `${bytes} B`;
|
|
3134
|
-
}
|
|
3135
|
-
const kb = (bytes / 1024).toFixed(2); // Size in KB
|
|
3136
|
-
if (bytes < 1024 * 1024) { // Less than 1 MB
|
|
3137
|
-
return `${kb} KB`;
|
|
3138
|
-
}
|
|
3139
|
-
const mb = (bytes / (1024 * 1024)).toFixed(2); // Size in MB
|
|
3140
|
-
return `${mb} MB`;
|
|
3141
|
-
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
// Track when the window loses focus (user switches to another window or application)
|
|
3145
|
-
window.addEventListener('blur', function() { // no i18n
|
|
3146
|
-
// Window lost focus, user switched to another window or application
|
|
3147
|
-
Console.log('Window lost focus, user switched to another window or application'); // no i18n
|
|
3148
|
-
updateLastActiveTimeOfSession();
|
|
3149
|
-
});
|
|
3150
|
-
|
|
3151
|
-
// Track when the window gains focus (user switches back to the window)
|
|
3152
|
-
window.addEventListener('focus', function() { // no i18n
|
|
3153
|
-
// Window regained focus, user switched back to the window
|
|
3154
|
-
Console.log('Window regained focus, user switched back to the window'); // no i18n
|
|
3155
|
-
scheduleToCheckAndUpdateSession();
|
|
3156
|
-
checkAndScheduleToSendData();
|
|
3157
|
-
});
|
|
3158
|
-
|
|
3159
|
-
window.addEventListener('beforeunload', function() { // no i18n
|
|
3160
|
-
// Send an analytics event before the user leaves the page
|
|
3161
|
-
updateScreenWithEndtime();
|
|
3162
|
-
Console.log('update lastactivetime upon page unload'); // no i18n
|
|
3163
|
-
});
|
|
3164
|
-
|
|
3165
|
-
// if we are running in cordova use ondeviceready otherwise onload
|
|
3166
|
-
window.addEventListener((window.cordova) ? 'deviceready' : 'load', checkAndUpdateSession, { passive: true }); // no i18n
|
|
3167
|
-
|
|
3168
|
-
// Always send pending request when the connection comes back online
|
|
3169
|
-
window.addEventListener('online', scheduleToSendDataToServer, { passive: true }); // no i18n
|
|
3170
|
-
|
|
3171
|
-
window.screen.orientation.addEventListener('change', function() { // no i18n
|
|
3172
|
-
_properties.orientation = getOrientation();
|
|
3173
|
-
});
|
|
3174
|
-
|
|
3175
|
-
window.addEventListener("unhandledrejection", function(event) { // no i18n
|
|
3176
|
-
if(_isGlobalErrorTracking){
|
|
3177
|
-
trackError(event);
|
|
3178
|
-
}
|
|
3179
|
-
});
|
|
3180
|
-
|
|
3181
|
-
window.addEventListener('error', function(event) { // no i18n
|
|
3182
|
-
if(_isGlobalErrorTracking){
|
|
3183
|
-
trackError(event);
|
|
3184
|
-
}
|
|
3185
|
-
});
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
//Feedback UI
|
|
3189
|
-
var feedback = {
|
|
3190
|
-
feedbackUIHtml : `<div id="zasdkFeedbackconatiner" class="zasdk-modal-content">
|
|
3191
|
-
<div class="zasdk-header">
|
|
3192
|
-
<h2 class="zasdk-title">Share feedback</h2>
|
|
3193
|
-
<span id="appticsfeedbackclose" class="zasdk-close"><svg viewBox="0 0 24 24" style=" width: 20px; "><path d="M19.92,19.08c.23.23.23.61,0,.85-.12.12-.27.18-.42.18s-.31-.06-.42-.18l-7.08-7.08-7.08,7.08c-.12.12-.27.18-.42.18s-.31-.06-.42-.18c-.23-.23-.23-.61,0-.85l7.08-7.08-7.08-7.08c-.23-.23-.23-.61,0-.85s.61-.23.85,0l7.08,7.08,7.08-7.08c.23-.23.61-.23.85,0s.23.61,0,.85l-7.08,7.08,7.08,7.08Z"/></svg></span>
|
|
3194
|
-
</div>
|
|
3195
|
-
<div class="zasdk-feedback-types" data-type="">
|
|
3196
|
-
<div class="zasdk-feedback-type zasdk-selected" data-type="bug">
|
|
3197
|
-
<div class="zasdk-iconcnt zasdkfeedback__icon-report">
|
|
3198
|
-
<i class="zasdkfeedback__icon"><svg viewBox="0 0 24 24"><path d="M15.6,6.58c-.13-.37-.3-.7-.5-.97l1.23-1.18c.24-.23.25-.61.02-.85-.23-.24-.61-.25-.85-.02l-1.26,1.21c-.66-.45-1.37-.62-1.79-.68-.25-.04-.51-.04-.76-.02-.83.08-1.45.35-1.93.7l-1.22-1.2c-.24-.23-.62-.23-.85,0-.23.24-.23.62,0,.85l1.21,1.19c-.24.34-.41.68-.51.96-2.02,1.37-3.27,3.82-3.27,6.44,0,4.18,3.08,7.58,6.87,7.58s6.87-3.4,6.87-7.58c0-2.62-1.25-5.06-3.26-6.44ZM11.82,5.27c.15-.02.31-.01.47.01.69.1,1.86.48,2.26,1.9-.17.17-.51.44-1.14.65-1.08.36-2.31.28-3.36-.23-.24-.11-.44-.23-.6-.36,0-.01,0-.03.01-.04.18-.65.73-1.77,2.36-1.93ZM12,19.4c-3.12,0-5.67-2.86-5.67-6.38,0-1.98.82-3.82,2.19-5.02.26.25.59.48,1.01.68.78.38,1.65.57,2.5.57.6,0,1.19-.09,1.76-.28.88-.29,1.39-.7,1.67-1,1.38,1.2,2.21,3.06,2.21,5.05,0,3.52-2.54,6.38-5.67,6.38ZM9.12,9.86c-.92,0-1.67.75-1.67,1.67s.75,1.67,1.67,1.67,1.67-.75,1.67-1.67-.75-1.67-1.67-1.67ZM9.12,11.99c-.26,0-.47-.21-.47-.47s.21-.47.47-.47.47.21.47.47-.21.47-.47.47ZM14.88,9.86c-.92,0-1.67.75-1.67,1.67s.75,1.67,1.67,1.67,1.67-.75,1.67-1.67-.75-1.67-1.67-1.67ZM14.88,11.99c-.26,0-.47-.21-.47-.47s.21-.47.47-.47.47.21.47.47-.21.47-.47.47ZM12,14.49c-.92,0-1.67.75-1.67,1.67s.75,1.67,1.67,1.67,1.67-.75,1.67-1.67-.75-1.67-1.67-1.67ZM12,16.62c-.26,0-.47-.21-.47-.47s.21-.47.47-.47.47.21.47.47-.21.47-.47.47Z"/></svg></i>
|
|
3199
|
-
</div>
|
|
3200
|
-
<div>Bug</div>
|
|
3201
|
-
</div>
|
|
3202
|
-
<div class="zasdk-feedback-type" data-type="feedback">
|
|
3203
|
-
<div class="zasdk-iconcnt zasdkfeedback__icon-reqest">
|
|
3204
|
-
<i class="zasdkfeedback__icon"><svg viewBox="0 0 24 24"><path d="M6.69,9.25h10.81c.41,0,.75-.34.75-.75s-.34-.75-.75-.75H6.69c-.41,0-.75.34-.75.75s.34.75.75.75Z"/><path d="M6.69,13.07h8.11c.41,0,.75-.34.75-.75s-.34-.75-.75-.75H6.69c-.41,0-.75.34-.75.75s.34.75.75.75Z"/><path d="M20.72,5.17c0-.68-.55-1.23-1.23-1.23H4.48c-.68,0-1.23.55-1.23,1.23v11.84c0,.68.55,1.23,1.23,1.23h13.49l1.25,1.51c.17.2.41.31.67.31.1,0,.2-.02.3-.05.34-.13.57-.46.56-.83l-.03-14.01ZM19.22,17.39l-.17-.2c-.24-.29-.58-.45-.95-.45H4.75V5.44h14.47v11.95Z"/></svg></i>
|
|
3205
|
-
</div>
|
|
3206
|
-
<div>Feedback</div>
|
|
3207
|
-
</div>
|
|
3208
|
-
<div class="zasdk-feedback-type" data-type="help">
|
|
3209
|
-
<div class="zasdk-iconcnt zasdkfeedback__icon-help">
|
|
3210
|
-
<i class="zasdkfeedback__icon"><svg viewBox="0 0 24 24"><path d="M12.45,16.47c-.33,0-.6-.27-.6-.6v-2.7c0-.43.25-.82.64-.99.95-.42,3.15-1.62,3.15-3.51,0-1.6-1.01-3.03-2.51-3.55-.95-.33-1.97-.28-2.87.16-.91.43-1.59,1.2-1.92,2.14-.11.31-.45.48-.77.37-.31-.11-.48-.45-.37-.77.44-1.25,1.34-2.25,2.54-2.83,1.2-.57,2.54-.65,3.79-.21,1.99.7,3.32,2.58,3.31,4.69,0,2.46-2.34,3.91-3.79,4.57v2.63c0,.33-.27.6-.6.6ZM13.21,19.1c0-.66-.54-1.2-1.2-1.2h-.03c-.66,0-1.19.54-1.19,1.2s.55,1.2,1.21,1.2,1.2-.54,1.2-1.2Z"/></svg></i>
|
|
3211
|
-
</div>
|
|
3212
|
-
<div>Help</div>
|
|
3213
|
-
</div>
|
|
3214
|
-
<div class="zasdk-feedback-type" data-type="report">
|
|
3215
|
-
<div class="zasdk-iconcnt zasdkfeedback__icon-appreciate">
|
|
3216
|
-
<i class="zasdkfeedback__icon"><svg viewBox="0 0 24 24"><path d="M20.47,16.72l-6.66-11.53c-.37-.65-1.07-1.05-1.81-1.05s-1.44.4-1.81,1.05l-6.66,11.53c-.37.65-.37,1.45,0,2.09.37.65,1.07,1.05,1.81,1.05h13.32c.75,0,1.44-.4,1.81-1.05.37-.64.37-1.45,0-2.09ZM19.17,18.06c-.11.18-.3.3-.51.3H5.34c-.21,0-.41-.11-.51-.3-.1-.18-.1-.41,0-.59l6.66-11.53h0c.11-.18.3-.3.51-.3s.41.11.51.3l6.66,11.53c.11.18.11.41,0,.59Z"/><path d="M12.35,13.9s.37-4.72.37-4.72c.05-1.08-1.58-1.06-1.5.02l.48,4.71c.03.38.62.37.64,0Z"/><path d="M11.97,15.06c-.52,0-.94.42-.94.94s.42.94.94.94.94-.42.94-.94-.42-.94-.94-.94Z"/></svg></i>
|
|
3217
|
-
</div>
|
|
3218
|
-
<div>Report</div>
|
|
3219
|
-
</div>
|
|
3220
|
-
</div>
|
|
3221
|
-
<div id="zasdkFeedbackForm" class="zasdk-form">
|
|
3222
|
-
<label class="zasdkdesclbl" for="zasdkDescription">Add details here<span class="zasdkmadfeld">*</span> <span class="zaleftcharspan"><span class="zaleftcharcnt">5000</span><span class="zaleftchartxt">character left</span></span></label>
|
|
3223
|
-
<textarea id="zasdkDescription" name="description" placeholder="Please provide more details for us to help you better." reqname="name" maxlength="5000"></textarea>
|
|
3224
|
-
<div id="zasdkreccheckcnt" class="zasdkqz-container">
|
|
3225
|
-
<div class="zasdkqz-checkbox-wrapper">
|
|
3226
|
-
<input type="checkbox" id="zasdkqz-consent" class="zasdkqz-checkbox">
|
|
3227
|
-
<label for="zasdkqz-consent">By agreeing to record screen, I allow the collection of the required information for further analysis.</label>
|
|
3228
|
-
</div>
|
|
3229
|
-
<div id="zasdkqz-content" class="zasdkqz-content">
|
|
3230
|
-
<div class="zasdkqz-prop-content">Data collected while screen recording.
|
|
3231
|
-
<div class="zasdk_rec_hdr_icon zasdk-tooltip-container zasdk_rec_hdr">
|
|
3232
|
-
<i><svg viewBox="0 0 24 24"><path d="M12,20.6c-4.74,0-8.6-3.86-8.6-8.6S7.26,3.4,12,3.4s8.6,3.86,8.6,8.6-3.86,8.6-8.6,8.6ZM12,4.6c-4.08,0-7.4,3.32-7.4,7.4s3.32,7.4,7.4,7.4,7.4-3.32,7.4-7.4-3.32-7.4-7.4-7.4ZM12.6,15.97v-4.91c0-.33-.27-.6-.6-.6s-.6.27-.6.6v4.91c0,.33.27.6.6.6s.6-.27.6-.6ZM12.61,9.03c0-.33-.27-.6-.6-.6h-.01c-.33,0-.59.27-.59.6s.28.6.61.6.6-.27.6-.6Z"/></svg></i>
|
|
3233
|
-
<div class="zasdk-tooltip-top zasdk-prop-info">
|
|
3234
|
-
<ul>
|
|
3235
|
-
<li>- A recording of the window or region specified.</li>
|
|
3236
|
-
<li>- Audio captured during recording. (You can mute or re-record)</li>
|
|
3237
|
-
<li>- IP address.</li>
|
|
3238
|
-
<li>- Browser console logs generated while recording.</li>
|
|
3239
|
-
<li>- Device details (screen resolution, OS, and browser version).</li>
|
|
3240
|
-
<li>- Client-side performance metrics (DNS lookup time, TCP connection time, etc.).</li>
|
|
3241
|
-
</ul>
|
|
3242
|
-
</div>
|
|
3243
|
-
</div>
|
|
3244
|
-
</div>
|
|
3245
|
-
<div id="zasdkqz_rec_button" class="zasdkqz-button">Start screen recording</div>
|
|
3246
|
-
</div>
|
|
3247
|
-
</div>
|
|
3248
|
-
<div id="editRecordedVideo" class="zasdk_recordedClipArea" style="">
|
|
3249
|
-
<div id="recordScreenDesc" class="zasdk_rec_hdr"> Recorded Clip
|
|
3250
|
-
<div class="zasdk_rec_hdr_icon zasdk-tooltip-container">
|
|
3251
|
-
<i><svg viewBox="0 0 24 24"><path d="M12,20.6c-4.74,0-8.6-3.86-8.6-8.6S7.26,3.4,12,3.4s8.6,3.86,8.6,8.6-3.86,8.6-8.6,8.6ZM12,4.6c-4.08,0-7.4,3.32-7.4,7.4s3.32,7.4,7.4,7.4,7.4-3.32,7.4-7.4-3.32-7.4-7.4-7.4ZM12.6,15.97v-4.91c0-.33-.27-.6-.6-.6s-.6.27-.6.6v4.91c0,.33.27.6.6.6s.6-.27.6-.6ZM12.61,9.03c0-.33-.27-.6-.6-.6h-.01c-.33,0-.59.27-.59.6s.28.6.61.6.6-.27.6-.6Z"/></svg></i>
|
|
3252
|
-
<div class="zasdk-tooltip">This recording will be sent along with your feedback for further analysis.</div>
|
|
3253
|
-
</div>
|
|
3254
|
-
</div>
|
|
3255
|
-
<div class="zasdk_playEdit">
|
|
3256
|
-
<div class="zasdk_clipAreaButtonCnt zasdk-tooltip-container">
|
|
3257
|
-
<div id="preivewPlayButton" class="zasdk_clipAreaButton" title="Preview">
|
|
3258
|
-
<svg viewBox="0 0 24 24"><path d="M6.24,20.6c-.2,0-.39-.05-.57-.15-.38-.21-.62-.61-.62-1.05V4.59c0-.44.24-.84.62-1.05.38-.21.85-.19,1.22.04l11.52,7.41c.34.22.55.6.55,1,0,.41-.2.78-.55,1l-11.52,7.41c-.2.13-.42.19-.64.19ZM6.56,4.1l-.33.5v14.81s11.52-7.41,11.52-7.41L6.23,4.6l.33-.5Z"/></svg>
|
|
3259
|
-
</div>
|
|
3260
|
-
<div class="zasdk-tooltip">Preview</div>
|
|
3261
|
-
</div>
|
|
3262
|
-
<div class="zasdk_clipAreaButtonCnt zasdk-tooltip-container">
|
|
3263
|
-
<div id="videoEditButton" class="zasdk_clipAreaButton">
|
|
3264
|
-
<svg id="Layer_2" viewBox="0 0 24 24"><path d="M20.6,7.18c0-.58-.23-1.13-.65-1.54l-1.53-1.51c-.83-.83-2.29-.83-3.12,0l-1.31,1.3h0S4.88,14.41,4.88,14.41c-.12.12-.21.27-.26.44l-1.19,4.4c-.09.34,0,.7.26.95.19.18.44.29.7.29.09,0,.17-.01.26-.04l4.44-1.2c.16-.05.31-.13.44-.25l8.54-8.43h0s1.88-1.86,1.88-1.86c.06-.06.12-.12.17-.19h0c.31-.39.48-.86.48-1.36ZM8.72,18.12l-4.03,1.09,1.08-3.98L13.97,7.12l2.88,2.97-8.13,8.03ZM17.71,9.25l-2.88-2.97,1.32-1.3c.38-.38,1.04-.38,1.43,0l1.53,1.51c.19.18.29.43.29.69,0,.22-.08.43-.21.6h0s-.04.05-.08.08l-1.4,1.39Z"/></svg>
|
|
3265
|
-
</div>
|
|
3266
|
-
<div class="zasdk-tooltip">Edit</div>
|
|
3267
|
-
</div>
|
|
3268
|
-
<div class="zasdk_clipAreaButtonCnt zasdk-tooltip-container">
|
|
3269
|
-
<div id="videoDelButton" class="zasdk_clipAreaButton">
|
|
3270
|
-
<svg id="Layer_2" viewBox="0 0 24 24"><path d="M19.2,6.6h-3.4v-1c0-1.21-.99-2.2-2.2-2.2h-3.2c-1.21,0-2.2.99-2.2,2.2v1h-3.4c-.33,0-.6.27-.6.6s.27.6.6.6h1v10.6c0,1.21.99,2.2,2.2,2.2h8c1.21,0,2.2-.99,2.2-2.2V7.8h1c.33,0,.6-.27.6-.6s-.27-.6-.6-.6ZM9.4,5.6c0-.55.45-1,1-1h3.2c.55,0,1,.45,1,1v1h-5.2v-1ZM17,18.4c0,.55-.45,1-1,1h-8c-.55,0-1-.45-1-1V7.8h10v10.6ZM11,11.2v4.8c0,.33-.27.6-.6.6s-.6-.27-.6-.6v-4.8c0-.33.27-.6.6-.6s.6.27.6.6ZM14.2,11.2v4.8c0,.33-.27.6-.6.6s-.6-.27-.6-.6v-4.8c0-.33.27-.6.6-.6s.6.27.6.6Z"/></svg>
|
|
3271
|
-
</div>
|
|
3272
|
-
<div class="zasdk-tooltip">Delete</div>
|
|
3273
|
-
</div>
|
|
3274
|
-
</div>
|
|
3275
|
-
<div class="zasdk_videoPrev">
|
|
3276
|
-
<video id="previewVideoElemId" width="320" height="240" src=""></video>
|
|
3277
|
-
</div>
|
|
3278
|
-
</div>
|
|
3279
|
-
|
|
3280
|
-
<div class="zasdk-buttons">
|
|
3281
|
-
<div class="zasdk-btncnt">
|
|
3282
|
-
<div id="zasdkattachinfo" class="zasdkattachinf">Maximum 5 attachments with a total file size of 10MB is allowed</div>
|
|
3283
|
-
<input type="file" id="zasdkFileInput" class="zasdk-file-input" multiple accept=".png, .jpg">
|
|
3284
|
-
<label id="zasdkAttachBtn" class="zasdk-btn zasdk-attach-btn" for="zasdkFileInput">
|
|
3285
|
-
<svg id="Layer_2" viewBox="0 0 24 24" style=" width: 25px; "><path d="M12,20.6c-2.63,0-4.78-2.14-4.78-4.78V6.78c0-1.87,1.52-3.38,3.38-3.38s3.38,1.52,3.38,3.38v9.04c0,1.1-.9,1.99-2,1.99s-1.99-.89-1.99-1.99V7.48c0-.33.27-.6.6-.6h0c.33,0,.6.27.6.6v8.35c0,.44.35.79.79.79s.79-.36.79-.79V6.78c0-1.2-.98-2.18-2.18-2.18s-2.18.98-2.18,2.18v9.04c0,1.97,1.6,3.58,3.58,3.58s3.58-1.6,3.58-3.58V6.78c0-.33.27-.6.6-.6s.6.27.6.6v9.04c0,2.63-2.14,4.78-4.78,4.78Z"/></svg>
|
|
3286
|
-
<span>Attachments</span>
|
|
3287
|
-
</label>
|
|
3288
|
-
<div id="zasdkfilesizeinfo" class="zasdkfilesizeinf"></div>
|
|
3289
|
-
<ul id="zasakfileList" class="zasakfilelstcnt"></ul>
|
|
3290
|
-
</div>
|
|
3291
|
-
</div>
|
|
3292
|
-
</div>
|
|
3293
|
-
<div class="zasdk_submit_btncnt">
|
|
3294
|
-
<div id="zasdksubmitstatus" class="zasdkstsmsg" style="display:none;" ></div>
|
|
3295
|
-
<div id="zasdk_submit_btnsubcnt" class="zasdk_submit_btnsubcnt">
|
|
3296
|
-
<input type="button" id="zasdk_submit_btn" class="zasdk-btn zasdk-send-btn zasdkbtndisableclr" value="Send">
|
|
3297
|
-
</div>
|
|
3298
|
-
</div>
|
|
3299
|
-
</div>`,
|
|
3300
|
-
timerHtml : `<div id="zasdkrectimer" class="zasdk-timer-container zasdk-tooltip-container">
|
|
3301
|
-
<div class="zasdk-timer-control" id="zasdkRecordButton"><div class="zasdk-timer-stopcricle"></div></div>
|
|
3302
|
-
<span class="zasdk-timer-display" id="zasdkTimerDisplay">05:00</span>
|
|
3303
|
-
<div class="zasdk-tooltip-top">Stop Recording</div>
|
|
3304
|
-
</div>`,
|
|
3305
|
-
typeObj : {'bug' : 0, 'feedback': 1,'help': 2, 'report': 3},
|
|
3306
|
-
init : function(){
|
|
3307
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3308
|
-
if(!isEmpty(modal)){
|
|
3309
|
-
return;
|
|
3310
|
-
}
|
|
3311
|
-
const tempContainer = document.createElement('div');
|
|
3312
|
-
feedback.uploadFileAry = [];
|
|
3313
|
-
tempContainer.id = 'zasdkFeedbackModal';
|
|
3314
|
-
tempContainer.className = 'zasdk-modal';
|
|
3315
|
-
tempContainer.innerHTML = feedback.feedbackUIHtml;
|
|
3316
|
-
document.body.appendChild(tempContainer);
|
|
3317
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3318
|
-
var defaultoption = window.appticssettings._defaultoptions;
|
|
3319
|
-
var qz_ws_key = defaultoption.quartz_workspace_key;
|
|
3320
|
-
var qz_dp_key = defaultoption.quartz_department_key;
|
|
3321
|
-
var quartz_DC = {
|
|
3322
|
-
"Local": "https://quartz.localzoho.com", // No i18n
|
|
3323
|
-
"US": "https://quartz.zoho.com", // No i18n
|
|
3324
|
-
"EU": "https://quartz.zoho.eu", // No i18n
|
|
3325
|
-
"IN": "https://quartz.zoho.in", // No i18n
|
|
3326
|
-
"AU": "https://quartz.zoho.com.au", // No i18n
|
|
3327
|
-
"CN": "https://quartz.zoho.com.cn", // No i18n
|
|
3328
|
-
"CA": "https://quartz.zohocloud.ca", // No i18n
|
|
3329
|
-
"JP": "https://quartz.zoho.jp", // No i18n
|
|
3330
|
-
"SA": "https://quartz.zoho.sa", // No i18n
|
|
3331
|
-
"AE": "https://quartz.zoho.ae" // No i18n
|
|
3332
|
-
}
|
|
3333
|
-
var qz_dc_key = defaultoption.DC !== '-' ? quartz_DC[defaultoption.DC] : []; // No i18n
|
|
3334
|
-
var closeBtn = modal.querySelector("#appticsfeedbackclose");
|
|
3335
|
-
var feedbackTypes = modal.querySelectorAll(".zasdk-feedback-type");
|
|
3336
|
-
feedback.fileInput = modal.querySelector("#zasdkFileInput");
|
|
3337
|
-
var quartzrecbtn = modal.querySelector("#zasdkqz_rec_button");
|
|
3338
|
-
var submitbtn = modal.querySelector("#zasdk_submit_btn");
|
|
3339
|
-
var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt");
|
|
3340
|
-
|
|
3341
|
-
const checkbox = modal.querySelector('#zasdkqz-consent');
|
|
3342
|
-
const content = modal.querySelector('#zasdkqz-content');
|
|
3343
|
-
const preivewButton = modal.querySelector('#preivewPlayButton');
|
|
3344
|
-
const videoEditButton = modal.querySelector('#videoEditButton');
|
|
3345
|
-
const deleteVideoButton = modal.querySelector('#videoDelButton');
|
|
3346
|
-
|
|
3347
|
-
const feedbackbox = modal.querySelector('#zasdkFeedbackconatiner');
|
|
3348
|
-
|
|
3349
|
-
const descriptionField = modal.querySelector('#zasdkDescription');
|
|
3350
|
-
|
|
3351
|
-
feedback.isScaled = false;
|
|
3352
|
-
feedback.isHidden = false;
|
|
3353
|
-
|
|
3354
|
-
document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent);
|
|
3355
|
-
document.addEventListener('quartz-feedback-state', feedback.bindQuartzEvent);
|
|
3356
|
-
|
|
3357
|
-
document.removeEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent);
|
|
3358
|
-
document.addEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent);
|
|
3359
|
-
|
|
3360
|
-
modal.querySelector("#zasdkreccheckcnt").style.display = "block";
|
|
3361
|
-
|
|
3362
|
-
if(qz_ws_key == "-" || qz_dp_key == "-" || qz_dc_key == "-"){
|
|
3363
|
-
modal.querySelector("#zasdkreccheckcnt").style.display = "none";
|
|
3364
|
-
}
|
|
3365
|
-
|
|
3366
|
-
feedbackbox.addEventListener('transitionend', function(event) {
|
|
3367
|
-
if (event.propertyName === 'transform' && feedback.isScaled) {
|
|
3368
|
-
feedback.toggleWindowAnimation();
|
|
3369
|
-
}
|
|
3370
|
-
});
|
|
3371
|
-
|
|
3372
|
-
quartzrecbtn.onclick = function(e){
|
|
3373
|
-
e.stopImmediatePropagation();
|
|
3374
|
-
|
|
3375
|
-
let recordingDetails = {
|
|
3376
|
-
workspaceLinkName : qz_ws_key,
|
|
3377
|
-
departmentLinkName : qz_dp_key,
|
|
3378
|
-
recordingDomain : qz_dc_key
|
|
3379
|
-
};
|
|
3380
|
-
feedback.handleStatusmsg();
|
|
3381
|
-
Quartz.startRecording(recordingDetails);
|
|
3382
|
-
}
|
|
3383
|
-
|
|
3384
|
-
closeBtn.onclick = function() {
|
|
3385
|
-
feedback.close();
|
|
3386
|
-
}
|
|
3387
|
-
|
|
3388
|
-
preivewButton.addEventListener('click', function() {
|
|
3389
|
-
Quartz.previewVideo();
|
|
3390
|
-
});
|
|
3391
|
-
|
|
3392
|
-
videoEditButton.addEventListener('click', function() {
|
|
3393
|
-
Quartz.editVideo({quartzBranding:false});
|
|
3394
|
-
});
|
|
3395
|
-
|
|
3396
|
-
deleteVideoButton.addEventListener('click', function() {
|
|
3397
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3398
|
-
Quartz.clearFeedback();
|
|
3399
|
-
checkbox.checked = false;
|
|
3400
|
-
content.classList.remove('zasdkqz-show');
|
|
3401
|
-
modal.querySelector("#editRecordedVideo").style.display = "none";
|
|
3402
|
-
modal.querySelector("#zasdkreccheckcnt").style.display = "block";
|
|
3403
|
-
feedback.validateFeedbackField();
|
|
3404
|
-
});
|
|
3405
|
-
|
|
3406
|
-
submitbtn.addEventListener('click', async () => {
|
|
3407
|
-
// Disable button and show loader
|
|
3408
|
-
feedback.validateFeedbackField();
|
|
3409
|
-
submitbtn.disabled = true;
|
|
3410
|
-
|
|
3411
|
-
submitbtncnt.classList.add('zasdkbtndisabled');
|
|
3412
|
-
submitbtn.value = '';
|
|
3413
|
-
|
|
3414
|
-
try {
|
|
3415
|
-
let videoElement = modal.querySelector('#previewVideoElemId'),
|
|
3416
|
-
videoVisible = videoElement && videoElement.offsetParent !== null;
|
|
3417
|
-
if(videoVisible){
|
|
3418
|
-
feedback.submitRecording();
|
|
3419
|
-
}
|
|
3420
|
-
else{
|
|
3421
|
-
let dataobj = {},
|
|
3422
|
-
seltype = modal.querySelector('.zasdk-selected').getAttribute('data-type'),
|
|
3423
|
-
feedtype = !isEmpty(seltype) ? feedback.typeObj[seltype] : 1,
|
|
3424
|
-
fileInput = modal.querySelector("#zasdkFileInput"),
|
|
3425
|
-
files = fileInput.files,
|
|
3426
|
-
message = modal.querySelector('#zasdkDescription').value.trim();
|
|
3427
|
-
if(message.length > 0){
|
|
3428
|
-
dataobj = {
|
|
3429
|
-
type : feedtype,
|
|
3430
|
-
message : message,
|
|
3431
|
-
attachment : files,
|
|
3432
|
-
quartzid : ''
|
|
3433
|
-
}
|
|
3434
|
-
sendFeedbackData(dataobj);
|
|
3435
|
-
}
|
|
3436
|
-
else{
|
|
3437
|
-
feedback.handleStatusmsg(false, 'Please provide more details for us to help you better.'); // no i18n
|
|
3438
|
-
}
|
|
3439
|
-
}
|
|
3440
|
-
|
|
3441
|
-
}
|
|
3442
|
-
catch (error) {
|
|
3443
|
-
Console.error("sendFeedbackData : " + error);
|
|
3444
|
-
}
|
|
3445
|
-
});
|
|
3446
|
-
|
|
3447
|
-
checkbox.addEventListener('change', function() {
|
|
3448
|
-
if (this.checked) {
|
|
3449
|
-
content.classList.add('zasdkqz-show');
|
|
3450
|
-
} else {
|
|
3451
|
-
content.classList.remove('zasdkqz-show');
|
|
3452
|
-
}
|
|
3453
|
-
});
|
|
3454
|
-
|
|
3455
|
-
descriptionField.addEventListener('input', feedback.validateFeedbackField);
|
|
3456
|
-
|
|
3457
|
-
feedbackTypes.forEach(function(type) {
|
|
3458
|
-
type.addEventListener("click", function() {
|
|
3459
|
-
feedbackTypes.forEach(function(t) {
|
|
3460
|
-
t.classList.remove("zasdk-selected");
|
|
3461
|
-
});
|
|
3462
|
-
this.classList.add("zasdk-selected");
|
|
3463
|
-
});
|
|
3464
|
-
});
|
|
3465
|
-
|
|
3466
|
-
feedback.selectedFiles = new DataTransfer();
|
|
3467
|
-
feedback.fileInput.onchange = function() {
|
|
3468
|
-
if(feedback.selectedFiles.files.length + this.files.length > 5) {
|
|
3469
|
-
feedback.handleStatusmsg(false, 'Maximum 5 attachments is allowed'); // no i18n
|
|
3470
|
-
feedback.fileInput.files = feedback.selectedFiles.files;
|
|
3471
|
-
this.files = feedback.selectedFiles.files;
|
|
3472
|
-
return;
|
|
3473
|
-
}
|
|
3474
|
-
if (this.files.length > 0) {
|
|
3475
|
-
let filesize = 0;
|
|
3476
|
-
for (let file of this.files) {
|
|
3477
|
-
filesize = filesize + file.size;
|
|
3478
|
-
if(filesize > 10485760) {
|
|
3479
|
-
feedback.handleStatusmsg(false, 'Maximum limit reached. The total file size cannot exceed 10MB.'); // no i18n
|
|
3480
|
-
this.files = feedback.selectedFiles.files;
|
|
3481
|
-
return;
|
|
3482
|
-
}
|
|
3483
|
-
else {
|
|
3484
|
-
feedback.selectedFiles.items.add(file); // Add new files
|
|
3485
|
-
}
|
|
3486
|
-
}
|
|
3487
|
-
this.files = feedback.selectedFiles.files; // Update input with all files
|
|
3488
|
-
feedback.fileAttachment(); // Update UI
|
|
3489
|
-
}
|
|
3490
|
-
else if (feedback.selectedFiles.files.length > 0) {
|
|
3491
|
-
// Restore previous files if the user cancels
|
|
3492
|
-
this.files = feedback.selectedFiles.files;
|
|
3493
|
-
}
|
|
3494
|
-
|
|
3495
|
-
}
|
|
3496
|
-
|
|
3497
|
-
feedback.handleStatusmsg();
|
|
3498
|
-
feedback.updateLeftCount();
|
|
3499
|
-
},
|
|
3500
|
-
updateLeftCount : function() {
|
|
3501
|
-
document.querySelectorAll("[reqname]").forEach(function (elem) {
|
|
3502
|
-
let val = elem.value;
|
|
3503
|
-
let maxLength = parseInt(elem.getAttribute("maxlength"), 10);
|
|
3504
|
-
let counterElem = elem.parentElement.querySelector(".zaleftcharcnt");
|
|
3505
|
-
|
|
3506
|
-
if (counterElem) {
|
|
3507
|
-
counterElem.textContent = maxLength - val.length; // Update remaining count
|
|
3508
|
-
}
|
|
3509
|
-
});
|
|
3510
|
-
},
|
|
3511
|
-
|
|
3512
|
-
handleStatusmsg : function(isSuccess, stsmsg){
|
|
3513
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3514
|
-
if(isEmpty(modal)){
|
|
3515
|
-
return;
|
|
3516
|
-
}
|
|
3517
|
-
var stscnt = modal.querySelector("#zasdksubmitstatus");
|
|
3518
|
-
var submitbtn = modal.querySelector("#zasdk_submit_btn");
|
|
3519
|
-
var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt");
|
|
3520
|
-
|
|
3521
|
-
var successmsgclass = '';
|
|
3522
|
-
var successmsg = '';
|
|
3523
|
-
stscnt.style.display = "none";
|
|
3524
|
-
if(!isEmpty(isSuccess)){
|
|
3525
|
-
successmsgclass = isSuccess ? 'zasdkstssucs' : 'zasdkstserror';
|
|
3526
|
-
successmsg = !isEmpty(stsmsg) ? stsmsg : '';
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
stscnt.textContent = successmsg;
|
|
3530
|
-
stscnt.classList.add(successmsgclass);
|
|
3531
|
-
|
|
3532
|
-
stscnt.style.display = "block";
|
|
3533
|
-
submitbtncnt.classList.remove('zasdkbtndisabled');
|
|
3534
|
-
submitbtn.disabled = false;
|
|
3535
|
-
submitbtn.value = 'Send';
|
|
3536
|
-
}
|
|
3537
|
-
},
|
|
3538
|
-
handleErrorQuartzEvent : function(event){
|
|
3539
|
-
let errorType = event.detail.error.name;
|
|
3540
|
-
let errorMessage = event.detail.error.message;
|
|
3541
|
-
if(errorType == QuartzConstants.ErrorType.RECORDING_INTERRUPTED || errorType == QuartzConstants.ErrorType.FEEDBACK_TIMEOUT){
|
|
3542
|
-
feedback.stopRecording();
|
|
3543
|
-
}
|
|
3544
|
-
feedback.handleStatusmsg(false, errorMessage);
|
|
3545
|
-
},
|
|
3546
|
-
bindQuartzEvent : function(event){
|
|
3547
|
-
let feedbackState = event.detail.feedbackState;
|
|
3548
|
-
if(feedbackState == QuartzConstants.FeedbackState.RECORDING_IN_PROGRESS){
|
|
3549
|
-
var feedbacktimer = document.getElementById("zasdkrectimer");
|
|
3550
|
-
if(!isEmpty(feedbacktimer)){
|
|
3551
|
-
feedbacktimer.remove();
|
|
3552
|
-
}
|
|
3553
|
-
const tempDiv = document.createElement("div");
|
|
3554
|
-
tempDiv.innerHTML = feedback.timerHtml;
|
|
3555
|
-
const node = tempDiv.firstElementChild;
|
|
3556
|
-
document.body.appendChild(node);
|
|
3557
|
-
var feedbacktimer = document.getElementById("zasdkrectimer");
|
|
3558
|
-
feedback.timerDisplay = feedbacktimer.querySelector('#zasdkTimerDisplay');
|
|
3559
|
-
feedback.recordButton = feedbacktimer;
|
|
3560
|
-
feedback.TOTAL_TIME = 5 * 60; // 5 minutes in seconds
|
|
3561
|
-
feedback.remainingTime = feedback.TOTAL_TIME;
|
|
3562
|
-
feedback.isRecording = true;
|
|
3563
|
-
feedback.timerInterval;
|
|
3564
|
-
feedback.recordButton.addEventListener('click', feedback.toggleRecording);
|
|
3565
|
-
feedback.startRecording();
|
|
3566
|
-
feedback.toggleWindowAnimation();
|
|
3567
|
-
}
|
|
3568
|
-
},
|
|
3569
|
-
close : function(){
|
|
3570
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3571
|
-
document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent);
|
|
3572
|
-
Quartz.clearFeedback();
|
|
3573
|
-
if(!isEmpty(modal)){
|
|
3574
|
-
modal.remove();
|
|
3575
|
-
}
|
|
3576
|
-
},
|
|
3577
|
-
toggleWindowAnimation : function() {
|
|
3578
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3579
|
-
const box = modal.querySelector('#zasdkFeedbackconatiner');
|
|
3580
|
-
|
|
3581
|
-
if (feedback.isHidden) {
|
|
3582
|
-
modal.style.display = 'block';
|
|
3583
|
-
setTimeout(() => {
|
|
3584
|
-
box.style.transform = 'scale(1)';
|
|
3585
|
-
feedback.validateFeedbackField();
|
|
3586
|
-
}, 10);
|
|
3587
|
-
feedback.isHidden = false;
|
|
3588
|
-
feedback.isScaled = false;
|
|
3589
|
-
}
|
|
3590
|
-
else if (feedback.isScaled) {
|
|
3591
|
-
modal.style.display = 'none';
|
|
3592
|
-
feedback.isHidden = true;
|
|
3593
|
-
}
|
|
3594
|
-
else {
|
|
3595
|
-
box.style.transform = 'scale(0)';
|
|
3596
|
-
feedback.isScaled = true;
|
|
3597
|
-
}
|
|
3598
|
-
},
|
|
3599
|
-
fileAttachment : function(){
|
|
3600
|
-
|
|
3601
|
-
var uploadedFiles = feedback.fileInput.files;
|
|
3602
|
-
feedback.uploadTotalSize = 0;
|
|
3603
|
-
feedback.MaxFileSize = 10 * 1024 * 1024; //10 MB
|
|
3604
|
-
|
|
3605
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3606
|
-
var sizeInfo = modal.querySelector("#zasdkfilesizeinfo");
|
|
3607
|
-
var fileUl = modal.querySelector("#zasakfileList");
|
|
3608
|
-
sizeInfo.textContent = "";
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
if ((uploadedFiles.length) > 5) {
|
|
3612
|
-
isLimitExceeded = true;
|
|
3613
|
-
feedback.fileLimitExceeded(false, true);
|
|
3614
|
-
feedback.validateFeedbackField();
|
|
3615
|
-
return;
|
|
3616
|
-
}
|
|
3617
|
-
|
|
3618
|
-
fileUl.innerHTML = '';
|
|
3619
|
-
|
|
3620
|
-
if (uploadedFiles.length > 0) {
|
|
3621
|
-
var totalSize = 0;
|
|
3622
|
-
|
|
3623
|
-
for (var i = 0; i < uploadedFiles.length; i++) {
|
|
3624
|
-
|
|
3625
|
-
var fileName = uploadedFiles[i].name;
|
|
3626
|
-
var fName = fileName.substring(0, fileName.lastIndexOf('.'));
|
|
3627
|
-
var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
|
3628
|
-
|
|
3629
|
-
var bytes = uploadedFiles[i].size;
|
|
3630
|
-
totalSize += bytes;
|
|
3631
|
-
|
|
3632
|
-
var fileLi = feedback.elementCreator("li");
|
|
3633
|
-
fileLi.title = fileName;
|
|
3634
|
-
|
|
3635
|
-
var span1 = feedback.elementCreator("span");
|
|
3636
|
-
span1.className = "zaskFdBckFlName";
|
|
3637
|
-
span1.innerText = (fName.length > 10) ? fName.slice(0, 3) + "..." + fName.slice(-3) : fName;
|
|
3638
|
-
|
|
3639
|
-
var span2 = feedback.elementCreator("span");
|
|
3640
|
-
span2.innerText = "." + extension;
|
|
3641
|
-
|
|
3642
|
-
var span3 = feedback.elementCreator("span");
|
|
3643
|
-
span3.className = "zasdkFdBckFlCls";
|
|
3644
|
-
span3.setAttribute("data-name", fileName);
|
|
3645
|
-
span3.innerHTML = "×"; // No i18N
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
fileLi.appendChild(span1);
|
|
3649
|
-
fileLi.appendChild(span2);
|
|
3650
|
-
fileLi.appendChild(span3);
|
|
3651
|
-
fileUl.appendChild(fileLi);
|
|
3652
|
-
|
|
3653
|
-
}
|
|
3654
|
-
var limitReached = totalSize > feedback.MaxFileSize;
|
|
3655
|
-
feedback.fileLimitExceeded(limitReached);
|
|
3656
|
-
|
|
3657
|
-
sizeInfo.textContent = `${feedback.formatFileSize(totalSize)} Used / 10 MB`;
|
|
3658
|
-
|
|
3659
|
-
const clearFile = modal.querySelectorAll('.zasdkFdBckFlCls');
|
|
3660
|
-
Array.from(clearFile).forEach(function(element) {
|
|
3661
|
-
element.addEventListener('click', function() {
|
|
3662
|
-
feedback.handleStatusmsg();
|
|
3663
|
-
feedback.removeFileFromList(this);
|
|
3664
|
-
feedback.fileAttachment();
|
|
3665
|
-
});
|
|
3666
|
-
});
|
|
3667
|
-
}
|
|
3668
|
-
feedback.validateFeedbackField();
|
|
3669
|
-
},
|
|
3670
|
-
elementCreator : function(elType){
|
|
3671
|
-
return document.createElement(elType);
|
|
3672
|
-
},
|
|
3673
|
-
fileLimitExceeded : function(limitReached, filesLengthReached) {
|
|
3674
|
-
var infoMsg = "";
|
|
3675
|
-
if(filesLengthReached || limitReached)
|
|
3676
|
-
{
|
|
3677
|
-
infoMsg = filesLengthReached ? 'Maximum 5 attachments is allowed' : 'Maximum limit reached. The total file size cannot exceed 10MB.';
|
|
3678
|
-
}
|
|
3679
|
-
feedback.handleStatusmsg(false, infoMsg);
|
|
3680
|
-
},
|
|
3681
|
-
removeFileFromList: function(elem) {
|
|
3682
|
-
const fileName = elem.getAttribute('data-name');
|
|
3683
|
-
|
|
3684
|
-
// Find the index of the element in the file preview list
|
|
3685
|
-
const indexToRemove = Array.from(elem.parentNode.parentNode.children).indexOf(elem.parentNode);
|
|
3686
|
-
|
|
3687
|
-
elem.parentNode.remove(); // Remove the file preview
|
|
3688
|
-
|
|
3689
|
-
let newFiles = new DataTransfer();
|
|
3690
|
-
feedback.selectedFiles = new DataTransfer();
|
|
3691
|
-
|
|
3692
|
-
for (let i = 0; i < feedback.fileInput.files.length; i++) {
|
|
3693
|
-
if (i !== indexToRemove) {
|
|
3694
|
-
newFiles.items.add(feedback.fileInput.files[i]);
|
|
3695
|
-
feedback.selectedFiles.items.add(feedback.fileInput.files[i]);
|
|
3696
|
-
}
|
|
3697
|
-
}
|
|
3698
|
-
|
|
3699
|
-
feedback.fileInput.files = newFiles.files;
|
|
3700
|
-
},
|
|
3701
|
-
formatFileSize : function(bytes) {
|
|
3702
|
-
if (bytes === 0) return '0 KB';
|
|
3703
|
-
|
|
3704
|
-
const k = 1024;
|
|
3705
|
-
const sizeInKB = bytes / k;
|
|
3706
|
-
const sizeInMB = bytes / (k * k);
|
|
3707
|
-
const sizeInGB = bytes / (k * k * k);
|
|
3708
|
-
|
|
3709
|
-
if (sizeInGB >= 1) {
|
|
3710
|
-
return sizeInGB.toFixed(2) + ' GB';
|
|
3711
|
-
} else if (sizeInMB >= 1) {
|
|
3712
|
-
return sizeInMB.toFixed(2) + ' MB';
|
|
3713
|
-
} else {
|
|
3714
|
-
return sizeInKB.toFixed(2) + ' KB';
|
|
3715
|
-
}
|
|
3716
|
-
},
|
|
3717
|
-
toggleRecording : function() {
|
|
3718
|
-
feedback.isRecording = !feedback.isRecording;
|
|
3719
|
-
|
|
3720
|
-
if (feedback.isRecording) {
|
|
3721
|
-
feedback.startRecording();
|
|
3722
|
-
} else {
|
|
3723
|
-
feedback.stopRecording();
|
|
3724
|
-
}
|
|
3725
|
-
},
|
|
3726
|
-
startRecording : function() {
|
|
3727
|
-
if (!feedback.timerInterval) {
|
|
3728
|
-
feedback.timerInterval = setInterval(feedback.updateTimer, 1000);
|
|
3729
|
-
}
|
|
3730
|
-
},
|
|
3731
|
-
stopRecording : function() {
|
|
3732
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3733
|
-
clearInterval(feedback.timerInterval);
|
|
3734
|
-
feedback.timerInterval = null;
|
|
3735
|
-
document.querySelector("#zasdkrectimer").remove();
|
|
3736
|
-
feedback.toggleWindowAnimation();
|
|
3737
|
-
modal.querySelector("#editRecordedVideo").style.display = "block";
|
|
3738
|
-
modal.querySelector("#zasdkreccheckcnt").style.display = "none";
|
|
3739
|
-
|
|
3740
|
-
let videoElem = modal.querySelector('#previewVideoElemId');
|
|
3741
|
-
Quartz.endRecording();
|
|
3742
|
-
Quartz.setVideoContent(videoElem);
|
|
3743
|
-
},
|
|
3744
|
-
submitRecording : function(){
|
|
3745
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3746
|
-
let testEmail = 'user@example.com',
|
|
3747
|
-
testMessage = '-',
|
|
3748
|
-
zqrecid = '',
|
|
3749
|
-
userEmail = (_user_info.hasOwnProperty('userid') && !isEmpty(_user_info.userid)) ? _user_info.userid : testEmail,
|
|
3750
|
-
subject = modal.querySelector('#zasdkDescription').value.trim() || testMessage,
|
|
3751
|
-
emailRegex = /^[\w]([\w\-\.\+\'=]*)@([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,22}$/;
|
|
3752
|
-
userEmail = (emailRegex.test(userEmail) && opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) ? userEmail : testEmail;
|
|
3753
|
-
|
|
3754
|
-
// Submit the recording
|
|
3755
|
-
Quartz.submitRecording({
|
|
3756
|
-
email: userEmail,
|
|
3757
|
-
subject: subject,
|
|
3758
|
-
})
|
|
3759
|
-
.then((response) => {
|
|
3760
|
-
zqrecid = !isEmptyObj(response) && response.hasOwnProperty('feedbackLink') ? response.feedbackLink : '';
|
|
3761
|
-
let dataobj = {},
|
|
3762
|
-
seltype = modal.querySelector('.zasdk-selected').getAttribute('data-type'),
|
|
3763
|
-
feedtype = !isEmpty(seltype) ? feedback.typeObj[seltype] : 1,
|
|
3764
|
-
fileInput = modal.querySelector("#zasdkFileInput"),
|
|
3765
|
-
files = fileInput.files,
|
|
3766
|
-
message = subject;
|
|
3767
|
-
dataobj = {
|
|
3768
|
-
type : feedtype,
|
|
3769
|
-
message : message,
|
|
3770
|
-
attachment : files,
|
|
3771
|
-
quartzid : zqrecid
|
|
3772
|
-
}
|
|
3773
|
-
sendFeedbackData(dataobj);
|
|
3774
|
-
});
|
|
3775
|
-
},
|
|
3776
|
-
updateTimer : function() {
|
|
3777
|
-
if (feedback.remainingTime > 0) {
|
|
3778
|
-
feedback.remainingTime--;
|
|
3779
|
-
feedback.updateDisplay();
|
|
3780
|
-
} else {
|
|
3781
|
-
feedback.stopRecording();
|
|
3782
|
-
}
|
|
3783
|
-
},
|
|
3784
|
-
updateDisplay : function() {
|
|
3785
|
-
const minutes = Math.floor(feedback.remainingTime / 60);
|
|
3786
|
-
const seconds = feedback.remainingTime % 60;
|
|
3787
|
-
feedback.timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
3788
|
-
},
|
|
3789
|
-
validateFeedbackField : function()
|
|
3790
|
-
{
|
|
3791
|
-
feedback.updateLeftCount();
|
|
3792
|
-
var modal = document.getElementById("zasdkFeedbackModal");
|
|
3793
|
-
const descriptionField = modal.querySelector('#zasdkDescription');
|
|
3794
|
-
const attachmentField = modal.querySelector('#zasdkFileInput');
|
|
3795
|
-
const videoElement = modal.querySelector('#previewVideoElemId');
|
|
3796
|
-
const sendButton = modal.querySelector('#zasdk_submit_btn');
|
|
3797
|
-
|
|
3798
|
-
const descriptionFilled = descriptionField && descriptionField.value.trim() !== '' && descriptionField.value.trim().length > 0;
|
|
3799
|
-
const attachmentSelected = attachmentField && attachmentField.files && attachmentField.files.length > 0;
|
|
3800
|
-
const videoVisible = videoElement && videoElement.offsetParent !== null; // Check if visible
|
|
3801
|
-
|
|
3802
|
-
const errorElements = modal.querySelectorAll('.zasdkmaxerror');
|
|
3803
|
-
const hasErrors = feedback.getVisibleErrorCount(errorElements) > 0;
|
|
3804
|
-
|
|
3805
|
-
if (!hasErrors && descriptionFilled) {
|
|
3806
|
-
sendButton.classList.remove('zasdkbtndisableclr');
|
|
3807
|
-
feedback.handleStatusmsg();
|
|
3808
|
-
} else {
|
|
3809
|
-
sendButton.classList.add('zasdkbtndisableclr');
|
|
3810
|
-
}
|
|
3811
|
-
},
|
|
3812
|
-
getVisibleErrorCount : function(elements) {
|
|
3813
|
-
return Array.from(elements).filter(element => element.offsetParent !== null).length;
|
|
3814
|
-
}
|
|
3815
|
-
}
|
|
3816
|
-
|
|
3817
|
-
})(this, document);
|