@chat21/chat21-web-widget 5.0.67 → 5.0.69-rc.1
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 +8 -0
- package/package.json +1 -1
- package/src/app/app.component.ts +20 -40
- package/src/app/app.module.ts +3 -1
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +8 -1
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +13 -0
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +4 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +5 -5
- package/src/app/component/message/audio/audio.component.scss +4 -0
- package/src/app/component/message/carousel/carousel.component.html +35 -0
- package/src/app/component/message/carousel/carousel.component.scss +260 -0
- package/src/app/component/message/carousel/carousel.component.spec.ts +23 -0
- package/src/app/component/message/carousel/carousel.component.ts +139 -0
- package/src/app/providers/global-settings.service.ts +33 -1
- package/src/app/utils/globals.ts +13 -0
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +53 -48
- package/src/chat21-core/utils/utils-message.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# chat21-web-widget ver 5.0
|
|
2
2
|
|
|
3
|
+
### 5.0.69-rc.1
|
|
4
|
+
- added: display/dispose widget on mobile/desktop behavior
|
|
5
|
+
- added: open/close widget on page change behavior
|
|
6
|
+
- added: 'redirect' action link on message type 'redirect'
|
|
7
|
+
|
|
8
|
+
### 5.0.68 in PROD
|
|
9
|
+
- bug-fixed: metadata.includes is not a function at isAudio function
|
|
10
|
+
|
|
3
11
|
### 5.0.67 in PROD
|
|
4
12
|
- bug-fixed: when refresh the page and an already open conversation is selected, footer is blocked
|
|
5
13
|
- bug-fix: pdf preview image is not contained into its container
|
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -258,8 +258,26 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
258
258
|
this.logger.setLoggerConfig(this.g.isLogEnabled, this.g.logLevel)
|
|
259
259
|
this.tabTitle = this.g.windowContext.window.document.title
|
|
260
260
|
this.appStorageService.initialize(environment.storage_prefix, this.g.persistence, this.g.projectid)
|
|
261
|
-
|
|
261
|
+
|
|
262
|
+
//set visibility
|
|
263
|
+
if((this.g.isMobile && !this.g.displayOnMobile) || (!this.g.isMobile && !this.g.displayOnDesktop)){
|
|
264
|
+
this.disposeWidget()
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
//set status (open /close)
|
|
268
|
+
if(this.g.isMobile && this.g.onPageChangeVisibilityMobile !== 'last'){
|
|
269
|
+
let isOpen = this.g.onPageChangeVisibilityMobile === 'open'? true: false
|
|
270
|
+
this.g.setIsOpen(isOpen)
|
|
271
|
+
this.appStorageService.setItem('isOpen', isOpen)
|
|
272
|
+
}
|
|
273
|
+
if(!this.g.isMobile && this.g.onPageChangeVisibilityDesktop !== 'last'){
|
|
274
|
+
let isOpen = this.g.onPageChangeVisibilityDesktop === 'open'? true: false
|
|
275
|
+
this.g.setIsOpen(isOpen)
|
|
276
|
+
this.appStorageService.setItem('isOpen', isOpen)
|
|
277
|
+
}
|
|
278
|
+
|
|
262
279
|
/**CHECK IF JWT IS IN URL PARAMETERS */
|
|
280
|
+
this.logger.debug('[APP-COMP] check if token is passed throw url: ', this.g.jwt);
|
|
263
281
|
if (this.g.jwt) {
|
|
264
282
|
// logging in with custom token from url
|
|
265
283
|
// 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)
|
|
@@ -488,40 +506,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
488
506
|
this.logger.debug('[APP-COMP] ---------------- 13 ---------------- ');
|
|
489
507
|
this.logger.debug('[APP-COMP] ----------- sono già loggato ------- ');
|
|
490
508
|
this.signInWithCustomToken(tiledeskToken)
|
|
491
|
-
|
|
492
|
-
// this.messagingAuthService.createCustomToken(tiledeskToken)
|
|
493
|
-
// }).catch(error => { console.error('SIGNINWITHCUSTOMTOKEN error::' + error) })
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
// const currentUser = this.authService2.getCurrentUser();
|
|
497
|
-
// this.g.senderId = currentUser.uid;
|
|
498
|
-
// this.g.setParameter('senderId', currentUser.uid);
|
|
499
|
-
|
|
500
|
-
// const fullName = currentUser.firstname + ' ' + currentUser.lastname;
|
|
501
|
-
// this.g.setParameter('userFullname', fullName);
|
|
502
|
-
// this.g.setAttributeParameter('userFullname', fullName);
|
|
503
|
-
// this.g.setParameter('userEmail', currentUser.email);
|
|
504
|
-
// this.g.setAttributeParameter('userEmail', currentUser.email);
|
|
505
|
-
|
|
506
|
-
// // if(currentUser.firstname || currentUser.lastname){
|
|
507
|
-
// // this.g.wdLog([' ---------------- 13 fullname ---------------- ']);
|
|
508
|
-
// // const fullName = currentUser.firstname + ' ' + currentUser.lastname;
|
|
509
|
-
// // this.g.setParameter('userFullname', fullName);
|
|
510
|
-
// // this.g.setAttributeParameter('userFullname', fullName);
|
|
511
|
-
// // }
|
|
512
|
-
// // if(currentUser.email){
|
|
513
|
-
// // this.g.wdLog([' ---------------- 13 email ---------------- ']);
|
|
514
|
-
// // this.g.setParameter('userEmail', currentUser.email);
|
|
515
|
-
// // this.g.setAttributeParameter('userEmail', currentUser.email);
|
|
516
|
-
// // }
|
|
517
|
-
|
|
518
|
-
// // this.g.setParameter('isLogged', true);
|
|
519
|
-
// // this.g.setParameter('attributes', this.setAttributesFromStorageService());
|
|
520
|
-
// // this.startNwConversation();
|
|
521
|
-
// //this.startUI();
|
|
522
|
-
// // this.g.wdLog([' 13 - IMPOSTO STATO CONNESSO UTENTE ']);
|
|
523
|
-
// // this.presenceService.setPresence(currentUser.uid);
|
|
524
|
-
//
|
|
509
|
+
|
|
525
510
|
} else {
|
|
526
511
|
// AUTENTICAZIONE ANONIMA
|
|
527
512
|
this.logger.debug('[APP-COMP] ---------------- 14 ---------------- ');
|
|
@@ -543,9 +528,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
543
528
|
this.g.setAttributeParameter('userEmail', user.email);
|
|
544
529
|
}
|
|
545
530
|
});
|
|
546
|
-
// this.authService.anonymousAuthentication();
|
|
547
|
-
// this.g.wdLog([' authenticateFirebaseAnonymously']);
|
|
548
|
-
// this.authService.authenticateFirebaseAnonymously();
|
|
549
531
|
}
|
|
550
532
|
}
|
|
551
533
|
|
|
@@ -599,8 +581,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
599
581
|
this.logger.error('[APP-COMP] signInAnonymous ERR', error);
|
|
600
582
|
return Promise.reject(error);
|
|
601
583
|
});
|
|
602
|
-
// this.authService.anonymousAuthentication();
|
|
603
|
-
// this.authService.authenticateFirebaseAnonymously();
|
|
604
584
|
}
|
|
605
585
|
// ========= end:: AUTHENTICATION ============//
|
|
606
586
|
|
package/src/app/app.module.ts
CHANGED
|
@@ -131,6 +131,7 @@ import { StarRatingWidgetService } from './providers/star-rating-widget.service'
|
|
|
131
131
|
import { LikeUnlikeComponent } from './component/message/like-unlike/like-unlike.component';
|
|
132
132
|
import { Rules } from './utils/rules';
|
|
133
133
|
import { ScriptService } from 'src/chat21-core/providers/scripts/script.service';
|
|
134
|
+
import { CarouselComponent } from './component/message/carousel/carousel.component';
|
|
134
135
|
|
|
135
136
|
|
|
136
137
|
|
|
@@ -290,7 +291,8 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
290
291
|
SafeHtmlPipe,
|
|
291
292
|
LikeUnlikeComponent,
|
|
292
293
|
TooltipDirective,
|
|
293
|
-
AudioComponent
|
|
294
|
+
AudioComponent,
|
|
295
|
+
CarouselComponent
|
|
294
296
|
],
|
|
295
297
|
imports: [
|
|
296
298
|
BrowserModule,
|
|
@@ -42,7 +42,7 @@ import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance'
|
|
|
42
42
|
import { TiledeskRequestsService } from 'src/chat21-core/providers/tiledesk/tiledesk-requests.service';
|
|
43
43
|
import { LIVE_PAGE } from 'src/chat21-core/utils/constants';
|
|
44
44
|
import { getDateDifference, popupUrl } from 'src/chat21-core/utils/utils';
|
|
45
|
-
import { isUserBanned } from 'src/chat21-core/utils/utils-message';
|
|
45
|
+
import { isJustRecived, isUserBanned } from 'src/chat21-core/utils/utils-message';
|
|
46
46
|
import { AppComponent } from '../../../app.component';
|
|
47
47
|
import { ConversationContentComponent } from '../conversation-content/conversation-content.component';
|
|
48
48
|
// import { TranslateService } from '@ngx-translate/core';
|
|
@@ -165,6 +165,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
165
165
|
|
|
166
166
|
public isButtonUrl: boolean = false;
|
|
167
167
|
public buttonClicked: any;
|
|
168
|
+
public startTime: Date = new Date();
|
|
168
169
|
private logger: LoggerService = LoggerInstance.getInstance();
|
|
169
170
|
|
|
170
171
|
constructor(
|
|
@@ -890,6 +891,12 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
890
891
|
}else {
|
|
891
892
|
this.footerMessagePlaceholder = '';
|
|
892
893
|
}
|
|
894
|
+
|
|
895
|
+
//check if redirect message is present inside message object
|
|
896
|
+
if(msg.type === 'redirect' && isJustRecived(this.startTime.getTime(), msg.timestamp)){
|
|
897
|
+
let button = { link: msg.metadata.src, target: msg.metadata.target}
|
|
898
|
+
this.openLink(button)
|
|
899
|
+
}
|
|
893
900
|
}
|
|
894
901
|
|
|
895
902
|
}
|
|
@@ -107,6 +107,19 @@
|
|
|
107
107
|
(onAttachmentButtonClicked)="onAttachmentButtonClickedFN($event)">
|
|
108
108
|
</chat-message-attachment>
|
|
109
109
|
</div>
|
|
110
|
+
|
|
111
|
+
<!-- carousel -->
|
|
112
|
+
<div *ngIf="message?.attributes && message?.attributes?.attachment
|
|
113
|
+
&& message?.attributes?.attachment?.gallery" [ngClass]="{'slide-in-left': false}" class="carousel_container">
|
|
114
|
+
<chat-carousel class="carousel_container"
|
|
115
|
+
[message]="message"
|
|
116
|
+
[isConversationArchived]="isConversationArchived"
|
|
117
|
+
[isLastMessage] = "isLastMessage(message?.uid)"
|
|
118
|
+
[stylesMap]="stylesMap"
|
|
119
|
+
(onElementRendered)="onElementRenderedFN($event)"
|
|
120
|
+
(onAttachmentButtonClicked)="onAttachmentButtonClickedFN($event)">
|
|
121
|
+
</chat-carousel>
|
|
122
|
+
</div>
|
|
110
123
|
|
|
111
124
|
</div>
|
|
112
125
|
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html
CHANGED
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
<!-- ICON EMOJII -->
|
|
32
32
|
<label tabindex="1504" aria-label="emojii" for="chat21-emojii" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-emoticon-picker" (click)="onEmojiiPickerClicked()">
|
|
33
33
|
<span class="v-align-center">
|
|
34
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
|
35
|
-
<path d="M0
|
|
36
|
-
<circle cx="15.
|
|
37
|
-
<circle cx="
|
|
38
|
-
<path d="M12
|
|
34
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
|
35
|
+
<path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
|
|
36
|
+
<circle cx="15.02" cy="9.86" r="1.29"/>
|
|
37
|
+
<circle cx="9.02" cy="9.86" r="1.29"/>
|
|
38
|
+
<path d="M12.02,15.43c-1.27,0-2.36-.69-2.96-1.71h-1.43c.69,1.76,2.39,3,4.39,3s3.7-1.24,4.39-3h-1.43c-.6,1.02-1.69,1.71-2.96,1.71Zm0-12C7.28,3.43,3.45,7.27,3.45,12s3.83,8.57,8.56,8.57,8.58-3.84,8.58-8.57S16.75,3.43,12.01,3.43Zm0,15.43c-3.79,0-6.86-3.07-6.86-6.86s3.07-6.86,6.86-6.86,6.86,3.07,6.86,6.86-3.07,6.86-6.86,6.86Z"/>
|
|
39
39
|
</svg>
|
|
40
40
|
</span>
|
|
41
41
|
</label>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<div class="wrapper">
|
|
2
|
+
<div id="left" class="arrow left" (click)="goTo('previous')" *ngIf="activeElement > 1">
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
|
4
|
+
<path d="M0 0h24v24H0V0z" fill="none"/><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12l4.58-4.59z"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="carousel">
|
|
8
|
+
<!-- <div class="card" style="width: 17px;"></div> -->
|
|
9
|
+
<div class="card" *ngFor="let card of gallery; let i = index">
|
|
10
|
+
<div [style.opacity]="i+1 === activeElement? 1: 0.5">
|
|
11
|
+
<div class="card-image">
|
|
12
|
+
<img [src]="card?.preview?.src" alt="img" draggable="false">
|
|
13
|
+
</div>
|
|
14
|
+
<div class="card-content">
|
|
15
|
+
<div class="card-title">{{card?.title}}</div>
|
|
16
|
+
<div class="card-description">{{card?.description}}</div>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="buttons" *ngIf="card?.buttons && card?.buttons.length > 0">
|
|
19
|
+
<div *ngFor="let button of card?.buttons"
|
|
20
|
+
class="single-button action"
|
|
21
|
+
[ngClass]="{'disabled': (isConversationArchived || !isLastMessage), 'active': button?.active}"
|
|
22
|
+
(click)="actionButtonClick($event, button, i)" >
|
|
23
|
+
{{button.value}}
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
<!-- <div class="card" style="width: 17px;"></div> -->
|
|
29
|
+
</div>
|
|
30
|
+
<div id="right" class="arrow right" (click)="goTo('next')" *ngIf="activeElement !== gallery.length">
|
|
31
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
|
|
32
|
+
<path d="M0 0h24v24H0V0z" fill="none"/><path d="M10.02 6L8.61 7.41 13.19 12l-4.58 4.59L10.02 18l6-6-6-6z"/>
|
|
33
|
+
</svg>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
@import 'src/app/sass/variables';
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
--backgroundColor: #{var(--blue)};
|
|
5
|
+
--textColor: #{var(--bck-msg-sent)};
|
|
6
|
+
--hoverBackgroundColor: #{var(--bck-msg-sent)};
|
|
7
|
+
--hoverTextColor: #{var(--blue)};
|
|
8
|
+
--buttonFontSize: #{var(--button-in-msg-font-size)};
|
|
9
|
+
--max-width: #{var(--button-in-msg-max-width)};
|
|
10
|
+
|
|
11
|
+
--cardWidth: 220px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
.wrapper {
|
|
16
|
+
// max-width: 1100px;
|
|
17
|
+
width: 100%;
|
|
18
|
+
position: relative;
|
|
19
|
+
display: flex;
|
|
20
|
+
|
|
21
|
+
// overflow: scroll;
|
|
22
|
+
gap: 10px;
|
|
23
|
+
margin: 0;
|
|
24
|
+
width: 100%;
|
|
25
|
+
font-size: 14px;
|
|
26
|
+
// margin: 0 25px;
|
|
27
|
+
}
|
|
28
|
+
.wrapper div.arrow {
|
|
29
|
+
top: 50%;
|
|
30
|
+
height: 40px;
|
|
31
|
+
width: 40px;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
position: absolute;
|
|
34
|
+
background: #fff;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
box-shadow: 0 3px 6px rgba(0,0,0,0.23);
|
|
37
|
+
transform: translateY(-50%);
|
|
38
|
+
transition: transform 0.1s linear;
|
|
39
|
+
z-index: 2;
|
|
40
|
+
|
|
41
|
+
display: flex;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
45
|
+
.wrapper div.arrow:active{
|
|
46
|
+
transform: translateY(-50%) scale(0.85);
|
|
47
|
+
}
|
|
48
|
+
.wrapper div.arrow:first-child{
|
|
49
|
+
left: -22px;
|
|
50
|
+
}
|
|
51
|
+
.wrapper div.arrow:last-child{
|
|
52
|
+
right: -22px;
|
|
53
|
+
}
|
|
54
|
+
.wrapper .carousel{
|
|
55
|
+
display: grid;
|
|
56
|
+
align-items: start;
|
|
57
|
+
grid-auto-flow: column;
|
|
58
|
+
grid-auto-columns: calc((100% / 3) - 12px);
|
|
59
|
+
// overflow-x: auto;
|
|
60
|
+
overflow-x: hidden;
|
|
61
|
+
scroll-snap-type: x mandatory;
|
|
62
|
+
gap: 10px;
|
|
63
|
+
border-radius: 8px;
|
|
64
|
+
scroll-behavior: smooth;
|
|
65
|
+
scrollbar-width: none;
|
|
66
|
+
|
|
67
|
+
padding: 10px 0px
|
|
68
|
+
}
|
|
69
|
+
.carousel::-webkit-scrollbar {
|
|
70
|
+
display: none;
|
|
71
|
+
}
|
|
72
|
+
.carousel.no-transition {
|
|
73
|
+
scroll-behavior: auto;
|
|
74
|
+
}
|
|
75
|
+
.carousel.dragging {
|
|
76
|
+
scroll-snap-type: none;
|
|
77
|
+
scroll-behavior: auto;
|
|
78
|
+
}
|
|
79
|
+
.carousel.dragging .card {
|
|
80
|
+
cursor: grab;
|
|
81
|
+
user-select: none;
|
|
82
|
+
}
|
|
83
|
+
.carousel :where(.card, .img) {
|
|
84
|
+
display: flex;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
align-items: center;
|
|
87
|
+
}
|
|
88
|
+
.carousel .card {
|
|
89
|
+
// padding: 0px 5px;
|
|
90
|
+
scroll-snap-align: start;
|
|
91
|
+
width: var(--cardWidth);
|
|
92
|
+
background: rgb(255, 255, 255);
|
|
93
|
+
list-style: none;
|
|
94
|
+
cursor: pointer;
|
|
95
|
+
// padding-bottom: 15px;
|
|
96
|
+
flex-direction: column;
|
|
97
|
+
border-radius: 8px;
|
|
98
|
+
box-shadow: 0 3px 6px rgba(0,0,0,0.23);
|
|
99
|
+
}
|
|
100
|
+
.carousel .card .card-image {
|
|
101
|
+
height: 150px;
|
|
102
|
+
width: var(--cardWidth);
|
|
103
|
+
}
|
|
104
|
+
.card .card-image img {
|
|
105
|
+
height: 100%;
|
|
106
|
+
-o-object-fit: cover;
|
|
107
|
+
object-fit: cover;
|
|
108
|
+
|
|
109
|
+
background: transparent!important;
|
|
110
|
+
display: block;
|
|
111
|
+
max-width: 100% !important;
|
|
112
|
+
border-radius: 8px 8px 0px 0px;
|
|
113
|
+
}
|
|
114
|
+
.carousel .card .card-content {
|
|
115
|
+
// font-weight: 500;
|
|
116
|
+
// font-size: 1.56rem;
|
|
117
|
+
// margin: 30px 0 5px;
|
|
118
|
+
-webkit-box-orient: vertical;
|
|
119
|
+
-webkit-box-direction: normal;
|
|
120
|
+
display: -webkit-box;
|
|
121
|
+
display: -ms-flexbox;
|
|
122
|
+
display: flex;
|
|
123
|
+
-ms-flex-direction: column;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
padding: 0 20px 30px;
|
|
126
|
+
|
|
127
|
+
.card-title{
|
|
128
|
+
word-wrap: break-word;
|
|
129
|
+
font-size: 16px;
|
|
130
|
+
font-weight: 600;
|
|
131
|
+
line-height: 20px;
|
|
132
|
+
margin-top: 12px;
|
|
133
|
+
white-space: pre-wrap;
|
|
134
|
+
width: 100%;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.card-description{
|
|
138
|
+
word-wrap: break-word;
|
|
139
|
+
font-size: 16px;
|
|
140
|
+
line-height: 20px;
|
|
141
|
+
margin-top: 12px;
|
|
142
|
+
white-space: pre-wrap;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.cards-scroll-spacer{
|
|
148
|
+
-ms-flex-negative: 0;
|
|
149
|
+
content: "";
|
|
150
|
+
flex-shrink: 0;
|
|
151
|
+
width: 17px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.carousel .card .buttons{
|
|
155
|
+
-webkit-box-orient: vertical;
|
|
156
|
+
-webkit-box-direction: normal;
|
|
157
|
+
display: -webkit-box;
|
|
158
|
+
display: -ms-flexbox;
|
|
159
|
+
display: flex;
|
|
160
|
+
-ms-flex-direction: column;
|
|
161
|
+
flex-direction: column;
|
|
162
|
+
width: 100%;
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
.single-button{
|
|
166
|
+
// border-top-color: rgb(219, 225, 232);
|
|
167
|
+
|
|
168
|
+
-webkit-box-align: center;
|
|
169
|
+
-ms-flex-align: center;
|
|
170
|
+
align-items: center;
|
|
171
|
+
justify-content: center;
|
|
172
|
+
border-top: 1px solid var(--textColor);
|
|
173
|
+
cursor: pointer;
|
|
174
|
+
display: -webkit-box;
|
|
175
|
+
display: -ms-flexbox;
|
|
176
|
+
display: flex;
|
|
177
|
+
font-weight: 600;
|
|
178
|
+
// height: 45px;
|
|
179
|
+
// padding: 0 10px;
|
|
180
|
+
-webkit-transition: all .3s;
|
|
181
|
+
transition: all .3s;
|
|
182
|
+
|
|
183
|
+
background: var(--backgroundColor);
|
|
184
|
+
font-family: 'Muli', sans-serif;
|
|
185
|
+
font-size: var(--buttonFontSize);
|
|
186
|
+
-o-text-overflow: ellipsis;
|
|
187
|
+
text-overflow: ellipsis;
|
|
188
|
+
// // white-space: nowrap;
|
|
189
|
+
word-wrap: break-word;
|
|
190
|
+
letter-spacing: -0.24px;
|
|
191
|
+
-webkit-font-smoothing: antialiased;
|
|
192
|
+
color: var(--textColor);
|
|
193
|
+
line-height: 16px;
|
|
194
|
+
padding: 8px 16px!important;
|
|
195
|
+
|
|
196
|
+
&:focus,
|
|
197
|
+
&:hover {
|
|
198
|
+
color: var(--hoverTextColor);
|
|
199
|
+
background: var(--hoverBackgroundColor);
|
|
200
|
+
// transform: scale(1.05);
|
|
201
|
+
.icon-button-action {
|
|
202
|
+
svg {
|
|
203
|
+
fill: var(--hoverTextColor);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
&:after {
|
|
208
|
+
content: "";
|
|
209
|
+
position: absolute;
|
|
210
|
+
width: 0;
|
|
211
|
+
height: 0;
|
|
212
|
+
top: 50%;
|
|
213
|
+
left: 50%;
|
|
214
|
+
transform-style: flat;
|
|
215
|
+
transform: translate3d(-50%,-50%,0);
|
|
216
|
+
background: rgba(white,.2);
|
|
217
|
+
border-radius: 100%;
|
|
218
|
+
transition: width .5s ease, height .5s ease;
|
|
219
|
+
}
|
|
220
|
+
&.active{
|
|
221
|
+
color: var(--hoverTextColor);
|
|
222
|
+
background: var(--hoverBackgroundColor);
|
|
223
|
+
.icon-button-action {
|
|
224
|
+
svg {
|
|
225
|
+
fill: var(--hoverTextColor);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.disabled {
|
|
234
|
+
// border: 1px solid #999999;
|
|
235
|
+
// background-color: #cccccc;
|
|
236
|
+
// color: #666666;
|
|
237
|
+
cursor: default;
|
|
238
|
+
pointer-events: none;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.single-button:last-child{
|
|
242
|
+
border-radius: 0px 0px 8px 8px;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.carousel .card span {
|
|
247
|
+
color: #6A6D78;
|
|
248
|
+
font-size: 1.31rem;
|
|
249
|
+
}
|
|
250
|
+
@media screen and (max-width: 900px) {
|
|
251
|
+
.wrapper .carousel {
|
|
252
|
+
grid-auto-columns: calc((100% / 2) - 9px);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
@media screen and (max-width: 600px) {
|
|
256
|
+
.wrapper .carousel {
|
|
257
|
+
grid-auto-columns: var(--cardWidth);
|
|
258
|
+
// grid-auto-columns: 17px repeat(var(--cardWidth)) 17px;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { CarouselComponent } from './carousel.component';
|
|
4
|
+
|
|
5
|
+
describe('CarouselComponent', () => {
|
|
6
|
+
let component: CarouselComponent;
|
|
7
|
+
let fixture: ComponentFixture<CarouselComponent>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
declarations: [ CarouselComponent ]
|
|
12
|
+
})
|
|
13
|
+
.compileComponents();
|
|
14
|
+
|
|
15
|
+
fixture = TestBed.createComponent(CarouselComponent);
|
|
16
|
+
component = fixture.componentInstance;
|
|
17
|
+
fixture.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
expect(component).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChange, SimpleChanges, ViewChildren } from '@angular/core';
|
|
2
|
+
import { MessageModel } from 'src/chat21-core/models/message';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'chat-carousel',
|
|
6
|
+
templateUrl: './carousel.component.html',
|
|
7
|
+
styleUrls: ['./carousel.component.scss']
|
|
8
|
+
})
|
|
9
|
+
export class CarouselComponent implements OnInit{
|
|
10
|
+
|
|
11
|
+
// ========= begin:: Input/Output values ============//
|
|
12
|
+
@Input() message: MessageModel;
|
|
13
|
+
@Input() isConversationArchived: boolean;
|
|
14
|
+
@Input() isLastMessage: boolean;
|
|
15
|
+
@Input() stylesMap: Map<string, string>;
|
|
16
|
+
@Output() onAttachmentButtonClicked = new EventEmitter<any>();
|
|
17
|
+
@Output() onElementRendered = new EventEmitter<{element: string, status: boolean}>()
|
|
18
|
+
// ========= end:: Input/Output values ============//
|
|
19
|
+
gallery: any[]
|
|
20
|
+
|
|
21
|
+
wrapper: HTMLElement;
|
|
22
|
+
carousel: HTMLElement;
|
|
23
|
+
firstCardWidth: number;
|
|
24
|
+
activeElement: number = 1;
|
|
25
|
+
|
|
26
|
+
fontSize: string;
|
|
27
|
+
backgroundColor: string;
|
|
28
|
+
textColor: string;
|
|
29
|
+
hoverBackgroundColor: string;
|
|
30
|
+
hoverTextColor: string;
|
|
31
|
+
type: string;
|
|
32
|
+
button: any;
|
|
33
|
+
|
|
34
|
+
constructor(private elementRef: ElementRef) { }
|
|
35
|
+
|
|
36
|
+
ngOnInit() {
|
|
37
|
+
console.log('[CAROUSEL-MESSAGE] hello', this.message)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
this.wrapper = this.elementRef.nativeElement.querySelector('.wrapper')
|
|
41
|
+
this.carousel = this.elementRef.nativeElement.querySelector('.carousel')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// this.firstCardWidth = (this.elementRef.nativeElement.querySelector(".card") as HTMLElement).offsetWidth
|
|
45
|
+
// // Get the number of cards that can fit in the carousel at once
|
|
46
|
+
// let cardPerView = Math.round(this.carousel.offsetWidth / this.firstCardWidth);
|
|
47
|
+
|
|
48
|
+
// Insert copies of the last few cards to beginning of carousel for infinite scrolling
|
|
49
|
+
// const carouselChildrens = [...this.carousel.children];
|
|
50
|
+
// carouselChildrens.slice(-cardPerView).reverse().forEach(card => {
|
|
51
|
+
// this.carousel.insertAdjacentHTML("afterbegin", card.outerHTML);
|
|
52
|
+
// });
|
|
53
|
+
// // Insert copies of the first few cards to end of carousel for infinite scrolling
|
|
54
|
+
// carouselChildrens.slice(0, cardPerView).forEach(card => {
|
|
55
|
+
// this.carousel.insertAdjacentHTML("beforeend", card.outerHTML);
|
|
56
|
+
// });
|
|
57
|
+
|
|
58
|
+
// Scroll the carousel at appropriate postition to hide first few duplicate cards on Firefox
|
|
59
|
+
this.carousel.classList.add("no-transition");
|
|
60
|
+
this.carousel.scrollLeft = this.carousel.offsetWidth;
|
|
61
|
+
this.carousel.classList.remove("no-transition");
|
|
62
|
+
|
|
63
|
+
let currentItem = 0
|
|
64
|
+
// Store items as an array of objects
|
|
65
|
+
const items = this.carousel.querySelectorAll('.card')
|
|
66
|
+
|
|
67
|
+
this.carousel.addEventListener("scroll", function(el){
|
|
68
|
+
// Find item closest to the goal
|
|
69
|
+
// currentItem = items.reduce((prev, curr) => {
|
|
70
|
+
// return (Math.abs(curr.offsetY - scrollY - goal) < Math.abs(prev.offsetY - scrollY - goal) ? curr : prev); // return the closest to the goal
|
|
71
|
+
// });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
ngOnChanges(changes: SimpleChanges){
|
|
77
|
+
if(this.message && this.message.attributes && this.message.attributes?.attachment && this.message.attributes?.attachment?.gallery){
|
|
78
|
+
this.gallery = this.message.attributes.attachment.gallery
|
|
79
|
+
console.log('carrrrrrrrr', this.wrapper, this.elementRef.nativeElement.querySelector(".card"))
|
|
80
|
+
// this.firstCardWidth = (this.elementRef.nativeElement.querySelector(".card") as HTMLElement).offsetWidth
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if(this.stylesMap ){
|
|
84
|
+
if(this.stylesMap.has('buttonFontSize')) this.elementRef.nativeElement.querySelector('.wrapper').style.setProperty('--buttonFontSize', this.stylesMap.get('buttonFontSize'));
|
|
85
|
+
if(this.stylesMap.has('buttonBackgroundColor')) this.elementRef.nativeElement.querySelector('.wrapper').style.setProperty('--backgroundColor', this.stylesMap.get('buttonBackgroundColor'));
|
|
86
|
+
if(this.stylesMap.has('buttonTextColor')) this.elementRef.nativeElement.querySelector('.wrapper').style.setProperty('--textColor', this.stylesMap.get('buttonTextColor'));
|
|
87
|
+
if(this.stylesMap.has('buttonHoverBackgroundColor')) this.elementRef.nativeElement.querySelector('.wrapper').style.setProperty('--hoverBackgroundColor', this.stylesMap.get('buttonHoverBackgroundColor'));
|
|
88
|
+
if(this.stylesMap.has('buttonHoverTextColor')) this.elementRef.nativeElement.querySelector('.wrapper').style.setProperty('--hoverTextColor', this.stylesMap.get('buttonHoverTextColor'));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
goTo(direction: 'next' | 'previous' ){
|
|
94
|
+
let width = (this.carousel.querySelectorAll(".card")[1] as HTMLElement).offsetWidth
|
|
95
|
+
let gap = 17
|
|
96
|
+
let cardPerView = Math.round(this.carousel.offsetWidth / width);
|
|
97
|
+
|
|
98
|
+
console.log('go to -->', direction, width, this.firstCardWidth, cardPerView, this.carousel.offsetWidth)
|
|
99
|
+
|
|
100
|
+
// this.carousel.scrollLeft += direction == "previous" ? -(width+gap) : width+gap;
|
|
101
|
+
this.carousel.scrollLeft += direction == "previous" ? -width : width;
|
|
102
|
+
this.activeElement += direction == "previous" ? -1 : 1;
|
|
103
|
+
|
|
104
|
+
// this.carousel.classList.add("no-transition");
|
|
105
|
+
// this.carousel.scrollLeft += width;
|
|
106
|
+
// this.carousel.classList.remove("no-transition");
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
actionButtonClick(ev, button, index){
|
|
111
|
+
this.button = button
|
|
112
|
+
this.type = button.type
|
|
113
|
+
console.log('buttonnnnnnn', ev, button)
|
|
114
|
+
if ( button && ((button.action && button.action !== '') || (button.link && button.link !== '') || button.text !== '' )) {
|
|
115
|
+
|
|
116
|
+
//set clicked button as the active one
|
|
117
|
+
this.gallery[index].buttons.find((element)=> { return element === button}).active = true
|
|
118
|
+
const spanCheck = this.elementRef.nativeElement.querySelector('.action');
|
|
119
|
+
if (spanCheck) {
|
|
120
|
+
// const item = domRepresentation[0] as HTMLInputElement;
|
|
121
|
+
// if (!spanCheck.classList.contains('active')) {
|
|
122
|
+
// spanCheck.classList.add('active');
|
|
123
|
+
// }
|
|
124
|
+
// setTimeout(function() {
|
|
125
|
+
// if (spanCheck.classList.contains('active')) {
|
|
126
|
+
// spanCheck.classList.remove('active');
|
|
127
|
+
// }
|
|
128
|
+
// }, 400);
|
|
129
|
+
ev.target.classList.add('active')
|
|
130
|
+
// event.target.classList
|
|
131
|
+
}
|
|
132
|
+
const event = { target: this, currentTarget: this}
|
|
133
|
+
if ( event && event.target ) {
|
|
134
|
+
const ev = {target: event.target, message: this.message, currentTarget: this }
|
|
135
|
+
this.onAttachmentButtonClicked.emit(ev);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -507,6 +507,18 @@ export class GlobalSettingsService {
|
|
|
507
507
|
if (variables.hasOwnProperty('fileUploadAccept')) {
|
|
508
508
|
globals['fileUploadAccept'] = variables['fileUploadAccept'];
|
|
509
509
|
}
|
|
510
|
+
if (variables.hasOwnProperty('displayOnDesktop')) {
|
|
511
|
+
globals['displayOnDesktop'] = variables['displayOnDesktop'];
|
|
512
|
+
}
|
|
513
|
+
if (variables.hasOwnProperty('displayOnMobile')) {
|
|
514
|
+
globals['displayOnMobile'] = variables['displayOnMobile'];
|
|
515
|
+
}
|
|
516
|
+
if (variables.hasOwnProperty('onPageChangeVisibilityDesktop')) {
|
|
517
|
+
globals['onPageChangeVisibilityDesktop'] = variables['onPageChangeVisibilityDesktop'];
|
|
518
|
+
}
|
|
519
|
+
if (variables.hasOwnProperty('onPageChangeVisibilityMobile')) {
|
|
520
|
+
globals['onPageChangeVisibilityMobile'] = variables['onPageChangeVisibilityMobile'];
|
|
521
|
+
}
|
|
510
522
|
|
|
511
523
|
}
|
|
512
524
|
}
|
|
@@ -997,7 +1009,7 @@ export class GlobalSettingsService {
|
|
|
997
1009
|
TEMP = tiledeskSettings['participants'];
|
|
998
1010
|
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > participants:: ', TEMP]);
|
|
999
1011
|
if (TEMP !== undefined) {
|
|
1000
|
-
globals.participants = TEMP.split(',').map(key => { return key.trim()})
|
|
1012
|
+
globals.participants = TEMP.split(',').map(key => { return key.trim()});
|
|
1001
1013
|
}
|
|
1002
1014
|
TEMP = tiledeskSettings['whatsappNumber'];
|
|
1003
1015
|
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > whatsappNumber:: ', TEMP]);
|
|
@@ -1023,6 +1035,26 @@ export class GlobalSettingsService {
|
|
|
1023
1035
|
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > disconnetTime:: ', TEMP]);
|
|
1024
1036
|
if (TEMP !== undefined) {
|
|
1025
1037
|
globals.disconnetTime = +TEMP;
|
|
1038
|
+
}
|
|
1039
|
+
TEMP = tiledeskSettings['displayOnDesktop'];
|
|
1040
|
+
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > displayOnDesktop:: ', TEMP]);
|
|
1041
|
+
if (TEMP !== undefined) {
|
|
1042
|
+
globals.displayOnDesktop = (TEMP === true) ? true : false;
|
|
1043
|
+
}
|
|
1044
|
+
TEMP = tiledeskSettings['displayOnMobile'];
|
|
1045
|
+
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > displayOnMobile:: ', TEMP]);
|
|
1046
|
+
if (TEMP !== undefined) {
|
|
1047
|
+
globals.displayOnMobile = (TEMP === true) ? true : false;
|
|
1048
|
+
}
|
|
1049
|
+
TEMP = tiledeskSettings['onPageChangeVisibilityDesktop'];
|
|
1050
|
+
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > onPageChangeVisibilityDesktop:: ', TEMP]);
|
|
1051
|
+
if (TEMP !== undefined) {
|
|
1052
|
+
globals.onPageChangeVisibilityDesktop = TEMP;
|
|
1053
|
+
}
|
|
1054
|
+
TEMP = tiledeskSettings['onPageChangeVisibilityMobile'];
|
|
1055
|
+
// this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > onPageChangeVisibilityMobile:: ', TEMP]);
|
|
1056
|
+
if (TEMP !== undefined) {
|
|
1057
|
+
globals.onPageChangeVisibilityMobile = TEMP;
|
|
1026
1058
|
}
|
|
1027
1059
|
}
|
|
1028
1060
|
|
package/src/app/utils/globals.ts
CHANGED
|
@@ -213,6 +213,11 @@ export class Globals {
|
|
|
213
213
|
telegramUsername: string; // ******* new ********
|
|
214
214
|
fileUploadAccept: string; // ******* new ********
|
|
215
215
|
disconnetTime: number; // ******* new ********
|
|
216
|
+
|
|
217
|
+
onPageChangeVisibilityMobile: 'open' | 'close' | 'last'; // ******* new ********
|
|
218
|
+
onPageChangeVisibilityDesktop: 'open' | 'close' | 'last'; // ******* new ********
|
|
219
|
+
displayOnMobile: boolean; // ******* new ********
|
|
220
|
+
displayOnDesktop: boolean; // ******* new ********
|
|
216
221
|
constructor(
|
|
217
222
|
) { }
|
|
218
223
|
|
|
@@ -402,6 +407,14 @@ export class Globals {
|
|
|
402
407
|
this.showAttachmentButton = true;
|
|
403
408
|
this.showAllConversations = true;
|
|
404
409
|
|
|
410
|
+
//WIDGET VISIBILITY - desktop
|
|
411
|
+
this.displayOnDesktop = true
|
|
412
|
+
this.onPageChangeVisibilityDesktop ='close'
|
|
413
|
+
//WIDGET VISIBILITY - mobile
|
|
414
|
+
this.displayOnMobile = true
|
|
415
|
+
this.onPageChangeVisibilityMobile = 'close'
|
|
416
|
+
|
|
417
|
+
|
|
405
418
|
// ============ END: SET EXTERNAL PARAMETERS ==============//
|
|
406
419
|
|
|
407
420
|
|
|
@@ -105,14 +105,14 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
105
105
|
this.logger.debug('[FIREBASEConversationHandlerSERVICE] urlNodeFirebase *****', this.urlNodeFirebase);
|
|
106
106
|
const firebaseMessages = this.firebase.database().ref(this.urlNodeFirebase);
|
|
107
107
|
this.ref = firebaseMessages.orderByChild('timestamp').limitToLast(100);
|
|
108
|
-
this.ref.on('child_added', (childSnapshot) => {
|
|
108
|
+
this.ref.on('child_added', async (childSnapshot) => {
|
|
109
109
|
that.logger.debug('[FIREBASEConversationHandlerSERVICE] >>>>>>>>>>>>>> child_added: ', childSnapshot.val())
|
|
110
110
|
const msg: MessageModel = childSnapshot.val();
|
|
111
111
|
msg.uid = childSnapshot.key;
|
|
112
112
|
|
|
113
113
|
if (msg.attributes && msg.attributes.commands) {
|
|
114
114
|
this.logger.debug('[FIREBASEConversationHandlerSERVICE] splitted message::::', msg)
|
|
115
|
-
that.addCommandMessage(msg)
|
|
115
|
+
await that.addCommandMessage(msg)
|
|
116
116
|
} else {
|
|
117
117
|
this.logger.debug('[FIREBASEConversationHandlerSERVICE] NOT splitted message::::', msg)
|
|
118
118
|
that.addedNew(msg)
|
|
@@ -255,6 +255,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
255
255
|
|
|
256
256
|
|
|
257
257
|
|
|
258
|
+
|
|
258
259
|
this.addRepalceMessageInArray(msg.uid, msg);
|
|
259
260
|
this.messageAdded.next(msg);
|
|
260
261
|
} else {
|
|
@@ -468,59 +469,63 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
|
|
471
|
-
private addCommandMessage(msg: MessageModel){
|
|
472
|
+
private async addCommandMessage(msg: MessageModel): Promise<boolean> {
|
|
472
473
|
const that = this;
|
|
473
474
|
const commands = msg.attributes.commands;
|
|
474
475
|
let i=0;
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
that.generateMessageObject(msg, command.message, function () {
|
|
498
|
-
i += 1
|
|
499
|
-
if (i < commands.length) {
|
|
500
|
-
execute(commands[i])
|
|
476
|
+
return new Promise((resolve, reject)=>{
|
|
477
|
+
function execute(command){
|
|
478
|
+
if(command.type === "message"){
|
|
479
|
+
that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
|
|
480
|
+
if (i >= 2) {
|
|
481
|
+
|
|
482
|
+
//check if previus wait message type has time value, otherwize set to 1000ms
|
|
483
|
+
!commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
|
|
484
|
+
command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
|
|
485
|
+
|
|
486
|
+
/** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
|
|
487
|
+
if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
|
|
488
|
+
let previewsTimeMsg = msg.timestamp;
|
|
489
|
+
commands[i-2]? previewsTimeMsg = commands[i-2].message.timestamp : null;
|
|
490
|
+
command.message.timestamp = previewsTimeMsg + 100
|
|
491
|
+
commands[i+1]? commands[i+1].time = 0 : null
|
|
492
|
+
}
|
|
493
|
+
} else { /**MANAGE FIRST MESSAGE */
|
|
494
|
+
command.message.timestamp = msg.timestamp;
|
|
495
|
+
if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
|
|
496
|
+
commands[i+1]? commands[i+1].time = 0 : null
|
|
497
|
+
}
|
|
501
498
|
}
|
|
502
|
-
|
|
503
|
-
|
|
499
|
+
that.generateMessageObject(msg, command.message, function () {
|
|
500
|
+
i += 1
|
|
501
|
+
if (i < commands.length) {
|
|
502
|
+
execute(commands[i])
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (wait), exit')
|
|
506
|
+
resolve(true)
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
}else if(command.type === "wait"){
|
|
510
|
+
that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
|
|
511
|
+
//publish waiting event to simulate user typing
|
|
512
|
+
if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
|
|
513
|
+
that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
|
|
504
514
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
515
|
+
setTimeout(function() {
|
|
516
|
+
i += 1
|
|
517
|
+
if (i < commands.length) {
|
|
518
|
+
execute(commands[i])
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
|
|
522
|
+
resolve(true)
|
|
523
|
+
}
|
|
524
|
+
},command.time)
|
|
511
525
|
}
|
|
512
|
-
setTimeout(function() {
|
|
513
|
-
i += 1
|
|
514
|
-
if (i < commands.length) {
|
|
515
|
-
execute(commands[i])
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
|
|
519
|
-
}
|
|
520
|
-
},command.time)
|
|
521
526
|
}
|
|
522
|
-
|
|
523
|
-
|
|
527
|
+
execute(commands[0]) //START render first message
|
|
528
|
+
})
|
|
524
529
|
}
|
|
525
530
|
|
|
526
531
|
private generateMessageObject(message, command_message, callback) {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
MAX_WIDTH_IMAGES,
|
|
9
9
|
CHANNEL_TYPE_GROUP,
|
|
10
10
|
TYPE_SUPPORT_GROUP
|
|
11
|
-
} from '
|
|
11
|
+
} from './constants';
|
|
12
12
|
|
|
13
13
|
/** */
|
|
14
14
|
export function isImage(message: any) {
|
|
@@ -27,14 +27,14 @@ export function isFrame(message: any) {
|
|
|
27
27
|
|
|
28
28
|
/** */
|
|
29
29
|
export function isFile(message: any) {
|
|
30
|
-
if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && !message.metadata.includes('audio')) {
|
|
30
|
+
if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && !message.metadata.type.includes('audio')) {
|
|
31
31
|
return true;
|
|
32
32
|
}
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function isAudio(message: any) {
|
|
37
|
-
if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && message.metadata.includes('audio') ) {
|
|
37
|
+
if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && message.metadata.type.includes('audio') ) {
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
return false;
|