surveysparrow-ionic-plugin 2.0.2-beta.1 → 2.0.2-beta.2

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 (44) hide show
  1. package/dist/angular-ui/esm2022/spotchecks/SpotCheckComponent.mjs +81 -100
  2. package/dist/angular-ui/esm2022/spotchecks/SpotCheckEventListener.mjs +26 -0
  3. package/dist/angular-ui/esm2022/spotchecks/SpotcheckStateService.mjs +1 -3
  4. package/dist/angular-ui/esm2022/spotchecks/api.mjs +3 -3
  5. package/dist/angular-ui/esm2022/spotchecks/helpers.mjs +14 -18
  6. package/dist/angular-ui/esm2022/spotchecks/index.mjs +2 -1
  7. package/dist/angular-ui/esm2022/spotchecks/types.mjs +1 -1
  8. package/dist/angular-ui/fesm2022/angular-ui.mjs +120 -122
  9. package/dist/angular-ui/fesm2022/angular-ui.mjs.map +1 -1
  10. package/dist/angular-ui/spotchecks/SpotCheckComponent.d.ts +10 -5
  11. package/dist/angular-ui/spotchecks/SpotCheckEventListener.d.ts +16 -0
  12. package/dist/angular-ui/spotchecks/helpers.d.ts +1 -2
  13. package/dist/angular-ui/spotchecks/index.d.ts +1 -0
  14. package/dist/angular-ui/spotchecks/types.d.ts +0 -2
  15. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckComponent.d.ts +10 -5
  16. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckComponent.js +75 -95
  17. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckComponent.js.map +1 -1
  18. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckEventListener.d.ts +16 -0
  19. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckEventListener.js +28 -0
  20. package/dist/esm/angular-ui/lib/spotchecks/SpotCheckEventListener.js.map +1 -0
  21. package/dist/esm/angular-ui/lib/spotchecks/SpotcheckStateService.js +0 -2
  22. package/dist/esm/angular-ui/lib/spotchecks/SpotcheckStateService.js.map +1 -1
  23. package/dist/esm/angular-ui/lib/spotchecks/api.js +3 -4
  24. package/dist/esm/angular-ui/lib/spotchecks/api.js.map +1 -1
  25. package/dist/esm/angular-ui/lib/spotchecks/helpers.d.ts +1 -2
  26. package/dist/esm/angular-ui/lib/spotchecks/helpers.js +15 -18
  27. package/dist/esm/angular-ui/lib/spotchecks/helpers.js.map +1 -1
  28. package/dist/esm/angular-ui/lib/spotchecks/index.d.ts +1 -0
  29. package/dist/esm/angular-ui/lib/spotchecks/index.js +1 -0
  30. package/dist/esm/angular-ui/lib/spotchecks/index.js.map +1 -1
  31. package/dist/esm/angular-ui/lib/spotchecks/types.d.ts +0 -2
  32. package/dist/esm/angular-ui/lib/spotchecks/types.js.map +1 -1
  33. package/dist/plugin.cjs.js +116 -116
  34. package/dist/plugin.cjs.js.map +1 -1
  35. package/dist/plugin.js +116 -116
  36. package/dist/plugin.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/angular-ui/lib/spotchecks/SpotCheckComponent.ts +76 -98
  39. package/src/angular-ui/lib/spotchecks/SpotCheckEventListener.ts +50 -0
  40. package/src/angular-ui/lib/spotchecks/SpotcheckStateService.ts +0 -2
  41. package/src/angular-ui/lib/spotchecks/api.ts +4 -4
  42. package/src/angular-ui/lib/spotchecks/helpers.ts +14 -23
  43. package/src/angular-ui/lib/spotchecks/index.ts +3 -0
  44. package/src/angular-ui/lib/spotchecks/types.ts +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "surveysparrow-ionic-plugin",
3
- "version": "2.0.2-beta.1",
3
+ "version": "2.0.2-beta.2",
4
4
  "description": "SurveySparrow SDK enables you to collect feedback from your mobile app. Embed the Classic, Chat & NPS surveys in your ionic application seamlessly with few lines of code.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.cjs.js",
@@ -7,6 +7,8 @@ import {
7
7
  ElementRef,
8
8
  AfterViewInit,
9
9
  HostListener,
10
+ NgZone,
11
+ ChangeDetectorRef,
10
12
  } from '@angular/core';
11
13
  import { CommonModule } from '@angular/common';
12
14
  import { Subscription } from 'rxjs';
@@ -15,6 +17,7 @@ import { closeSpotCheck, closeSpotCheckAndHandleSurveyEnd, getSpotcheckComponent
15
17
  import { SpotcheckState } from './types';
16
18
  import { getSpotcheckStateService } from './helpers';
17
19
  import { SpotcheckStateService } from './SpotcheckStateService';
20
+ import { getSpotCheckEventListener } from './SpotCheckEventListener';
18
21
  import axios from 'axios';
19
22
 
20
23
  @Component({
@@ -22,8 +25,7 @@ import axios from 'axios';
22
25
  template: `
23
26
  <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;">
24
27
  <iframe
25
- allow="camera; microphone; geolocation; display-capture; autoplay; clipboard-read; clipboard-write; fullscreen"
26
- allowfullscreen
28
+ allow="camera; microphone; geolocation; display-capture; autoplay; clipboard-read; clipboard-write;"
27
29
  #iframeRef
28
30
  [src]="safeUrl"
29
31
  style="width: 100%; height: 100%; display: block; border-radius: {{isMiniCard ? 12 : 0}}px;"
@@ -43,7 +45,11 @@ export class WebViewComponent implements OnInit, AfterViewInit {
43
45
  safeUrl: SafeResourceUrl | null = null;
44
46
  @ViewChild('iframeRef') iframe!: ElementRef<HTMLIFrameElement>;
45
47
 
46
- constructor(private sanitizer: DomSanitizer) {}
48
+ constructor(
49
+ private sanitizer: DomSanitizer,
50
+ private ngZone: NgZone,
51
+ private cdr: ChangeDetectorRef,
52
+ ) {}
47
53
  ngOnInit() {
48
54
  if (this.url) {
49
55
  this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
@@ -71,102 +77,57 @@ export class WebViewComponent implements OnInit, AfterViewInit {
71
77
  private setupIframeLoadListener() {
72
78
  const iframe = this.iframe.nativeElement;
73
79
  iframe.addEventListener('load', () => {
74
- this.injectNativeBridgeAdapters(iframe);
75
- const stateService = getSpotcheckStateService();
76
- if (this.webviewType === 'classic') {
77
- stateService.setState({ isClassicLoading: false });
78
- } else {
79
- stateService.setState({ isChatLoading: false });
80
- }
81
- });
82
- }
83
-
84
- private injectNativeBridgeAdapters(iframe: HTMLIFrameElement) {
85
- if (iframe && iframe.contentWindow) {
86
- try {
87
- const iframeWindow = iframe.contentWindow as any;
88
-
89
- if (!iframeWindow.SsAndroidSdk) {
90
- iframeWindow.SsAndroidSdk = {
91
- shareData: function() {},
92
- sendPartialSubmissionData: function() {}
93
- };
94
- }
95
-
96
- if (!iframeWindow.Android) {
97
- iframeWindow.Android = {
98
- onMessageReceive: function() {}
99
- };
100
- }
101
-
102
- if (!iframeWindow.webkit) {
103
- iframeWindow.webkit = {
104
- messageHandlers: {
105
- surveyResponse: {
106
- postMessage: function() {}
107
- },
108
- spotCheckData: {
109
- postMessage: function() {}
110
- },
111
- flutterSpotCheckData: {
112
- postMessage: function() {}
113
- }
114
- }
115
- };
116
- }
117
-
118
- if (!iframeWindow.flutterSpotCheckData) {
119
- iframeWindow.flutterSpotCheckData = {
120
- postMessage: function() {}
121
- };
80
+ this.ngZone.run(() => {
81
+ const stateService = getSpotcheckStateService();
82
+ if (this.webviewType === 'classic') {
83
+ stateService.setState({ isClassicLoading: false });
84
+ } else {
85
+ stateService.setState({ isChatLoading: false });
122
86
  }
123
- } catch (error) {}
124
- }
87
+ });
88
+ });
125
89
  }
126
90
 
127
91
  @HostListener('window:message', ['$event'])
128
92
  onMessage(event: MessageEvent) {
129
- const stateService = getSpotcheckStateService();
130
- const { data } = event;
131
- switch (data.type) {
132
- case 'slideInFrame':
133
- if (data.mounted) {
134
- stateService.setState({ isMounted: true });
135
- }
136
- break;
93
+ this.ngZone.run(() => {
94
+ const stateService = getSpotcheckStateService();
95
+ const { data } = event;
96
+ switch (data.type) {
97
+ case 'slideInFrame':
98
+ if (data.mounted) {
99
+ stateService.setState({ isMounted: true });
100
+ }
101
+ break;
102
+
103
+ case 'resizeWindow':
104
+ if (data.size) {
105
+ stateService.setState({
106
+ currentQuestionHeight: data.size.height,
107
+ });
108
+ } else if (data.isCloseButtonEnabled) {
109
+ stateService.setState({
110
+ isCloseButtonEnabled: data.isCloseButtonEnabled,
111
+ });
112
+ }
113
+ break;
137
114
 
138
- case 'resizeWindow':
139
- if (data.size) {
140
- stateService.setState({
141
- currentQuestionHeight: data.size.height,
142
- });
143
- } else if (data.isCloseButtonEnabled) {
144
- stateService.setState({
145
- isCloseButtonEnabled: data.isCloseButtonEnabled,
115
+ case 'surveyCompleted':
116
+ closeSpotCheckAndHandleSurveyEnd().then(() => {
117
+ getSpotCheckEventListener().emit('surveyCompleted', data.response);
118
+ this.cdr.detectChanges();
146
119
  });
147
- }
148
- break;
149
-
150
- case 'surveyCompleted':
151
- closeSpotCheckAndHandleSurveyEnd();
152
- // spotchecksListener.emitSurveyCompleted(data.response);
153
- break;
154
-
155
- case 'surveyLoadStarted':
156
- // spotchecksListener.emitSurveyLoadStarted(data.surveyDetails);
157
- break;
158
-
159
- case 'classicLoadEvent':
160
- stateService.setState({ isClassicLoadEventReceived: true });
161
- break;
120
+ break;
162
121
 
163
- case 'chatLoadEvent':
164
- stateService.setState({ isChatLoadEventReceived: true });
165
- break;
122
+ case 'surveyLoadStarted':
123
+ getSpotCheckEventListener().emit('surveyLoadStarted', data.surveyDetails);
124
+ break;
166
125
 
167
- default:
168
- break;
169
- }
126
+ default:
127
+ break;
128
+ }
129
+ this.cdr.detectChanges();
130
+ });
170
131
  }
171
132
  }
172
133
 
@@ -223,15 +184,21 @@ export class CloseButtonComponent implements OnDestroy {
223
184
  isMiniCard: boolean = false;
224
185
  stroke: string = 'black';
225
186
 
226
- constructor() {
187
+ constructor(
188
+ private ngZone: NgZone,
189
+ private cdr: ChangeDetectorRef,
190
+ ) {
227
191
  this.stateService = getSpotcheckStateService();
228
192
  this.state = this.stateService.getState();
229
193
  this.updateComponentState();
230
194
 
231
195
  this.stateSubscription = this.stateService.state$.subscribe(
232
196
  (newState: SpotcheckState) => {
233
- this.state = newState;
234
- this.updateComponentState();
197
+ this.ngZone.run(() => {
198
+ this.state = newState;
199
+ this.updateComponentState();
200
+ this.cdr.detectChanges();
201
+ });
235
202
  }
236
203
  );
237
204
  }
@@ -258,6 +225,9 @@ export class CloseButtonComponent implements OnDestroy {
258
225
  onClick = async () => {
259
226
  await closeSpotCheck();
260
227
  handleSurveyEnd();
228
+ this.ngZone.run(() => {
229
+ this.cdr.detectChanges();
230
+ });
261
231
  };
262
232
  }
263
233
 
@@ -276,16 +246,22 @@ export class SpotCheckComponent implements OnInit, OnDestroy {
276
246
  componentStyles: any = {};
277
247
  avatarUrl: string = '';
278
248
 
279
- constructor() {
249
+ constructor(
250
+ private ngZone: NgZone,
251
+ private cdr: ChangeDetectorRef,
252
+ ) {
280
253
  this.spotcheckStateService = getSpotcheckStateService();
281
254
  this.state = this.spotcheckStateService.getState();
282
255
  this.updateComponentStyles();
283
256
 
284
257
  this.stateSubscription = this.spotcheckStateService.state$.subscribe(
285
258
  (newState: SpotcheckState) => {
286
- this.state = newState;
287
- this.updateComponentStyles();
288
- this.avatarUrl = this.state.avatarUrl || "https://static.surveysparrow.com/application/images/profile.png";
259
+ this.ngZone.run(() => {
260
+ this.state = newState;
261
+ this.updateComponentStyles();
262
+ this.avatarUrl = this.state.avatarUrl || "https://static.surveysparrow.com/application/images/profile.png";
263
+ this.cdr.detectChanges();
264
+ });
289
265
  }
290
266
  );
291
267
  }
@@ -308,9 +284,11 @@ export class SpotCheckComponent implements OnInit, OnDestroy {
308
284
  try {
309
285
  const domainName = this.state.domainName;
310
286
  const targetToken = this.state.targetToken;
311
- const response = await axios.get(
287
+
288
+ const response = await axios.get<any>(
312
289
  `https://${domainName}/api/internal/spotcheck/widget/${targetToken}/init`
313
290
  );
291
+
314
292
  const data = response.data;
315
293
 
316
294
  if (data.filteredSpotChecks && data.filteredSpotChecks.length > 0) {
@@ -0,0 +1,50 @@
1
+ import { Subject } from 'rxjs';
2
+ import type { Subscription } from 'rxjs';
3
+
4
+ export type SpotCheckEventType =
5
+ | 'surveyCompleted'
6
+ | 'surveyDismissed'
7
+ | 'surveyLoadStarted';
8
+
9
+ export interface SpotCheckEvent {
10
+ type: SpotCheckEventType;
11
+ data?: any;
12
+ }
13
+
14
+ type EventCallback = (data?: any) => void;
15
+
16
+ class SpotCheckEventListenerService {
17
+ private eventSubject = new Subject<SpotCheckEvent>();
18
+ private event$ = this.eventSubject.asObservable();
19
+
20
+ emit(type: SpotCheckEventType, data?: any): void {
21
+ this.eventSubject.next({ type, data });
22
+ }
23
+
24
+ addListener(
25
+ eventType: SpotCheckEventType,
26
+ callback: EventCallback
27
+ ): Subscription {
28
+ return this.event$.subscribe((event: SpotCheckEvent) => {
29
+ if (event.type === eventType) {
30
+ callback(event.data);
31
+ }
32
+ });
33
+ }
34
+ }
35
+
36
+ let globalInstance: SpotCheckEventListenerService;
37
+
38
+ export const getSpotCheckEventListener = (): SpotCheckEventListenerService => {
39
+ if (!globalInstance) {
40
+ globalInstance = new SpotCheckEventListenerService();
41
+ }
42
+ return globalInstance;
43
+ };
44
+
45
+ export const addSpotCheckListener = (
46
+ eventType: SpotCheckEventType,
47
+ callback: EventCallback
48
+ ): Subscription => {
49
+ return getSpotCheckEventListener().addListener(eventType, callback);
50
+ };
@@ -31,8 +31,6 @@ export class SpotcheckStateService {
31
31
  traceId: '',
32
32
  isClassicLoading: true,
33
33
  isChatLoading: true,
34
- isClassicLoadEventReceived: false,
35
- isChatLoadEventReceived: false,
36
34
  classicUrl: '',
37
35
  chatUrl: '',
38
36
  classicWebViewRef: null,
@@ -65,7 +65,7 @@ export const sendTrackScreenRequest = async ({
65
65
  };
66
66
 
67
67
  const url = `https://${state.domainName}/api/internal/spotcheck/widget/${state.targetToken}/properties?isSpotCheck=true&sdk=IONIC`;
68
- const response = await axios.post(url, payload, {
68
+ const response = await axios.post<any>(url, payload, {
69
69
  headers: {
70
70
  'Content-Type': 'application/json',
71
71
  },
@@ -158,7 +158,7 @@ export const sendTrackScreenRequest = async ({
158
158
  }
159
159
  }
160
160
 
161
- throw new Error(responseJson?.reason?.toString() ?? 'Spotcheck conditions not met');
161
+ throw new Error(responseJson?.reason.toString());
162
162
  } else {
163
163
  throw new Error(`Received status code ${response.status}`);
164
164
  }
@@ -212,7 +212,7 @@ export const sendTrackEventRequest = async ({ screen, event }: TrackEventProps)
212
212
  const url = `https://${state.domainName}/api/internal/spotcheck/widget/${state.targetToken}/eventTrigger?isSpotCheck=true`;
213
213
 
214
214
  try {
215
- const response = await axios.post(url, payload, {
215
+ const response = await axios.post<any>(url, payload, {
216
216
  headers: {
217
217
  'Content-Type': 'application/json',
218
218
  },
@@ -265,7 +265,7 @@ export const sendTrackEventRequest = async ({ screen, event }: TrackEventProps)
265
265
  }
266
266
  }
267
267
 
268
- throw new Error(responseJson?.reason?.toString() ?? 'Event conditions not met');
268
+ throw new Error(responseJson?.reason.toString());
269
269
  } else {
270
270
  throw new Error(`Received status code ${response.status}`);
271
271
  }
@@ -3,9 +3,9 @@ import { Device } from '@capacitor/device';
3
3
  import { SpotcheckState } from './types';
4
4
  import axios from 'axios';
5
5
  import { SpotcheckStateService } from './SpotcheckStateService';
6
+ import { getSpotCheckEventListener } from './SpotCheckEventListener';
6
7
 
7
8
  let globalSpotcheckStateService: SpotcheckStateService;
8
- let globalOS: string | null = null;
9
9
 
10
10
  export const getSpotcheckStateService = (): SpotcheckStateService => {
11
11
  if (!globalSpotcheckStateService) {
@@ -31,8 +31,7 @@ export const ischatSurvey = (type: String) => {
31
31
 
32
32
  export const getOS = async () => {
33
33
  const info = await Device.getInfo();
34
- globalOS = info.operatingSystem;
35
- return globalOS;
34
+ return info.operatingSystem;
36
35
  };
37
36
 
38
37
  export const setAppearance = async (
@@ -122,13 +121,13 @@ export const setAppearance = async (
122
121
  spotcheckStateService.setState(updatedState);
123
122
 
124
123
  try {
125
- const response = await axios.get(fullSpotcheckURL);
126
- const themeInfo = response.data?.config?.generatedCSS;
124
+ const response = await axios.get<any>(fullSpotcheckURL);
125
+ const themeInfo = response.data.config.generatedCSS;
127
126
  const theme_payload = { type: 'THEME_UPDATE_SPOTCHECK', themeInfo };
128
127
  state = spotcheckStateService.getState();
129
128
 
130
129
  let webViewRef = chat ? state.chatWebViewRef : state.classicWebViewRef;
131
- let isLoading = chat ? state.isChatLoading || !state.isChatLoadEventReceived : state.isClassicLoading || !state.isClassicLoadEventReceived;
130
+ let isLoading = chat ? state.isChatLoading : state.isClassicLoading;
132
131
 
133
132
  const resetStateData = {
134
133
  type: 'RESET_STATE',
@@ -179,12 +178,9 @@ export const setAppearance = async (
179
178
  isClassicLoading,
180
179
  chatWebViewRef,
181
180
  classicWebViewRef,
182
- isClassicLoadEventReceived,
183
- isChatLoadEventReceived,
184
181
  } = currentState;
185
182
 
186
-
187
- if ((!isChatLoading && chat && isChatLoadEventReceived) || (!isClassicLoading && !chat && isClassicLoadEventReceived)) {
183
+ if ((!isChatLoading && chat) || (!isClassicLoading && !chat)) {
188
184
  unsubscribe.unsubscribe();
189
185
  const activeWebViewRef = chat
190
186
  ? chatWebViewRef
@@ -209,8 +205,8 @@ export const setAppearance = async (
209
205
  ? currentState.chatWebViewRef
210
206
  : currentState.classicWebViewRef;
211
207
  const updatedIsLoading = chat
212
- ? currentState.isChatLoading || !currentState.isChatLoadEventReceived
213
- : currentState.isClassicLoading || !currentState.isClassicLoadEventReceived;
208
+ ? currentState.isChatLoading
209
+ : currentState.isClassicLoading;
214
210
 
215
211
  if (updatedWebViewRef) {
216
212
  if (!updatedIsLoading) {
@@ -261,8 +257,10 @@ export const closeSpotCheck = async () => {
261
257
  body: JSON.stringify(payload),
262
258
  }
263
259
  );
264
-
265
- if (response.status != 200) {
260
+ if(response.status == 200) {
261
+ getSpotCheckEventListener().emit('surveyDismissed');
262
+ }
263
+ else{
266
264
  console.log(`Error: ${response.status}`);
267
265
  }
268
266
  } catch (error) {
@@ -323,8 +321,6 @@ export const getSpotcheckComponentCssStyles = (state: SpotcheckState) => {
323
321
  height: '100%',
324
322
  };
325
323
  }
326
-
327
- let marginBottom = globalOS !== 'ios' ? 18 : 0;
328
324
 
329
325
  if (state.isVisible && state.isMounted) {
330
326
 
@@ -332,9 +328,6 @@ export const getSpotcheckComponentCssStyles = (state: SpotcheckState) => {
332
328
  if(state.spotChecksMode === 'miniCard') {
333
329
  if(state.avatarEnabled) {
334
330
  height = height - 56;
335
- if(state.spotcheckPosition === 'bottom') {
336
- marginBottom += 56;
337
- }
338
331
  }
339
332
  if(state.isCloseButtonEnabled) {
340
333
  height = height - 40;
@@ -342,7 +335,7 @@ export const getSpotcheckComponentCssStyles = (state: SpotcheckState) => {
342
335
  }
343
336
 
344
337
  switch (state.spotcheckPosition) {
345
- case 'bottom':
338
+ case 'bottom':
346
339
  styles = {
347
340
  display: 'flex',
348
341
  height: height+'px',
@@ -391,7 +384,7 @@ export const getSpotcheckComponentCssStyles = (state: SpotcheckState) => {
391
384
  top: '0',
392
385
  left: '0',
393
386
  backgroundColor: 'rgba(0, 0, 0, 0.3)',
394
- zIndex: '100001',
387
+ zIndex: '99999999',
395
388
  display: 'none',
396
389
  flexDirection: 'column',
397
390
  ...wrapperStyles
@@ -400,13 +393,11 @@ export const getSpotcheckComponentCssStyles = (state: SpotcheckState) => {
400
393
  display: 'none',
401
394
  flexDirection: 'column',
402
395
  paddingTop: extraPaddingForMiniCardCloseButtonIfTopPosition+'px',
403
- marginBottom: marginBottom+'px',
404
396
  ...styles,
405
397
  }
406
398
  };
407
399
  };
408
400
 
409
401
  export const closeSpotCheckAndHandleSurveyEnd = async () => {
410
- await closeSpotCheck();
411
402
  handleSurveyEnd();
412
403
  };
@@ -1,4 +1,7 @@
1
1
  export { initializeSpotChecks, trackScreen, trackEvent } from './SpotCheck';
2
+ export {
3
+ addSpotCheckListener,
4
+ } from './SpotCheckEventListener';
2
5
  export type {
3
6
  UserDetails,
4
7
  Variables,
@@ -23,8 +23,6 @@ export interface SpotcheckState {
23
23
  traceId: string;
24
24
  isClassicLoading: boolean;
25
25
  isChatLoading: boolean;
26
- isClassicLoadEventReceived: boolean;
27
- isChatLoadEventReceived: boolean;
28
26
  classicUrl: string;
29
27
  chatUrl: string;
30
28
  classicWebViewRef: any | null;