@chat21/chat21-web-widget 5.0.59-rc.2 → 5.0.59-rc.3
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 +3 -0
- package/package.json +1 -1
- package/src/app/app.component.ts +188 -177
- package/src/app/app.module.ts +5 -3
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +1 -1
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +43 -0
- package/src/app/component/home/home.component.html +1 -1
- package/src/app/component/home/home.component.ts +45 -0
- package/src/app/providers/global-settings.service.ts +1 -0
- package/src/app/utils/globals.ts +12 -0
- package/src/chat21-core/providers/scripts/script.service.spec.ts +12 -0
- package/src/chat21-core/providers/scripts/script.service.ts +71 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# chat21-web-widget ver 5.0
|
|
2
2
|
|
|
3
|
+
### 5.0.59-rc.3
|
|
4
|
+
- bug-fixed: if mobileMarginX or MobileMarginY is set, widget do not fit on fullscreen once is opened
|
|
5
|
+
|
|
3
6
|
### 5.0.59-rc.2
|
|
4
7
|
- added: handler for buttons in last-message component
|
|
5
8
|
- changed: tooltip custom directive
|
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ScriptService } from './../chat21-core/providers/scripts/script.service';
|
|
1
2
|
import { TYPE_DIRECT } from './../chat21-core/utils/constants';
|
|
2
3
|
/** ANGULAR MODULES */
|
|
3
4
|
import { AfterViewInit, Component, ElementRef, HostListener, NgZone, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
@@ -113,6 +114,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
113
114
|
private appStorageService: AppStorageService,
|
|
114
115
|
private translatorService: TranslatorService,
|
|
115
116
|
private translateService: CustomTranslateService,
|
|
117
|
+
private scriptService: ScriptService,
|
|
116
118
|
public chatManager: ChatManager,
|
|
117
119
|
private tiledeskRequestsService: TiledeskRequestsService,
|
|
118
120
|
public tiledeskAuthService: TiledeskAuthService,
|
|
@@ -123,220 +125,222 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
123
125
|
public imageRepoService: ImageRepoService,
|
|
124
126
|
public typingService: TypingService,
|
|
125
127
|
public presenceService: PresenceService,
|
|
126
|
-
public uploadService: UploadService
|
|
128
|
+
public uploadService: UploadService
|
|
127
129
|
){}
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
ngOnInit(): void {
|
|
132
|
+
this.logger.info('[APP-CONF]---------------- ngOnInit: APP.COMPONENT ---------------- ')
|
|
133
|
+
this.initWidgetParamiters();
|
|
134
|
+
}
|
|
133
135
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
136
|
+
ngAfterViewInit(): void {
|
|
137
|
+
this.logger.info('[APP-CONF]---------------- ngAfterViewInit: APP.COMPONENT ---------------- ')
|
|
138
|
+
this.ngZone.run(() => {
|
|
139
|
+
const that = this;
|
|
140
|
+
const subChangedConversation = this.conversationsHandlerService.conversationChanged.subscribe((conversation) => {
|
|
141
|
+
// that.ngZone.run(() => {
|
|
142
|
+
if (conversation) {
|
|
143
|
+
this.onImageLoaded(conversation)
|
|
144
|
+
this.onConversationLoaded(conversation)
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
if(conversation.recipient === this.g.senderId && isUserBanned(conversation)){
|
|
147
|
+
that.disposeWidget();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if(conversation.is_new && conversation.sender !== this.g.senderId && !isInfo(conversation)){
|
|
152
|
+
that.manageTabNotification();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (that.g.isOpen === true) {
|
|
156
|
+
that.g.setParameter('displayEyeCatcherCard', 'none');
|
|
157
|
+
|
|
158
|
+
this.logger.debug('[APP-COMP] obsChangeConversation ::: ', conversation);
|
|
159
|
+
if (conversation.attributes && conversation.attributes['subtype'] === 'info') {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
} else {
|
|
164
|
+
// if(conversation.is_new && isJustRecived(this.g.startedAt.getTime(), conversation.timestamp)){
|
|
165
|
+
//widget closed
|
|
166
|
+
if(conversation.is_new && conversation.sender !== this.g.senderId && !isInfo(conversation)){
|
|
167
|
+
that.lastConversation = conversation;
|
|
168
|
+
that.g.isOpenNewMessage = true;
|
|
169
|
+
that.logger.debug('[APP-COMP] lastconversationnn', that.lastConversation)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
let badgeNewConverstionNumber = that.conversationsHandlerService.countIsNew()
|
|
174
|
+
that.g.setParameter('conversationsBadge', badgeNewConverstionNumber);
|
|
175
|
+
// }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
that.triggerOnConversationUpdated(conversation);
|
|
179
|
+
} else {
|
|
180
|
+
this.logger.debug('[APP-COMP] oBSconversationChanged null: errorrr')
|
|
146
181
|
return;
|
|
147
182
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
183
|
+
|
|
184
|
+
// });
|
|
185
|
+
});
|
|
186
|
+
this.subscriptions.push(subChangedConversation);
|
|
152
187
|
|
|
153
|
-
|
|
188
|
+
const subAddedConversation = this.conversationsHandlerService.conversationAdded.subscribe((conversation) => {
|
|
189
|
+
// that.ngZone.run(() => {
|
|
190
|
+
if (that.g.isOpen === true && conversation) {
|
|
154
191
|
that.g.setParameter('displayEyeCatcherCard', 'none');
|
|
155
|
-
|
|
156
|
-
|
|
192
|
+
that.triggerOnConversationUpdated(conversation);
|
|
193
|
+
that.logger.debug('[APP-COMP] obsAddedConversation ::: ', conversation);
|
|
157
194
|
if (conversation.attributes && conversation.attributes['subtype'] === 'info') {
|
|
158
195
|
return;
|
|
159
196
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if(
|
|
197
|
+
if (conversation.is_new) {
|
|
198
|
+
that.manageTabNotification()
|
|
199
|
+
// this.soundMessage();
|
|
200
|
+
}
|
|
201
|
+
if(this.g.isOpen === false){
|
|
165
202
|
that.lastConversation = conversation;
|
|
166
203
|
that.g.isOpenNewMessage = true;
|
|
167
|
-
that.logger.debug('[APP-COMP] lastconversationnn', that.lastConversation)
|
|
168
204
|
}
|
|
169
|
-
|
|
205
|
+
} else {
|
|
206
|
+
//widget closed
|
|
170
207
|
|
|
171
208
|
let badgeNewConverstionNumber = that.conversationsHandlerService.countIsNew()
|
|
172
209
|
that.g.setParameter('conversationsBadge', badgeNewConverstionNumber);
|
|
173
|
-
// }
|
|
174
210
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// });
|
|
183
|
-
});
|
|
184
|
-
this.subscriptions.push(subChangedConversation);
|
|
185
|
-
|
|
186
|
-
const subAddedConversation = this.conversationsHandlerService.conversationAdded.subscribe((conversation) => {
|
|
187
|
-
// that.ngZone.run(() => {
|
|
188
|
-
if (that.g.isOpen === true && conversation) {
|
|
189
|
-
that.g.setParameter('displayEyeCatcherCard', 'none');
|
|
190
|
-
that.triggerOnConversationUpdated(conversation);
|
|
191
|
-
that.logger.debug('[APP-COMP] obsAddedConversation ::: ', conversation);
|
|
192
|
-
if (conversation.attributes && conversation.attributes['subtype'] === 'info') {
|
|
193
|
-
return;
|
|
211
|
+
// that.manageTabNotification()
|
|
212
|
+
// });
|
|
213
|
+
if(conversation){
|
|
214
|
+
this.onImageLoaded(conversation)
|
|
215
|
+
this.onConversationLoaded(conversation)
|
|
194
216
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
217
|
+
|
|
218
|
+
});
|
|
219
|
+
this.subscriptions.push(subAddedConversation);
|
|
220
|
+
|
|
221
|
+
const subAddedArchivedConversations = this.archivedConversationsService.archivedConversationAdded.subscribe((conversation) => {
|
|
222
|
+
// that.ngZone.run(() => {
|
|
223
|
+
if (conversation) {
|
|
224
|
+
that.triggerOnConversationUpdated(conversation);
|
|
225
|
+
this.onImageLoaded(conversation)
|
|
226
|
+
this.onConversationLoaded(conversation)
|
|
198
227
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
228
|
+
// });
|
|
229
|
+
});
|
|
230
|
+
this.subscriptions.push(subAddedArchivedConversations);
|
|
231
|
+
|
|
232
|
+
const subRemovedArchivedConversations = this.archivedConversationsService.archivedConversationRemoved.subscribe((conversation) => {
|
|
233
|
+
// that.ngZone.run(() => {
|
|
234
|
+
if (conversation) {
|
|
235
|
+
this.isConversationArchived = false;
|
|
236
|
+
that.triggerOnConversationUpdated(conversation);
|
|
202
237
|
}
|
|
203
|
-
|
|
204
|
-
|
|
238
|
+
// });
|
|
239
|
+
});
|
|
240
|
+
this.subscriptions.push(subRemovedArchivedConversations);
|
|
205
241
|
|
|
206
|
-
let badgeNewConverstionNumber = that.conversationsHandlerService.countIsNew()
|
|
207
|
-
that.g.setParameter('conversationsBadge', badgeNewConverstionNumber);
|
|
208
|
-
}
|
|
209
|
-
// that.manageTabNotification()
|
|
210
|
-
// });
|
|
211
|
-
if(conversation){
|
|
212
|
-
this.onImageLoaded(conversation)
|
|
213
|
-
this.onConversationLoaded(conversation)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
242
|
});
|
|
217
|
-
this.
|
|
243
|
+
this.appStorageService.initialize(environment.storage_prefix, this.g.persistence, this.g.projectid)
|
|
244
|
+
this.tiledeskAuthService.initialize(this.appConfigService.getConfig().apiUrl)
|
|
245
|
+
this.tiledeskRequestsService.initialize(this.appConfigService.getConfig().apiUrl, this.g.projectid)
|
|
246
|
+
this.messagingAuthService.initialize();
|
|
247
|
+
this.chatManager.initialize();
|
|
248
|
+
this.uploadService.initialize();
|
|
249
|
+
}
|
|
218
250
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
251
|
+
private initWidgetParamiters(){
|
|
252
|
+
const that = this;
|
|
253
|
+
const obsSettingsService = this.globalSettingsService.obsSettingsService.subscribe((resp) => {
|
|
254
|
+
if(resp){
|
|
255
|
+
|
|
256
|
+
// /** INIT */
|
|
257
|
+
this.logger.setLoggerConfig(this.g.isLogEnabled, this.g.logLevel)
|
|
258
|
+
this.tabTitle = this.g.windowContext.window.document.title
|
|
259
|
+
this.appStorageService.initialize(environment.storage_prefix, this.g.persistence, this.g.projectid)
|
|
260
|
+
this.logger.debug('[APP-COMP] check if token is passed throw url: ', this.g.jwt);
|
|
261
|
+
/**CHECK IF JWT IS IN URL PARAMETERS */
|
|
262
|
+
if (this.g.jwt) {
|
|
263
|
+
// logging in with custom token from url
|
|
264
|
+
// add JWY token to localstorage and authenticate with it this.logger.debug('[APP-COMP] token from url. isShown:', this.g.isShown, 'autostart:', this.g.autoStart)
|
|
265
|
+
this.logger.debug('[APP-COMP] ---------------- logging in with custom token from url ---------------- ');
|
|
266
|
+
// this.g.autoStart = false;
|
|
267
|
+
const storedTiledeskToken = this.appStorageService.getItem('tiledeskToken')
|
|
268
|
+
storedTiledeskToken === this.g.jwt? null: this.appStorageService.setItem('tiledeskToken', this.g.jwt);
|
|
269
|
+
this.g.tiledeskToken = this.g.jwt;
|
|
270
|
+
// this.signInWithCustomToken(this.g.jwt) // moved to authenticate() in else(tiledeskToken)
|
|
271
|
+
}
|
|
229
272
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
273
|
+
/** INIT LABELS TRANSLATIONS */
|
|
274
|
+
this.translatorService.initI18n().then((result) => {
|
|
275
|
+
this.logger.debug('[APP-COMP] »»»» APP-COMPONENT.TS initI18n result', result);
|
|
276
|
+
const browserLang = this.translatorService.getLanguage();
|
|
277
|
+
// moment.locale(browserLang)
|
|
278
|
+
dayjs.locale(browserLang)
|
|
279
|
+
this.translatorService.translate(this.g);
|
|
280
|
+
}).then(() => {
|
|
281
|
+
/** INIT */
|
|
282
|
+
that.initAll();
|
|
283
|
+
/** TRIGGER ONBEFORE INIT */
|
|
284
|
+
that.triggerOnBeforeInit();
|
|
285
|
+
/** AUTH */
|
|
286
|
+
that.setAuthSubscription();
|
|
287
|
+
/** SCRIPT LOAD */
|
|
288
|
+
that.loadCustomScript(this.appConfigService.getConfig())
|
|
289
|
+
})
|
|
290
|
+
|
|
235
291
|
}
|
|
236
|
-
// });
|
|
237
292
|
});
|
|
238
|
-
this.subscriptions.push(
|
|
239
|
-
|
|
240
|
-
});
|
|
241
|
-
this.appStorageService.initialize(environment.storage_prefix, this.g.persistence, this.g.projectid)
|
|
242
|
-
this.tiledeskAuthService.initialize(this.appConfigService.getConfig().apiUrl)
|
|
243
|
-
this.tiledeskRequestsService.initialize(this.appConfigService.getConfig().apiUrl, this.g.projectid)
|
|
244
|
-
this.messagingAuthService.initialize();
|
|
245
|
-
this.chatManager.initialize();
|
|
246
|
-
this.uploadService.initialize();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
private initWidgetParamiters(){
|
|
250
|
-
const that = this;
|
|
251
|
-
const obsSettingsService = this.globalSettingsService.obsSettingsService.subscribe((resp) => {
|
|
252
|
-
if(resp){
|
|
253
|
-
|
|
254
|
-
// /** INIT */
|
|
255
|
-
this.logger.setLoggerConfig(this.g.isLogEnabled, this.g.logLevel)
|
|
256
|
-
this.tabTitle = this.g.windowContext.window.document.title
|
|
257
|
-
this.appStorageService.initialize(environment.storage_prefix, this.g.persistence, this.g.projectid)
|
|
258
|
-
this.logger.debug('[APP-COMP] check if token is passed throw url: ', this.g.jwt);
|
|
259
|
-
/**CHECK IF JWT IS IN URL PARAMETERS */
|
|
260
|
-
if (this.g.jwt) {
|
|
261
|
-
// logging in with custom token from url
|
|
262
|
-
// add JWY token to localstorage and authenticate with it this.logger.debug('[APP-COMP] token from url. isShown:', this.g.isShown, 'autostart:', this.g.autoStart)
|
|
263
|
-
this.logger.debug('[APP-COMP] ---------------- logging in with custom token from url ---------------- ');
|
|
264
|
-
// this.g.autoStart = false;
|
|
265
|
-
const storedTiledeskToken = this.appStorageService.getItem('tiledeskToken')
|
|
266
|
-
storedTiledeskToken === this.g.jwt? null: this.appStorageService.setItem('tiledeskToken', this.g.jwt);
|
|
267
|
-
this.g.tiledeskToken = this.g.jwt;
|
|
268
|
-
// this.signInWithCustomToken(this.g.jwt) // moved to authenticate() in else(tiledeskToken)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/** INIT LABELS TRANSLATIONS */
|
|
272
|
-
this.translatorService.initI18n().then((result) => {
|
|
273
|
-
this.logger.debug('[APP-COMP] »»»» APP-COMPONENT.TS initI18n result', result);
|
|
274
|
-
const browserLang = this.translatorService.getLanguage();
|
|
275
|
-
// moment.locale(browserLang)
|
|
276
|
-
dayjs.locale(browserLang)
|
|
277
|
-
this.translatorService.translate(this.g);
|
|
278
|
-
}).then(() => {
|
|
279
|
-
/** INIT */
|
|
280
|
-
that.initAll();
|
|
281
|
-
/** TRIGGER ONBEFORE INIT */
|
|
282
|
-
that.triggerOnBeforeInit();
|
|
283
|
-
/** AUTH */
|
|
284
|
-
that.setAuthSubscription();
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
this.subscriptions.push(obsSettingsService);
|
|
290
|
-
this.globalSettingsService.initWidgetParamiters(this.g, this.el);
|
|
293
|
+
this.subscriptions.push(obsSettingsService);
|
|
294
|
+
this.globalSettingsService.initWidgetParamiters(this.g, this.el);
|
|
291
295
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
// SET AUDIO
|
|
297
|
+
this.audio = new Audio();
|
|
298
|
+
this.audio.src = this.g.baseLocation + URL_SOUND_LIST_CONVERSATION;
|
|
299
|
+
this.audio.load();
|
|
300
|
+
}
|
|
297
301
|
|
|
298
|
-
|
|
299
|
-
|
|
302
|
+
private initAll() {
|
|
303
|
+
this.addComponentToWindow(this.ngZone);
|
|
300
304
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
305
|
+
//INIT TRIGGER-HANDLER
|
|
306
|
+
this.triggerHandler.setElement(this.el)
|
|
307
|
+
this.triggerHandler.setWindowContext(this.g.windowContext)
|
|
304
308
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
// /** TRANSLATION LOADER: */
|
|
310
|
+
// // this.translatorService.translate(this.g);
|
|
311
|
+
// this.translatorService.initI18n().then((result) => {
|
|
312
|
+
// this.g.wdLog(['»»»» APP-COMPONENT.TS initI18n result', result]);
|
|
313
|
+
// this.translatorService.translate(this.g);
|
|
314
|
+
// });
|
|
311
315
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
/** SET ATTRIBUTES */
|
|
317
|
+
const attributes = this.setAttributesFromStorageService();
|
|
318
|
+
if (attributes) {
|
|
319
|
+
this.g.attributes = attributes;
|
|
320
|
+
}
|
|
321
|
+
this.setStyleMap()
|
|
318
322
|
|
|
319
|
-
|
|
323
|
+
// ------------------------------- //
|
|
320
324
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
325
|
+
// ------------------------------- //
|
|
326
|
+
/**
|
|
327
|
+
* INIZIALIZE GLOBALS :
|
|
328
|
+
* create settings object used in trigger
|
|
329
|
+
* set isMobile
|
|
330
|
+
* set attributes
|
|
331
|
+
*/
|
|
332
|
+
this.g.initialize();
|
|
333
|
+
// ------------------------------- //
|
|
330
334
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
335
|
+
this.removeFirebasewebsocketFromLocalStorage();
|
|
336
|
+
// this.triggerLoadParamsEvent();
|
|
337
|
+
// this.addComponentToWindow(this.ngZone); // forse dovrebbe stare prima di tutti i triggers
|
|
334
338
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
339
|
+
this.initLauncherButton();
|
|
340
|
+
this.triggerLoadParamsEvent(); // first trigger
|
|
341
|
+
//this.setAvailableAgentsStatus();
|
|
338
342
|
|
|
339
|
-
|
|
343
|
+
}
|
|
340
344
|
|
|
341
345
|
// ========= begin:: SUBSCRIPTIONS ============//
|
|
342
346
|
private async setAuthSubscription(){
|
|
@@ -2064,6 +2068,13 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
2064
2068
|
this.el.nativeElement.style.setProperty('--button-in-msg-font-size', this.g.buttonFontSize)
|
|
2065
2069
|
}
|
|
2066
2070
|
|
|
2071
|
+
|
|
2072
|
+
private loadCustomScript(config){
|
|
2073
|
+
if(config.hasOwnProperty("globalRemoteJSSrc")){
|
|
2074
|
+
this.scriptService.buildScriptArray(config['globalRemoteJSSrc'])
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2067
2078
|
// ========= begin:: DESTROY ALL SUBSCRIPTIONS ============//
|
|
2068
2079
|
/** elimino tutte le sottoscrizioni */
|
|
2069
2080
|
ngOnDestroy() {
|
package/src/app/app.module.ts
CHANGED
|
@@ -62,10 +62,11 @@ import { TranslateModule } from '@ngx-translate/core';
|
|
|
62
62
|
import { PickerModule } from '@ctrl/ngx-emoji-mart';
|
|
63
63
|
import { LoggerModule, NGXLogger, NgxLoggerLevel } from "ngx-logger";
|
|
64
64
|
|
|
65
|
-
//DIRECTIVES
|
|
65
|
+
//DIRECTIVES-PIPES
|
|
66
66
|
import { HtmlEntitiesEncodePipe } from './pipe/html-entities-encode.pipe';
|
|
67
67
|
import { MarkedPipe } from './pipe/marked.pipe';
|
|
68
68
|
import { SafeHtmlPipe } from './pipe/safe-html.pipe';
|
|
69
|
+
import { TooltipDirective } from 'src/app/directives/tooltip.directive';
|
|
69
70
|
|
|
70
71
|
//LOGGER SERVICES
|
|
71
72
|
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
@@ -128,7 +129,7 @@ import { WaitingService } from './providers/waiting.service';
|
|
|
128
129
|
import { StarRatingWidgetService } from './providers/star-rating-widget.service';
|
|
129
130
|
import { LikeUnlikeComponent } from './component/message/like-unlike/like-unlike.component';
|
|
130
131
|
import { Rules } from './utils/rules';
|
|
131
|
-
import {
|
|
132
|
+
import { ScriptService } from 'src/chat21-core/providers/scripts/script.service';
|
|
132
133
|
|
|
133
134
|
|
|
134
135
|
const appInitializerFn = (appConfig: AppConfigService, logger: NGXLogger) => {
|
|
@@ -381,7 +382,8 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
381
382
|
TranslatorService,
|
|
382
383
|
CustomTranslateService,
|
|
383
384
|
Triggerhandler,
|
|
384
|
-
WaitingService
|
|
385
|
+
WaitingService,
|
|
386
|
+
ScriptService
|
|
385
387
|
],
|
|
386
388
|
bootstrap: [AppComponent]
|
|
387
389
|
})
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- LOGO-->
|
|
2
2
|
<div id="hiddenFooter" *ngIf="!hideTextAreaContent && poweredBy" class="fade-in-bottom"
|
|
3
3
|
[class.hideTextReply]="hideTextReply">
|
|
4
|
-
<div tabindex="-1" class="c21-powered-by" [innerHTML]="poweredBy"></div>
|
|
4
|
+
<div tabindex="-1" class="c21-powered-by" [innerHTML]="poweredBy" (click)="managePoweredBy($event)"></div>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<!-- TEXTAREA + ICONS: conv active-->
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts
CHANGED
|
@@ -596,4 +596,47 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
596
596
|
}
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
managePoweredBy(event: Event){
|
|
602
|
+
event.stopPropagation();
|
|
603
|
+
this.segmentLogoClick()
|
|
604
|
+
let target = (event.target as Element) || (event.srcElement as Element) || (event.currentTarget as Element)
|
|
605
|
+
if(target.parentElement.tagName === 'A' && target.parentElement.hasAttribute('href')){
|
|
606
|
+
window.open(target.parentElement.getAttribute('href'), '_blank')
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
private segmentLogoClick(){
|
|
612
|
+
let that = this
|
|
613
|
+
if(window['analytics']){
|
|
614
|
+
try {
|
|
615
|
+
window['analytics'].page("Widget Conversation Page, LogoClick", {});
|
|
616
|
+
} catch (err) {
|
|
617
|
+
this.logger.error('Event:Signed In [page] error', err);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
try {
|
|
621
|
+
window['analytics'].identify(that.senderId, {
|
|
622
|
+
name: that.userFullname,
|
|
623
|
+
email: that.userEmail,
|
|
624
|
+
logins: 5,
|
|
625
|
+
});
|
|
626
|
+
} catch (err) {
|
|
627
|
+
this.logger.error('Event:LogoClick [identify] error', err);
|
|
628
|
+
}
|
|
629
|
+
// Segments
|
|
630
|
+
try {
|
|
631
|
+
window['analytics'].track('LogoClick', {
|
|
632
|
+
"username": that.userFullname,
|
|
633
|
+
"userId": that.userEmail,
|
|
634
|
+
"attributes": that.attributes
|
|
635
|
+
});
|
|
636
|
+
} catch (err) {
|
|
637
|
+
this.logger.error('Event:LogoClick [track] error', err);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
599
642
|
}
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
<!-- FOOTER -->
|
|
145
145
|
<div class="c21-footer fade-in-bottom-footer">
|
|
146
146
|
<div id="c21-powered-by" (mouseover)="hover=true" (mouseleave)="hover=false">
|
|
147
|
-
<div tabindex="-1" class="c21-powered-by" [innerHTML]="g.poweredBy"></div>
|
|
147
|
+
<div tabindex="-1" class="c21-powered-by" [innerHTML]="g.poweredBy" (click)="managePoweredBy($event)"></div>
|
|
148
148
|
<!-- <div class="build_version">{{g.BUILD_VERSION}}</div> -->
|
|
149
149
|
</div>
|
|
150
150
|
<chat-menu-options *ngIf="!hideSettings"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TiledeskAuthService } from './../../../chat21-core/providers/tiledesk/tiledesk-auth.service';
|
|
1
2
|
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
2
3
|
import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
|
|
3
4
|
import { ConversationModel } from '../../../chat21-core/models/conversation';
|
|
@@ -47,6 +48,7 @@ export class HomeComponent implements OnInit, AfterViewInit {
|
|
|
47
48
|
|
|
48
49
|
constructor(
|
|
49
50
|
public g: Globals,
|
|
51
|
+
private tiledeskAuthService : TiledeskAuthService,
|
|
50
52
|
private customTranslateService: CustomTranslateService,
|
|
51
53
|
) {
|
|
52
54
|
|
|
@@ -85,6 +87,49 @@ export class HomeComponent implements OnInit, AfterViewInit {
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
|
|
90
|
+
managePoweredBy(event: Event){
|
|
91
|
+
event.stopPropagation();
|
|
92
|
+
this.segmentLogoClick()
|
|
93
|
+
let target = (event.target as Element) || (event.srcElement as Element) || (event.currentTarget as Element)
|
|
94
|
+
if(target.parentElement.tagName === 'A' && target.parentElement.hasAttribute('href')){
|
|
95
|
+
window.open(target.parentElement.getAttribute('href'), '_blank')
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
private segmentLogoClick(){
|
|
101
|
+
let that = this
|
|
102
|
+
let user = this.tiledeskAuthService.getCurrentUser()
|
|
103
|
+
if(window['analytics']){
|
|
104
|
+
try {
|
|
105
|
+
window['analytics'].page("Widget Home Page, LogoClick", {});
|
|
106
|
+
} catch (err) {
|
|
107
|
+
this.logger.error('Event:Signed In [page] error', err);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
window['analytics'].identify(user.uid, {
|
|
112
|
+
name: user.firstname + ' ' + user.lastname,
|
|
113
|
+
email: user.email,
|
|
114
|
+
logins: 5,
|
|
115
|
+
});
|
|
116
|
+
} catch (err) {
|
|
117
|
+
this.logger.error('Event:LogoClick [identify] error', err);
|
|
118
|
+
}
|
|
119
|
+
// Segments
|
|
120
|
+
try {
|
|
121
|
+
window['analytics'].track('LogoClick', {
|
|
122
|
+
"username": user.firstname + ' ' + user.lastname,
|
|
123
|
+
"userId": user.uid,
|
|
124
|
+
"attributes": that.g.attributes
|
|
125
|
+
});
|
|
126
|
+
} catch (err) {
|
|
127
|
+
this.logger.error('Event:LogoClick [track] error', err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
88
133
|
|
|
89
134
|
|
|
90
135
|
|
|
@@ -369,6 +369,7 @@ export class GlobalSettingsService {
|
|
|
369
369
|
this.globals.isMobile? marginX= this.globals.mobileMarginX: marginX = this.globals.marginX
|
|
370
370
|
divTiledeskiframe.style.right = marginX;
|
|
371
371
|
}
|
|
372
|
+
|
|
372
373
|
if (this.globals.isMobile) {
|
|
373
374
|
divTiledeskiframe.style.bottom = this.globals.mobileMarginY
|
|
374
375
|
} else {
|
package/src/app/utils/globals.ts
CHANGED
|
@@ -587,6 +587,18 @@ export class Globals {
|
|
|
587
587
|
} else if(!isOpen && chat21conversationsEL){
|
|
588
588
|
chat21conversationsEL.classList.remove('isMobile')
|
|
589
589
|
}
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
//customize position for 'tiledeskdiv' for mobile
|
|
593
|
+
if(isOpen && this.isMobile && divTiledeskWidget){
|
|
594
|
+
divTiledeskWidget.style.right = '0px'
|
|
595
|
+
divTiledeskWidget.style.bottom = '0px'
|
|
596
|
+
} else if(!isOpen && this.isMobile && divTiledeskWidget){
|
|
597
|
+
divTiledeskWidget.style.bottom = this.marginY
|
|
598
|
+
this.align === 'left'? divTiledeskWidget.style.left = this.mobileMarginX : divTiledeskWidget.style.right = this.mobileMarginX;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
|
|
590
602
|
}
|
|
591
603
|
|
|
592
604
|
setWidgetPreviewContainerSize(width: number, height: number){
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { ScriptService } from './script.service';
|
|
4
|
+
|
|
5
|
+
describe('ScriptService', () => {
|
|
6
|
+
beforeEach(() => TestBed.configureTestingModule({}));
|
|
7
|
+
|
|
8
|
+
it('should be created', () => {
|
|
9
|
+
const service: ScriptService = TestBed.get(ScriptService);
|
|
10
|
+
expect(service).toBeTruthy();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
|
|
4
|
+
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
5
|
+
|
|
6
|
+
@Injectable({
|
|
7
|
+
providedIn: 'root'
|
|
8
|
+
})
|
|
9
|
+
export class ScriptService {
|
|
10
|
+
|
|
11
|
+
private scriptList: Array<{name: string, loaded: boolean, src: string}> = []
|
|
12
|
+
private logger: LoggerService = LoggerInstance.getInstance();
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
public http: HttpClient,
|
|
16
|
+
) { }
|
|
17
|
+
|
|
18
|
+
buildScriptArray(globalRemoteJSSrc: string){
|
|
19
|
+
this.logger.log('[SCRIPT-SERVICE] buildScriptArray globalRemoteJSSrc ', globalRemoteJSSrc);
|
|
20
|
+
if(!this.isEmpty(globalRemoteJSSrc)){
|
|
21
|
+
var scriptArray = globalRemoteJSSrc.split(",")
|
|
22
|
+
|
|
23
|
+
let count = 0;
|
|
24
|
+
scriptArray.forEach(element => {
|
|
25
|
+
count = count + 1;
|
|
26
|
+
this.scriptList.push({name: element.split('/').pop(), loaded: false, src: element})
|
|
27
|
+
});
|
|
28
|
+
this.logger.log('[SCRIPT-SERVICE] buildScriptArray ', this.scriptList);
|
|
29
|
+
this.load()
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
load() {
|
|
35
|
+
this.logger.log('[SCRIPT-SERV] load ...scripts ', this.scriptList)
|
|
36
|
+
var promises: any[] = [];
|
|
37
|
+
this.scriptList.forEach((script) => promises.push(this.loadScript(script)));
|
|
38
|
+
return Promise.all(promises).catch((err) => {
|
|
39
|
+
// log that I have an error, return the entire array;
|
|
40
|
+
this.logger.error('A promise failed to resolve', err);
|
|
41
|
+
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
loadScript(currentScript){
|
|
47
|
+
this.logger.log('[SCRIPT-SERVICE] load script:', currentScript);
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
//resolve if already loaded
|
|
50
|
+
if (currentScript.loaded) {
|
|
51
|
+
resolve({ script: currentScript.name, loaded: true, status: 'Already Loaded' });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
//load script
|
|
55
|
+
let script = document.createElement('script')
|
|
56
|
+
script.type = 'text/javascript';
|
|
57
|
+
script.src = currentScript.src;
|
|
58
|
+
script.onload = () => {
|
|
59
|
+
currentScript.loaded = true;
|
|
60
|
+
resolve({ script: name, loaded: true, status: 'Loaded' });
|
|
61
|
+
}
|
|
62
|
+
script.onerror = (error: any) => resolve({ script: currentScript.name, loaded: false, status: 'Loaded' });
|
|
63
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
isEmpty(url: string) {
|
|
69
|
+
return (url === undefined || url == null || url.length <= 0) ? true : false;
|
|
70
|
+
}
|
|
71
|
+
}
|