surveysparrow-ionic-plugin 1.0.7-beta.4 → 2.0.0

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.
Files changed (94) hide show
  1. package/dist/angular-ui/esm2022/angular-ui.mjs +5 -0
  2. package/dist/angular-ui/esm2022/public-api.mjs +3 -0
  3. package/dist/angular-ui/esm2022/spotcheck.component.mjs +17 -0
  4. package/dist/angular-ui/esm2022/spotchecks/SpotCheck.mjs +51 -0
  5. package/dist/angular-ui/esm2022/spotchecks/SpotCheckComponent.mjs +323 -0
  6. package/dist/angular-ui/esm2022/spotchecks/SpotcheckStateService.mjs +65 -0
  7. package/dist/angular-ui/esm2022/spotchecks/api.mjs +230 -0
  8. package/dist/angular-ui/esm2022/spotchecks/helpers.mjs +328 -0
  9. package/dist/angular-ui/esm2022/spotchecks/index.mjs +2 -0
  10. package/dist/angular-ui/esm2022/spotchecks/storage.mjs +7 -0
  11. package/dist/angular-ui/esm2022/spotchecks/types.mjs +2 -0
  12. package/dist/angular-ui/fesm2022/angular-ui.mjs +1013 -0
  13. package/dist/angular-ui/fesm2022/angular-ui.mjs.map +1 -0
  14. package/dist/angular-ui/index.d.ts +5 -0
  15. package/dist/angular-ui/public-api.d.ts +2 -0
  16. package/dist/angular-ui/spotcheck.component.d.ts +5 -0
  17. package/dist/angular-ui/spotchecks/SpotCheckComponent.d.ts +56 -0
  18. package/dist/angular-ui/spotchecks/SpotcheckStateService.d.ts +12 -0
  19. package/dist/{esm → angular-ui}/spotchecks/helpers.d.ts +1 -4
  20. package/dist/angular-ui/spotchecks/index.d.ts +2 -0
  21. package/dist/angular-ui/spotchecks/storage.d.ts +2 -0
  22. package/dist/{esm → angular-ui}/spotchecks/types.d.ts +5 -4
  23. package/dist/esm/angular-ui/lib/public-api.d.ts +2 -0
  24. package/dist/esm/angular-ui/lib/public-api.js +3 -0
  25. package/dist/esm/angular-ui/lib/public-api.js.map +1 -0
  26. package/dist/esm/angular-ui/lib/spotcheck.component.d.ts +2 -0
  27. package/dist/esm/angular-ui/lib/spotcheck.component.js +20 -0
  28. package/dist/esm/angular-ui/lib/spotcheck.component.js.map +1 -0
  29. package/dist/esm/angular-ui/lib/spotchecks/SpotCheck.d.ts +4 -0
  30. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/SpotCheck.js +1 -3
  31. package/dist/esm/angular-ui/lib/spotchecks/SpotCheck.js.map +1 -0
  32. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/SpotCheckComponent.d.ts +1 -0
  33. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/SpotCheckComponent.js +13 -7
  34. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckComponent.js.map +1 -0
  35. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/SpotcheckStateService.js +1 -0
  36. package/dist/esm/angular-ui/lib/spotchecks/SpotcheckStateService.js.map +1 -0
  37. package/dist/esm/angular-ui/lib/spotchecks/api.d.ts +15 -0
  38. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/api.js +20 -29
  39. package/dist/esm/angular-ui/lib/spotchecks/api.js.map +1 -0
  40. package/dist/esm/angular-ui/lib/spotchecks/helpers.d.ts +29 -0
  41. package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/helpers.js +6 -19
  42. package/dist/esm/angular-ui/lib/spotchecks/helpers.js.map +1 -0
  43. package/dist/esm/angular-ui/lib/spotchecks/index.d.ts +2 -0
  44. package/dist/esm/angular-ui/lib/spotchecks/index.js +2 -0
  45. package/dist/esm/angular-ui/lib/spotchecks/index.js.map +1 -0
  46. package/dist/esm/angular-ui/lib/spotchecks/storage.js.map +1 -0
  47. package/dist/esm/angular-ui/lib/spotchecks/types.d.ts +78 -0
  48. package/dist/esm/angular-ui/lib/spotchecks/types.js.map +1 -0
  49. package/dist/esm/index.d.ts +1 -1
  50. package/dist/esm/index.js +1 -1
  51. package/dist/esm/index.js.map +1 -1
  52. package/dist/plugin.cjs.js +51510 -527
  53. package/dist/plugin.cjs.js.map +1 -1
  54. package/dist/plugin.js +51511 -524
  55. package/dist/plugin.js.map +1 -1
  56. package/package.json +31 -4
  57. package/src/angular-ui/lib/public-api.ts +2 -0
  58. package/src/angular-ui/lib/spotcheck.component.ts +10 -0
  59. package/src/angular-ui/lib/spotchecks/SpotCheck.ts +54 -0
  60. package/src/angular-ui/lib/spotchecks/SpotCheckComponent.css +7 -0
  61. package/src/angular-ui/lib/spotchecks/SpotCheckComponent.html +27 -0
  62. package/src/angular-ui/lib/spotchecks/SpotCheckComponent.ts +295 -0
  63. package/src/angular-ui/lib/spotchecks/SpotcheckStateService.ts +64 -0
  64. package/src/angular-ui/lib/spotchecks/api.ts +286 -0
  65. package/src/angular-ui/lib/spotchecks/helpers.ts +401 -0
  66. package/src/angular-ui/lib/spotchecks/index.ts +9 -0
  67. package/src/angular-ui/lib/spotchecks/storage.ts +7 -0
  68. package/src/angular-ui/lib/spotchecks/types.ts +84 -0
  69. package/src/angular-ui/ng-package.json +13 -0
  70. package/src/angular-ui/package.json +10 -0
  71. package/src/definitions.ts +17 -0
  72. package/src/index.ts +10 -0
  73. package/dist/esm/spotchecks/SpotCheck.js.map +0 -1
  74. package/dist/esm/spotchecks/SpotCheckComponent.js.map +0 -1
  75. package/dist/esm/spotchecks/SpotCheckService.d.ts +0 -8
  76. package/dist/esm/spotchecks/SpotCheckService.js +0 -45
  77. package/dist/esm/spotchecks/SpotCheckService.js.map +0 -1
  78. package/dist/esm/spotchecks/SpotcheckStateService.js.map +0 -1
  79. package/dist/esm/spotchecks/SpotchecksListener.d.ts +0 -9
  80. package/dist/esm/spotchecks/SpotchecksListener.js +0 -37
  81. package/dist/esm/spotchecks/SpotchecksListener.js.map +0 -1
  82. package/dist/esm/spotchecks/api.js.map +0 -1
  83. package/dist/esm/spotchecks/helpers.js.map +0 -1
  84. package/dist/esm/spotchecks/index.d.ts +0 -5
  85. package/dist/esm/spotchecks/index.js +0 -6
  86. package/dist/esm/spotchecks/index.js.map +0 -1
  87. package/dist/esm/spotchecks/storage.js.map +0 -1
  88. package/dist/esm/spotchecks/types.js.map +0 -1
  89. /package/dist/{esm → angular-ui}/spotchecks/SpotCheck.d.ts +0 -0
  90. /package/dist/{esm → angular-ui}/spotchecks/api.d.ts +0 -0
  91. /package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/SpotcheckStateService.d.ts +0 -0
  92. /package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/storage.d.ts +0 -0
  93. /package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/storage.js +0 -0
  94. /package/dist/esm/{spotchecks → angular-ui/lib/spotchecks}/types.js +0 -0
@@ -0,0 +1,1013 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, Component, Input, ViewChild, HostListener } from '@angular/core';
3
+ import * as i2 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { v4 } from 'uuid';
6
+ import { Device } from '@capacitor/device';
7
+ import axios from 'axios';
8
+ import { BehaviorSubject } from 'rxjs';
9
+ import * as i1 from '@angular/platform-browser';
10
+
11
+ class SpotcheckStateService {
12
+ initialState = {
13
+ isVisible: false,
14
+ spotcheckPosition: 'bottom',
15
+ spotcheckURL: '',
16
+ spotcheckID: 0,
17
+ spotcheckContactID: 0,
18
+ afterDelay: 0.0,
19
+ maxHeight: 0.5,
20
+ currentQuestionHeight: 0,
21
+ isFullScreenMode: false,
22
+ isBannerImageOn: false,
23
+ triggerToken: '',
24
+ closeButtonStyle: {},
25
+ isCloseButtonEnabled: false,
26
+ isSpotPassed: false,
27
+ isChecksPassed: false,
28
+ customEventsSpotChecks: [],
29
+ targetToken: '',
30
+ domainName: '',
31
+ userDetails: {},
32
+ variables: {},
33
+ customProperties: {},
34
+ traceId: '',
35
+ isClassicLoading: true,
36
+ isChatLoading: true,
37
+ classicUrl: '',
38
+ chatUrl: '',
39
+ classicWebViewRef: null,
40
+ chatWebViewRef: null,
41
+ filteredSpotChecks: [],
42
+ spotCheckType: '',
43
+ isMounted: false,
44
+ textPosition: 0,
45
+ screenHeight: 0,
46
+ keyBoardHeight: 0,
47
+ spotChecksMode: '',
48
+ avatarEnabled: false,
49
+ avatarUrl: '',
50
+ screenwiseUserDetails: {}
51
+ };
52
+ spotcheckState = new BehaviorSubject(this.initialState);
53
+ state$ = this.spotcheckState.asObservable();
54
+ setState(state) {
55
+ this.spotcheckState.next({ ...this.spotcheckState.value, ...state });
56
+ }
57
+ clearState() {
58
+ this.spotcheckState.next(this.initialState);
59
+ }
60
+ getState() {
61
+ return this.spotcheckState.getValue();
62
+ }
63
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotcheckStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
64
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotcheckStateService, providedIn: 'root' });
65
+ }
66
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotcheckStateService, decorators: [{
67
+ type: Injectable,
68
+ args: [{
69
+ providedIn: 'root',
70
+ }]
71
+ }] });
72
+
73
+ let globalSpotcheckStateService;
74
+ const getSpotcheckStateService = () => {
75
+ if (!globalSpotcheckStateService) {
76
+ globalSpotcheckStateService = new SpotcheckStateService();
77
+ }
78
+ return globalSpotcheckStateService;
79
+ };
80
+ function generateTraceId() {
81
+ const uuidString = v4();
82
+ const timestamp = Date.now();
83
+ return `${uuidString}-${timestamp}`;
84
+ }
85
+ const ischatSurvey = (type) => {
86
+ return (type === 'Conversational' ||
87
+ type === 'CESChat' ||
88
+ type === 'NPSChat' ||
89
+ type === 'CSATChat');
90
+ };
91
+ const getOS = async () => {
92
+ const info = await Device.getInfo();
93
+ return info.operatingSystem;
94
+ };
95
+ const setAppearance = async (responseJson, screen, domainName, traceId, variables) => {
96
+ try {
97
+ const spotcheckStateService = getSpotcheckStateService();
98
+ let state = spotcheckStateService.getState();
99
+ if (responseJson) {
100
+ const currentSpotcheck = state.filteredSpotChecks.find((spotcheck) => spotcheck['id'] === responseJson?.spotCheckId ||
101
+ spotcheck['id'] === responseJson?.id);
102
+ const appearance = responseJson?.appearance;
103
+ let chat = false;
104
+ let updatedState = {};
105
+ if (appearance) {
106
+ const { position, closeButton, colors, cardProperties, mode, bannerImage, } = appearance;
107
+ const { maxHeight } = cardProperties || {};
108
+ updatedState = {
109
+ spotcheckPosition: position === 'top_full' || position === 'center_top'
110
+ ? 'top'
111
+ : position === 'center_center'
112
+ ? 'center'
113
+ : 'bottom',
114
+ isCloseButtonEnabled: closeButton ?? true,
115
+ closeButtonStyle: colors?.overrides ?? {},
116
+ maxHeight: maxHeight ? parseFloat(maxHeight) / 100 : 0,
117
+ spotCheckType: ischatSurvey(currentSpotcheck?.['survey']?.surveyType) &&
118
+ mode === 'fullScreen'
119
+ ? 'chat'
120
+ : 'classic',
121
+ isFullScreenMode: mode === 'fullScreen',
122
+ isBannerImageOn: bannerImage?.enabled ?? false,
123
+ spotChecksMode: mode,
124
+ avatarEnabled: appearance?.avatar?.enabled ?? false,
125
+ avatarUrl: appearance?.avatar?.avatarUrl ?? '',
126
+ };
127
+ chat = updatedState.spotCheckType === 'chat';
128
+ }
129
+ const spotCheckId = responseJson?.spotCheckId ?? 0;
130
+ const spotCheckContactId = responseJson?.spotCheckContactId ??
131
+ responseJson?.spotCheckContact?.id ??
132
+ 0;
133
+ const triggerToken = responseJson?.triggerToken ?? '';
134
+ updatedState = {
135
+ ...updatedState,
136
+ spotcheckID: spotCheckId,
137
+ spotcheckContactID: spotCheckContactId,
138
+ triggerToken,
139
+ };
140
+ const baseSpotcheckURL = `https://${domainName}/s/spotcheck/${triggerToken}/${chat ? 'config' : 'bootstrap'}?spotcheckContactId=${spotCheckContactId}&traceId=${traceId}&spotcheckUrl=${screen}`;
141
+ let fullSpotcheckURL = baseSpotcheckURL;
142
+ Object.entries(variables).forEach(([key, value]) => {
143
+ fullSpotcheckURL += `&${key}=${value}`;
144
+ });
145
+ updatedState.spotcheckURL = fullSpotcheckURL;
146
+ spotcheckStateService.setState(updatedState);
147
+ try {
148
+ const response = await axios.get(fullSpotcheckURL);
149
+ const themeInfo = response.data.config.generatedCSS;
150
+ const theme_payload = { type: 'THEME_UPDATE_SPOTCHECK', themeInfo };
151
+ state = spotcheckStateService.getState();
152
+ let webViewRef = chat ? state.chatWebViewRef : state.classicWebViewRef;
153
+ let isLoading = chat ? state.isChatLoading : state.isClassicLoading;
154
+ const resetStateData = {
155
+ type: 'RESET_STATE',
156
+ state: {
157
+ ...(response.data || {}),
158
+ skip: true,
159
+ spotCheckAppearance: {
160
+ ...(appearance || {}),
161
+ targetType: 'MOBILE',
162
+ },
163
+ spotcheckUrl: screen,
164
+ traceId,
165
+ elementBuilderParams: {
166
+ ...(variables || {}),
167
+ },
168
+ },
169
+ };
170
+ const sendMessageToIframe = (iframe, data) => {
171
+ if (iframe && iframe.contentWindow) {
172
+ try {
173
+ iframe.contentWindow.postMessage(data, '*');
174
+ }
175
+ catch (error) {
176
+ console.error('❌ Failed to send message to iframe:', error);
177
+ }
178
+ }
179
+ };
180
+ const communicateWithWebView = async (iframe) => {
181
+ await new Promise(resolve => setTimeout(() => {
182
+ sendMessageToIframe(iframe, resetStateData);
183
+ sendMessageToIframe(iframe, theme_payload);
184
+ resolve(true);
185
+ }, 2000));
186
+ };
187
+ if (webViewRef) {
188
+ if (isLoading === false) {
189
+ communicateWithWebView(webViewRef);
190
+ start();
191
+ return true;
192
+ }
193
+ else {
194
+ // todo: recheck this
195
+ const unsubscribe = spotcheckStateService.state$.subscribe((currentState) => {
196
+ const { isChatLoading, isClassicLoading, chatWebViewRef, classicWebViewRef, } = currentState;
197
+ if ((!isChatLoading && chat) || (!isClassicLoading && !chat)) {
198
+ unsubscribe.unsubscribe();
199
+ const activeWebViewRef = chat
200
+ ? chatWebViewRef
201
+ : classicWebViewRef;
202
+ if (activeWebViewRef) {
203
+ communicateWithWebView(activeWebViewRef);
204
+ start();
205
+ }
206
+ else {
207
+ console.warn('⚠️ Active WebView ref is null after loading completed');
208
+ }
209
+ }
210
+ });
211
+ return true;
212
+ }
213
+ }
214
+ else {
215
+ const unsubscribeWebView = spotcheckStateService.state$.subscribe((currentState) => {
216
+ const updatedWebViewRef = chat
217
+ ? currentState.chatWebViewRef
218
+ : currentState.classicWebViewRef;
219
+ const updatedIsLoading = chat
220
+ ? currentState.isChatLoading
221
+ : currentState.isClassicLoading;
222
+ if (updatedWebViewRef) {
223
+ if (!updatedIsLoading) {
224
+ unsubscribeWebView.unsubscribe();
225
+ communicateWithWebView(updatedWebViewRef);
226
+ start();
227
+ }
228
+ else {
229
+ console.log('⏳ WebView ref available but still loading...');
230
+ }
231
+ }
232
+ });
233
+ return true;
234
+ }
235
+ }
236
+ catch (error) {
237
+ throw new Error(error.message);
238
+ }
239
+ }
240
+ throw new Error('Something went wrong');
241
+ }
242
+ catch (error) {
243
+ throw new Error(error.message);
244
+ }
245
+ };
246
+ const start = () => {
247
+ const state = getSpotcheckStateService().getState();
248
+ setTimeout(() => {
249
+ getSpotcheckStateService().setState({ isVisible: true });
250
+ }, state.afterDelay * 1000);
251
+ };
252
+ const closeSpotCheck = async () => {
253
+ try {
254
+ const stateService = getSpotcheckStateService();
255
+ const state = stateService.getState();
256
+ const payload = {
257
+ traceId: state.traceId,
258
+ triggerToken: state.triggerToken,
259
+ };
260
+ const response = await fetch(`https://${state.domainName}/api/internal/spotcheck/dismiss/${state.spotcheckContactID}`, {
261
+ method: 'PUT',
262
+ headers: {
263
+ 'Content-Type': 'application/json',
264
+ },
265
+ body: JSON.stringify(payload),
266
+ });
267
+ if (response.status != 200) {
268
+ console.log(`Error: ${response.status}`);
269
+ }
270
+ }
271
+ catch (error) {
272
+ console.log('Error parsing JSON:', error);
273
+ }
274
+ };
275
+ const handleSurveyEnd = () => {
276
+ const stateService = getSpotcheckStateService();
277
+ const state = stateService.getState();
278
+ const webViewRef = state.spotCheckType === 'chat'
279
+ ? state.chatWebViewRef
280
+ : state.classicWebViewRef;
281
+ webViewRef?.current?.injectJavaScript(`
282
+ (function() {
283
+ window.dispatchEvent(new MessageEvent('message', {
284
+ data: ${JSON.stringify({ type: 'UNMOUNT_APP' })}
285
+ }));
286
+ })();
287
+ `);
288
+ const updatedState = {
289
+ isVisible: false,
290
+ isCloseButtonEnabled: false,
291
+ isFullScreenMode: false,
292
+ spotcheckID: 0,
293
+ currentQuestionHeight: 0,
294
+ closeButtonStyle: {},
295
+ spotcheckContactID: 0,
296
+ spotcheckURL: '',
297
+ spotcheckPosition: 'bottom',
298
+ isMounted: false,
299
+ spotCheckType: '',
300
+ screenHeight: 0,
301
+ keyBoardHeight: 0,
302
+ textPosition: 0,
303
+ spotChecksMode: '',
304
+ avatarEnabled: false,
305
+ avatarUrl: '',
306
+ };
307
+ stateService.setState(updatedState);
308
+ };
309
+ const getSpotcheckComponentCssStyles = (state) => {
310
+ let styles = {};
311
+ let wrapperStyles = {};
312
+ let extraPaddingForMiniCardCloseButtonIfTopPosition = 0;
313
+ if (state.isFullScreenMode && state.isVisible) {
314
+ wrapperStyles = {
315
+ display: 'flex',
316
+ height: '100%',
317
+ };
318
+ styles = {
319
+ display: 'flex',
320
+ height: '100%',
321
+ };
322
+ }
323
+ if (state.isVisible && state.isMounted) {
324
+ let height = Math.min(state.currentQuestionHeight, (state.maxHeight * window.innerHeight));
325
+ if (state.spotChecksMode === 'miniCard') {
326
+ if (state.avatarEnabled) {
327
+ height = height - 56;
328
+ }
329
+ if (state.isCloseButtonEnabled) {
330
+ height = height - 40;
331
+ }
332
+ }
333
+ switch (state.spotcheckPosition) {
334
+ case 'bottom':
335
+ styles = {
336
+ display: 'flex',
337
+ height: height + 'px',
338
+ };
339
+ wrapperStyles = {
340
+ display: 'flex',
341
+ justifyContent: 'flex-end',
342
+ };
343
+ break;
344
+ case 'top':
345
+ styles = {
346
+ display: 'flex',
347
+ height: height + 'px',
348
+ };
349
+ wrapperStyles = {
350
+ display: 'flex',
351
+ justifyContent: 'flex-start',
352
+ };
353
+ if (state.spotChecksMode === 'miniCard' && state.isCloseButtonEnabled) {
354
+ extraPaddingForMiniCardCloseButtonIfTopPosition = 30;
355
+ }
356
+ break;
357
+ case 'center':
358
+ styles = {
359
+ display: 'flex',
360
+ height: height + 'px',
361
+ };
362
+ wrapperStyles = {
363
+ display: 'flex',
364
+ justifyContent: 'center',
365
+ };
366
+ break;
367
+ default:
368
+ break;
369
+ }
370
+ }
371
+ return {
372
+ wrapperStyles: {
373
+ position: 'fixed',
374
+ width: '100%',
375
+ height: '100%',
376
+ top: '0',
377
+ left: '0',
378
+ backgroundColor: 'rgba(0, 0, 0, 0.3)',
379
+ zIndex: '99999999',
380
+ display: 'none',
381
+ flexDirection: 'column',
382
+ ...wrapperStyles
383
+ },
384
+ styles: {
385
+ display: 'none',
386
+ flexDirection: 'column',
387
+ paddingTop: extraPaddingForMiniCardCloseButtonIfTopPosition + 'px',
388
+ ...styles,
389
+ }
390
+ };
391
+ };
392
+ const closeSpotCheckAndHandleSurveyEnd = async () => {
393
+ await closeSpotCheck();
394
+ handleSurveyEnd();
395
+ };
396
+
397
+ class WebViewComponent {
398
+ sanitizer;
399
+ url = '';
400
+ webviewType = 'classic';
401
+ isMiniCard = false;
402
+ safeUrl = null;
403
+ iframe;
404
+ constructor(sanitizer) {
405
+ this.sanitizer = sanitizer;
406
+ }
407
+ ngOnInit() {
408
+ if (this.url) {
409
+ this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
410
+ }
411
+ }
412
+ ngAfterViewInit() {
413
+ const stateService = getSpotcheckStateService();
414
+ const webViewRef = this.iframe.nativeElement;
415
+ if (this.webviewType === 'classic') {
416
+ stateService.setState({
417
+ classicWebViewRef: webViewRef,
418
+ isClassicLoading: false,
419
+ });
420
+ }
421
+ else {
422
+ stateService.setState({
423
+ chatWebViewRef: webViewRef,
424
+ isChatLoading: false,
425
+ });
426
+ }
427
+ this.setupIframeLoadListener();
428
+ }
429
+ setupIframeLoadListener() {
430
+ const iframe = this.iframe.nativeElement;
431
+ iframe.addEventListener('load', () => {
432
+ const stateService = getSpotcheckStateService();
433
+ if (this.webviewType === 'classic') {
434
+ stateService.setState({ isClassicLoading: false });
435
+ }
436
+ else {
437
+ stateService.setState({ isChatLoading: false });
438
+ }
439
+ });
440
+ }
441
+ onMessage(event) {
442
+ const stateService = getSpotcheckStateService();
443
+ const { data } = event;
444
+ switch (data.type) {
445
+ case 'slideInFrame':
446
+ if (data.mounted) {
447
+ stateService.setState({ isMounted: true });
448
+ }
449
+ break;
450
+ case 'resizeWindow':
451
+ if (data.size) {
452
+ stateService.setState({
453
+ currentQuestionHeight: data.size.height,
454
+ });
455
+ }
456
+ else if (data.isCloseButtonEnabled) {
457
+ stateService.setState({
458
+ isCloseButtonEnabled: data.isCloseButtonEnabled,
459
+ });
460
+ }
461
+ break;
462
+ case 'surveyCompleted':
463
+ closeSpotCheckAndHandleSurveyEnd();
464
+ // spotchecksListener.emitSurveyCompleted(data.response);
465
+ break;
466
+ case 'surveyLoadStarted':
467
+ // spotchecksListener.emitSurveyLoadStarted(data.surveyDetails);
468
+ break;
469
+ default:
470
+ break;
471
+ }
472
+ }
473
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: WebViewComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
474
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: WebViewComponent, isStandalone: true, selector: "WebViewComponent", inputs: { url: "url", webviewType: "webviewType", isMiniCard: "isMiniCard" }, host: { listeners: { "window:message": "onMessage($event)" } }, viewQueries: [{ propertyName: "iframe", first: true, predicate: ["iframeRef"], descendants: true }], ngImport: i0, template: `
475
+ <div style="overflow: hidden; height: 100%; border-radius: {{isMiniCard ? 12 : 0}}px; padding-left: {{isMiniCard ? 12 : 0}}px; padding-right: {{isMiniCard ? 12 : 0}}px; box-sizing: border-box;">
476
+ <iframe
477
+ allow="camera; microphone; geolocation; display-capture; autoplay; clipboard-read; clipboard-write;"
478
+ #iframeRef
479
+ [src]="safeUrl"
480
+ style="width: 100%; height: 100%; display: block; border-radius: {{isMiniCard ? 12 : 0}}px;"
481
+ frameborder="0"
482
+ >
483
+ </iframe>
484
+ </div>
485
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
486
+ }
487
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: WebViewComponent, decorators: [{
488
+ type: Component,
489
+ args: [{
490
+ selector: 'WebViewComponent',
491
+ template: `
492
+ <div style="overflow: hidden; height: 100%; border-radius: {{isMiniCard ? 12 : 0}}px; padding-left: {{isMiniCard ? 12 : 0}}px; padding-right: {{isMiniCard ? 12 : 0}}px; box-sizing: border-box;">
493
+ <iframe
494
+ allow="camera; microphone; geolocation; display-capture; autoplay; clipboard-read; clipboard-write;"
495
+ #iframeRef
496
+ [src]="safeUrl"
497
+ style="width: 100%; height: 100%; display: block; border-radius: {{isMiniCard ? 12 : 0}}px;"
498
+ frameborder="0"
499
+ >
500
+ </iframe>
501
+ </div>
502
+ `,
503
+ standalone: true,
504
+ imports: [CommonModule],
505
+ }]
506
+ }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { url: [{
507
+ type: Input
508
+ }], webviewType: [{
509
+ type: Input
510
+ }], isMiniCard: [{
511
+ type: Input
512
+ }], iframe: [{
513
+ type: ViewChild,
514
+ args: ['iframeRef']
515
+ }], onMessage: [{
516
+ type: HostListener,
517
+ args: ['window:message', ['$event']]
518
+ }] } });
519
+ class CloseSVGComponent {
520
+ size = 32;
521
+ stroke = '#919191';
522
+ strokeWidth = 1.5;
523
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: CloseSVGComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
524
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: CloseSVGComponent, isStandalone: true, selector: "close-svg", inputs: { size: "size", stroke: "stroke", strokeWidth: "strokeWidth" }, ngImport: i0, template: `
525
+ <svg
526
+ [attr.width]="size"
527
+ [attr.height]="size"
528
+ viewBox="0 0 32 32"
529
+ fill="none"
530
+ xmlns="https://www.w3.org/2000/svg"
531
+ >
532
+ <path
533
+ d="M10.6665 10.667L21.3332 21.3337M21.3332 10.667L10.6665 21.3337"
534
+ [attr.stroke]="stroke"
535
+ [attr.stroke-width]="strokeWidth"
536
+ stroke-linecap="round"
537
+ stroke-linejoin="round"
538
+ />
539
+ </svg>
540
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
541
+ }
542
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: CloseSVGComponent, decorators: [{
543
+ type: Component,
544
+ args: [{
545
+ selector: 'close-svg',
546
+ template: `
547
+ <svg
548
+ [attr.width]="size"
549
+ [attr.height]="size"
550
+ viewBox="0 0 32 32"
551
+ fill="none"
552
+ xmlns="https://www.w3.org/2000/svg"
553
+ >
554
+ <path
555
+ d="M10.6665 10.667L21.3332 21.3337M21.3332 10.667L10.6665 21.3337"
556
+ [attr.stroke]="stroke"
557
+ [attr.stroke-width]="strokeWidth"
558
+ stroke-linecap="round"
559
+ stroke-linejoin="round"
560
+ />
561
+ </svg>
562
+ `,
563
+ standalone: true,
564
+ imports: [CommonModule],
565
+ }]
566
+ }], propDecorators: { size: [{
567
+ type: Input
568
+ }], stroke: [{
569
+ type: Input
570
+ }], strokeWidth: [{
571
+ type: Input
572
+ }] } });
573
+ class CloseButtonComponent {
574
+ size = 30;
575
+ strokeWidth = 1.2;
576
+ state;
577
+ stateService;
578
+ stateSubscription;
579
+ isVisible = false;
580
+ isMiniCard = false;
581
+ stroke = 'black';
582
+ constructor() {
583
+ this.stateService = getSpotcheckStateService();
584
+ this.state = this.stateService.getState();
585
+ this.updateComponentState();
586
+ this.stateSubscription = this.stateService.state$.subscribe((newState) => {
587
+ this.state = newState;
588
+ this.updateComponentState();
589
+ });
590
+ }
591
+ ngOnDestroy() {
592
+ if (this.stateSubscription) {
593
+ this.stateSubscription.unsubscribe();
594
+ }
595
+ }
596
+ updateComponentState() {
597
+ this.isVisible =
598
+ this.state.isCloseButtonEnabled &&
599
+ ((this.state.currentQuestionHeight > 0 && !this.state.isFullScreenMode) ||
600
+ (this.state.isFullScreenMode &&
601
+ ((!this.state.isClassicLoading &&
602
+ this.state.spotCheckType === 'classic') ||
603
+ (!this.state.isChatLoading &&
604
+ this.state.spotCheckType === 'chat'))));
605
+ this.isMiniCard = this.state.spotChecksMode === 'miniCard';
606
+ this.stroke = this.isMiniCard ? 'black' : this.state.closeButtonStyle?.['ctaButton'] || 'black';
607
+ }
608
+ onClick = async () => {
609
+ await closeSpotCheck();
610
+ handleSurveyEnd();
611
+ };
612
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: CloseButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
613
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: CloseButtonComponent, isStandalone: true, selector: "spotcheck-close-button", inputs: { size: "size", strokeWidth: "strokeWidth" }, ngImport: i0, template: `
614
+ <div style="position: absolute; top: -36px; right: 16px; z-index: 100001; cursor: pointer; background-color: white; border-radius: 50px;" (click)="onClick()" *ngIf="isVisible && isMiniCard">
615
+ <close-svg [size]="size" [stroke]="stroke" [strokeWidth]="strokeWidth" style="display: flex; align-items: center; justify-content: center;"/>
616
+ </div>
617
+ <div style="position: absolute; top: 16px; right: 16px; z-index: 100001; cursor: pointer;" (click)="onClick()" *ngIf="isVisible && !isMiniCard">
618
+ <close-svg [size]="size" [stroke]="stroke" [strokeWidth]="strokeWidth"/>
619
+ </div>
620
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CloseSVGComponent, selector: "close-svg", inputs: ["size", "stroke", "strokeWidth"] }] });
621
+ }
622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: CloseButtonComponent, decorators: [{
623
+ type: Component,
624
+ args: [{
625
+ selector: 'spotcheck-close-button',
626
+ template: `
627
+ <div style="position: absolute; top: -36px; right: 16px; z-index: 100001; cursor: pointer; background-color: white; border-radius: 50px;" (click)="onClick()" *ngIf="isVisible && isMiniCard">
628
+ <close-svg [size]="size" [stroke]="stroke" [strokeWidth]="strokeWidth" style="display: flex; align-items: center; justify-content: center;"/>
629
+ </div>
630
+ <div style="position: absolute; top: 16px; right: 16px; z-index: 100001; cursor: pointer;" (click)="onClick()" *ngIf="isVisible && !isMiniCard">
631
+ <close-svg [size]="size" [stroke]="stroke" [strokeWidth]="strokeWidth"/>
632
+ </div>
633
+ `,
634
+ standalone: true,
635
+ imports: [CommonModule, CloseSVGComponent],
636
+ }]
637
+ }], ctorParameters: () => [], propDecorators: { size: [{
638
+ type: Input
639
+ }], strokeWidth: [{
640
+ type: Input
641
+ }] } });
642
+ class SpotCheckComponent {
643
+ state;
644
+ spotcheckStateService;
645
+ stateSubscription;
646
+ componentStyles = {};
647
+ avatarUrl = '';
648
+ constructor() {
649
+ this.spotcheckStateService = getSpotcheckStateService();
650
+ this.state = this.spotcheckStateService.getState();
651
+ this.updateComponentStyles();
652
+ this.stateSubscription = this.spotcheckStateService.state$.subscribe((newState) => {
653
+ this.state = newState;
654
+ this.updateComponentStyles();
655
+ this.avatarUrl = this.state.avatarUrl || "https://static.surveysparrow.com/application/images/profile.png";
656
+ });
657
+ }
658
+ ngOnInit() {
659
+ this.initializeComponent();
660
+ }
661
+ ngOnDestroy() {
662
+ if (this.stateSubscription) {
663
+ this.stateSubscription.unsubscribe();
664
+ }
665
+ }
666
+ updateComponentStyles() {
667
+ this.componentStyles = getSpotcheckComponentCssStyles(this.state);
668
+ }
669
+ initializeComponent = async () => {
670
+ try {
671
+ const domainName = this.state.domainName;
672
+ const targetToken = this.state.targetToken;
673
+ const response = await axios.get(`https://${domainName}/api/internal/spotcheck/widget/${targetToken}/init`);
674
+ const data = response.data;
675
+ if (data.filteredSpotChecks && data.filteredSpotChecks.length > 0) {
676
+ let classicIframe = false;
677
+ let chatIframe = false;
678
+ data.filteredSpotChecks.forEach((spotcheck) => {
679
+ if (spotcheck.appearance.mode === 'fullScreen' &&
680
+ ischatSurvey(spotcheck?.survey?.surveyType)) {
681
+ chatIframe = true;
682
+ }
683
+ else {
684
+ classicIframe = true;
685
+ }
686
+ });
687
+ const newClassicUrl = classicIframe
688
+ ? `https://${domainName}/eui-template/classic`
689
+ : '';
690
+ const newChatUrl = chatIframe
691
+ ? `https://${domainName}/eui-template/chat`
692
+ : '';
693
+ this.spotcheckStateService.setState({
694
+ filteredSpotChecks: data.filteredSpotChecks,
695
+ classicUrl: newClassicUrl,
696
+ chatUrl: newChatUrl,
697
+ });
698
+ }
699
+ }
700
+ catch (error) {
701
+ console.log('Error initializing widget:', JSON.stringify(error));
702
+ }
703
+ };
704
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotCheckComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: SpotCheckComponent, isStandalone: true, selector: "SpotCheckComponent", ngImport: i0, template: "<div [ngStyle]=\"componentStyles.wrapperStyles\" class=\"safe-area\">\n <div [ngStyle]=\"componentStyles.styles\">\n <div style=\"position: relative; height: 100%;\">\n <spotcheck-close-button />\n \n <WebViewComponent\n *ngIf=\"state.classicUrl && state.classicUrl.length > 0 && state.spotcheckURL.length > 0 && state.spotCheckType === 'classic'\"\n [url]=\"state.classicUrl\"\n [webviewType]=\"'classic'\"\n [isMiniCard]=\"state.spotChecksMode === 'miniCard'\"\n />\n \n <WebViewComponent\n *ngIf=\"state.chatUrl && state.chatUrl.length > 0 && state.spotcheckURL.length > 0 && state.spotCheckType === 'chat'\"\n [url]=\"state.chatUrl\"\n [webviewType]=\"'chat'\"\n [isMiniCard]=\"state.spotChecksMode === 'miniCard'\"\n />\n\n <div *ngIf=\"state.spotChecksMode === 'miniCard' && state.avatarEnabled\">\n <div style=\"position: absolute; bottom: -66px; left: 16px; z-index: 100001;\">\n <img [src]=\"avatarUrl\" style=\"width: 56px; height: 56px; border-radius: 50px; background-color: white;\"/>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".safe-area{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);box-sizing:border-box}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: WebViewComponent, selector: "WebViewComponent", inputs: ["url", "webviewType", "isMiniCard"] }, { kind: "component", type: CloseButtonComponent, selector: "spotcheck-close-button", inputs: ["size", "strokeWidth"] }] });
706
+ }
707
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotCheckComponent, decorators: [{
708
+ type: Component,
709
+ args: [{ selector: 'SpotCheckComponent', standalone: true, imports: [CommonModule, WebViewComponent, CloseButtonComponent], template: "<div [ngStyle]=\"componentStyles.wrapperStyles\" class=\"safe-area\">\n <div [ngStyle]=\"componentStyles.styles\">\n <div style=\"position: relative; height: 100%;\">\n <spotcheck-close-button />\n \n <WebViewComponent\n *ngIf=\"state.classicUrl && state.classicUrl.length > 0 && state.spotcheckURL.length > 0 && state.spotCheckType === 'classic'\"\n [url]=\"state.classicUrl\"\n [webviewType]=\"'classic'\"\n [isMiniCard]=\"state.spotChecksMode === 'miniCard'\"\n />\n \n <WebViewComponent\n *ngIf=\"state.chatUrl && state.chatUrl.length > 0 && state.spotcheckURL.length > 0 && state.spotCheckType === 'chat'\"\n [url]=\"state.chatUrl\"\n [webviewType]=\"'chat'\"\n [isMiniCard]=\"state.spotChecksMode === 'miniCard'\"\n />\n\n <div *ngIf=\"state.spotChecksMode === 'miniCard' && state.avatarEnabled\">\n <div style=\"position: absolute; bottom: -66px; left: 16px; z-index: 100001;\">\n <img [src]=\"avatarUrl\" style=\"width: 56px; height: 56px; border-radius: 50px; background-color: white;\"/>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".safe-area{padding-top:env(safe-area-inset-top);padding-bottom:env(safe-area-inset-bottom);padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);box-sizing:border-box}\n"] }]
710
+ }], ctorParameters: () => [] });
711
+
712
+ class SpotCheck {
713
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotCheck, deps: [], target: i0.ɵɵFactoryTarget.Component });
714
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: SpotCheck, isStandalone: true, selector: "SpotCheck", ngImport: i0, template: `<SpotCheckComponent />`, isInline: true, dependencies: [{ kind: "component", type: SpotCheckComponent, selector: "SpotCheckComponent" }] });
715
+ }
716
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: SpotCheck, decorators: [{
717
+ type: Component,
718
+ args: [{
719
+ selector: 'SpotCheck',
720
+ template: `<SpotCheckComponent />`,
721
+ standalone: true,
722
+ imports: [SpotCheckComponent],
723
+ }]
724
+ }] });
725
+
726
+ const getStoredUUID = () => {
727
+ return localStorage.getItem('SurveySparrowUUID') || null;
728
+ };
729
+ const setUUID = (uuid) => {
730
+ localStorage.setItem('SurveySparrowUUID', uuid);
731
+ };
732
+
733
+ const sendTrackScreenRequest = async ({ screen, options, }) => {
734
+ try {
735
+ const spotcheckStateService = getSpotcheckStateService();
736
+ const oldState = spotcheckStateService.getState();
737
+ let variables = { ...oldState.variables };
738
+ let customProperties = { ...oldState.customProperties };
739
+ let userDetails = { ...oldState.userDetails };
740
+ if (options && options.variables && Object.keys(options.variables).length > 0) {
741
+ variables = { ...variables, ...options.variables };
742
+ }
743
+ if (options && options.customProperties && Object.keys(options.customProperties).length > 0) {
744
+ customProperties = { ...customProperties, ...options.customProperties };
745
+ }
746
+ if (options && options.userDetails && Object.keys(options.userDetails).length > 0) {
747
+ userDetails = { ...userDetails, ...options.userDetails };
748
+ }
749
+ let traceId = oldState.traceId;
750
+ if (!traceId) {
751
+ traceId = generateTraceId();
752
+ }
753
+ if (!userDetails.uuid && !userDetails.email && !userDetails.mobile) {
754
+ const uuid = getStoredUUID();
755
+ if (uuid) {
756
+ userDetails.uuid = uuid;
757
+ }
758
+ }
759
+ spotcheckStateService.setState({
760
+ traceId,
761
+ screenwiseUserDetails: {
762
+ [screen]: userDetails
763
+ },
764
+ });
765
+ const state = spotcheckStateService.getState();
766
+ let { isSpotPassed, isChecksPassed } = state;
767
+ const payload = {
768
+ screenName: screen,
769
+ variables: variables,
770
+ userDetails: userDetails,
771
+ visitor: {
772
+ deviceType: 'MOBILE',
773
+ operatingSystem: await getOS(),
774
+ screenResolution: {
775
+ height: window.innerHeight,
776
+ width: window.innerWidth,
777
+ },
778
+ currentDate: new Date().toISOString(),
779
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
780
+ },
781
+ traceId: state.traceId,
782
+ customProperties: customProperties,
783
+ };
784
+ const url = `https://${state.domainName}/api/internal/spotcheck/widget/${state.targetToken}/properties?isSpotCheck=true`;
785
+ const response = await axios.post(url, payload, {
786
+ headers: {
787
+ 'Content-Type': 'application/json',
788
+ },
789
+ });
790
+ if (response.status === 200) {
791
+ const responseJson = response.data;
792
+ if (responseJson.uuid) {
793
+ setUUID(responseJson.uuid);
794
+ }
795
+ if (responseJson?.show) {
796
+ if (responseJson?.show) {
797
+ const appearance_response = await setAppearance(responseJson, screen, state.domainName, traceId, variables);
798
+ if (appearance_response) {
799
+ isSpotPassed = true;
800
+ spotcheckStateService.setState({ isSpotPassed });
801
+ return { valid: true };
802
+ }
803
+ }
804
+ else {
805
+ throw new Error('');
806
+ }
807
+ }
808
+ if (!isSpotPassed && responseJson?.checkPassed) {
809
+ if (responseJson.checkCondition) {
810
+ const checkCondition = responseJson.checkCondition;
811
+ spotcheckStateService.setState({ afterDelay: checkCondition.afterDelay || 0 });
812
+ if (checkCondition.customEvent) {
813
+ spotcheckStateService.setState({ customEventsSpotChecks: [responseJson] });
814
+ throw new Error('');
815
+ }
816
+ }
817
+ const appearance_response = await setAppearance(responseJson, screen, state.domainName, traceId, variables);
818
+ if (appearance_response) {
819
+ isChecksPassed = true;
820
+ spotcheckStateService.setState({ isChecksPassed });
821
+ return { valid: true };
822
+ }
823
+ }
824
+ if (!isSpotPassed && !isChecksPassed && responseJson?.multiShow != null) {
825
+ if (responseJson.multiShow) {
826
+ spotcheckStateService.setState({ customEventsSpotChecks: responseJson.resultantSpotCheck });
827
+ let selectedSpotCheck = {};
828
+ let minDelay = Number.POSITIVE_INFINITY;
829
+ for (const spotcheck of responseJson.resultantSpotCheck) {
830
+ const checks = spotcheck?.checks || {};
831
+ if (Object.keys(checks).length === 0) {
832
+ minDelay = 0;
833
+ selectedSpotCheck = spotcheck;
834
+ }
835
+ else if (checks.afterDelay != null) {
836
+ const delay = parseFloat(checks.afterDelay);
837
+ if (minDelay > delay) {
838
+ minDelay = delay;
839
+ selectedSpotCheck = spotcheck;
840
+ }
841
+ }
842
+ }
843
+ if (Object.keys(selectedSpotCheck).length > 0) {
844
+ spotcheckStateService.setState({ afterDelay: minDelay });
845
+ const appearance_response = await setAppearance(selectedSpotCheck, screen, state.domainName, traceId, variables);
846
+ if (appearance_response) {
847
+ return { valid: true };
848
+ }
849
+ }
850
+ }
851
+ }
852
+ throw new Error(responseJson?.reason.toString());
853
+ }
854
+ else {
855
+ throw new Error(`Received status code ${response.status}`);
856
+ }
857
+ }
858
+ catch (error) {
859
+ return { valid: false, error: error.message };
860
+ }
861
+ };
862
+ const sendTrackEventRequest = async ({ screen, event }) => {
863
+ try {
864
+ const intMax = Number.POSITIVE_INFINITY;
865
+ const state = getSpotcheckStateService().getState();
866
+ let selectedSpotCheckID = intMax;
867
+ let { isSpotPassed } = state;
868
+ if (state.customEventsSpotChecks.length > 0) {
869
+ const eventKeys = Object.keys(event);
870
+ for (const spotCheck of state.customEventsSpotChecks) {
871
+ const checks = spotCheck?.['checks'] ?? spotCheck?.['checkCondition'];
872
+ if (checks) {
873
+ const customEvent = checks?.customEvent;
874
+ if (eventKeys.includes(customEvent?.eventName)) {
875
+ selectedSpotCheckID =
876
+ spotCheck?.['id'] ?? spotCheck?.['spotCheckId'] ?? intMax;
877
+ if (selectedSpotCheckID !== intMax) {
878
+ const payload = {
879
+ screenName: screen,
880
+ variables: state.variables,
881
+ userDetails: state.screenwiseUserDetails[screen] || {},
882
+ visitor: {
883
+ deviceType: 'MOBILE',
884
+ operatingSystem: await getOS(),
885
+ screenResolution: {
886
+ height: window.innerHeight,
887
+ width: window.innerWidth,
888
+ },
889
+ currentDate: new Date().toISOString(),
890
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
891
+ },
892
+ spotCheckId: selectedSpotCheckID,
893
+ eventTrigger: {
894
+ customEvent: event,
895
+ },
896
+ traceId: state.traceId,
897
+ customProperties: state.customProperties,
898
+ };
899
+ const url = `https://${state.domainName}/api/internal/spotcheck/widget/${state.targetToken}/eventTrigger?isSpotCheck=true`;
900
+ try {
901
+ const response = await axios.post(url, payload, {
902
+ headers: {
903
+ 'Content-Type': 'application/json',
904
+ },
905
+ });
906
+ if (response.status === 200) {
907
+ const responseJson = response.data;
908
+ if (responseJson?.show != null) {
909
+ if (responseJson?.show) {
910
+ const appearance_response = await setAppearance(responseJson, screen, state.domainName, state.traceId, state.variables);
911
+ if (appearance_response) {
912
+ getSpotcheckStateService().setState({ isSpotPassed: true });
913
+ isSpotPassed = true;
914
+ return { valid: true };
915
+ }
916
+ }
917
+ }
918
+ if (!isSpotPassed && responseJson?.eventShow) {
919
+ if (responseJson?.checkCondition != null) {
920
+ const checkCondition = responseJson?.checkCondition;
921
+ getSpotcheckStateService().setState({
922
+ afterDelay: checkCondition?.afterDelay ?? 0,
923
+ });
924
+ if (checkCondition?.customEvent != null) {
925
+ getSpotcheckStateService().setState({
926
+ afterDelay: checkCondition?.customEvent?.delayInSeconds ?? 0,
927
+ });
928
+ }
929
+ }
930
+ const appearance_response = await setAppearance(responseJson, screen, state.domainName, state.traceId, state.variables);
931
+ if (appearance_response) {
932
+ return { valid: true };
933
+ }
934
+ }
935
+ throw new Error(responseJson?.reason.toString());
936
+ }
937
+ else {
938
+ throw new Error(`Received status code ${response.status}`);
939
+ }
940
+ }
941
+ catch (error) {
942
+ throw new Error(error.message);
943
+ }
944
+ }
945
+ }
946
+ }
947
+ }
948
+ throw new Error('');
949
+ }
950
+ else {
951
+ throw new Error('');
952
+ }
953
+ }
954
+ catch (error) {
955
+ return { valid: false, error: error.message };
956
+ }
957
+ };
958
+
959
+ const initializeSpotChecks = ({ domainName, targetToken, userDetails = {}, variables = {}, customProperties = {}, }) => {
960
+ const spotcheckStateService = getSpotcheckStateService();
961
+ spotcheckStateService.setState({
962
+ domainName,
963
+ targetToken,
964
+ userDetails,
965
+ variables,
966
+ customProperties,
967
+ });
968
+ };
969
+ const trackScreen = async ({ screen, options }) => {
970
+ try {
971
+ const response = await sendTrackScreenRequest({ screen, options });
972
+ if (response.valid) {
973
+ console.log('Screen Tracking succeeded.');
974
+ }
975
+ else {
976
+ if ('error' in response) {
977
+ throw new Error(response.error.toString());
978
+ }
979
+ else {
980
+ throw new Error('Tracking failed without an explicit error.');
981
+ }
982
+ }
983
+ }
984
+ catch (error) {
985
+ console.log(`Screen Tracking Failed. ${error.message}`);
986
+ }
987
+ };
988
+ const trackEvent = async ({ screen, event }) => {
989
+ try {
990
+ const response = await sendTrackEventRequest({ screen, event });
991
+ if (response.valid) {
992
+ console.log('TrackEvent succeeded.');
993
+ }
994
+ else {
995
+ if ('error' in response) {
996
+ throw new Error(response.error.toString());
997
+ }
998
+ else {
999
+ throw new Error('Tracking failed without an explicit error.');
1000
+ }
1001
+ }
1002
+ }
1003
+ catch (error) {
1004
+ console.log(`Event Tracking Failed. ${error.message}`);
1005
+ }
1006
+ };
1007
+
1008
+ /**
1009
+ * Generated bundle index. Do not edit.
1010
+ */
1011
+
1012
+ export { SpotCheck, initializeSpotChecks, trackEvent, trackScreen };
1013
+ //# sourceMappingURL=angular-ui.mjs.map