@chat21/chat21-web-widget 5.0.66 → 5.0.68

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 (26) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +1 -1
  3. package/src/app/app.component.ts +12 -9
  4. package/src/app/app.module.ts +6 -1
  5. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +10 -0
  6. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +4 -0
  7. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.html +11 -1
  8. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.scss +8 -0
  9. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.ts +24 -2
  10. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +6 -5
  11. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +12 -5
  12. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.ts +3 -2
  13. package/src/app/component/message/audio/audio.component.html +20 -0
  14. package/src/app/component/message/audio/audio.component.scss +122 -0
  15. package/src/app/component/message/audio/audio.component.spec.ts +23 -0
  16. package/src/app/component/message/audio/audio.component.ts +123 -0
  17. package/src/app/component/message/bubble-message/bubble-message.component.html +5 -0
  18. package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
  19. package/src/app/component/message/carousel/carousel.component.html +29 -0
  20. package/src/app/component/message/carousel/carousel.component.scss +257 -0
  21. package/src/app/component/message/carousel/carousel.component.spec.ts +23 -0
  22. package/src/app/component/message/carousel/carousel.component.ts +111 -0
  23. package/src/app/providers/global-settings.service.ts +1 -1
  24. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +53 -48
  25. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +61 -54
  26. package/src/chat21-core/utils/utils-message.ts +14 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # chat21-web-widget ver 5.0
2
2
 
3
+ ### 5.0.68 in PROD
4
+ - bug-fixed: metadata.includes is not a function at isAudio function
5
+
6
+ ### 5.0.67 in PROD
7
+ - bug-fixed: when refresh the page and an already open conversation is selected, footer is blocked
8
+ - bug-fix: pdf preview image is not contained into its container
9
+ - bug-fixed: cannot push isHere() for presence management if user is disconnected and a notification is received
10
+
3
11
  ### 5.0.66 in PROD
4
12
  - added: LWT e imHere() for presence management
5
13
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-web-widget",
3
3
  "author": "Tiledesk SRL",
4
- "version": "5.0.66",
4
+ "version": "5.0.68",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -432,7 +432,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
432
432
 
433
433
  const subUserLogOut = this.messagingAuthService.BSSignOut.subscribe((state) => {
434
434
  // that.ngZone.run(() => {
435
- console.log('[FORCE] messagingAuthService BSSignOut', state, this.forceDisconnect)
435
+ this.logger.log('[FORCE] messagingAuthService BSSignOut', state, this.forceDisconnect)
436
436
  if (state === true && !this.forceDisconnect) { //state = true -> user has logged out
437
437
  /** ho effettuato il logout: nascondo il widget */
438
438
  that.logger.debug('[APP-COMP] sono nel caso logout -1');
@@ -1507,7 +1507,9 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1507
1507
  // this.g.windowContext.window.document.title = this.tabTitle
1508
1508
  } else {
1509
1509
  // TAB IS ACTIVE --> restore title and DO NOT SOUND
1510
- this.presenceService.imHere()
1510
+ if(!this.forceDisconnect){
1511
+ this.presenceService.imHere()
1512
+ }
1511
1513
  clearInterval(this.setIntervalTime)
1512
1514
  this.setIntervalTime = null;
1513
1515
  this.isTabVisible = true;
@@ -1587,7 +1589,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1587
1589
  this.logger.debug('[APP-COMP] openCloseWidget', recipientId, this.g.isOpen, this.g.startFromHome);
1588
1590
  if (this.g.isOpen === false) {
1589
1591
  if(this.forceDisconnect){
1590
- console.log('[FORCE] onOpenCloseWidget --> reconnect', this.forceDisconnect)
1592
+ this.logger.log('[FORCE] onOpenCloseWidget --> reconnect', this.forceDisconnect)
1591
1593
  this.messagingAuthService.createCustomToken(this.g.tiledeskToken)
1592
1594
  this.forceDisconnect = false;
1593
1595
  }
@@ -1729,7 +1731,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1729
1731
  if (this.g.isOpen === false) {
1730
1732
 
1731
1733
  if(this.forceDisconnect){
1732
- console.log('[FORCE] onSelectedConversation --> reconnect', this.forceDisconnect)
1734
+ this.logger.log('[FORCE] onSelectedConversation --> reconnect', this.forceDisconnect)
1733
1735
  this.messagingAuthService.createCustomToken(this.g.tiledeskToken)
1734
1736
  this.forceDisconnect = false;
1735
1737
  }
@@ -2095,14 +2097,15 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
2095
2097
 
2096
2098
 
2097
2099
  private listenToWidgetClick(){
2100
+ const that = this
2098
2101
  let clickTimeout = setTimeout(() => {
2099
- console.log('[FORCE] --> NO INTERACTION: disconnection... <--- ')
2102
+ that.logger.log('[FORCE] --> NO INTERACTION: disconnection... <--- ')
2100
2103
  //disconnect
2101
- this.forceDisconnect = true
2102
- this.messagingAuthService.logout()
2103
- }, this.g.disconnetTime * 1000);
2104
+ that.forceDisconnect = true
2105
+ that.messagingAuthService.logout()
2106
+ }, that.g.disconnetTime * 1000);
2104
2107
  window.addEventListener("click", function(){
2105
- console.log('[FORCE] <<INTERACTION>> within 1 minute')
2108
+ that.logger.log('[FORCE] <<INTERACTION>> within 1 minute')
2106
2109
  clearTimeout(clickTimeout)
2107
2110
  })
2108
2111
  }
@@ -23,6 +23,7 @@ import { ImageComponent } from './component/message/image/image.component';
23
23
  import { InfoMessageComponent } from './component/message/info-message/info-message.component';
24
24
  import { HtmlComponent } from './component/message/html/html.component';
25
25
  import { FrameComponent } from './component/message/frame/frame.component';
26
+ import { AudioComponent } from './component/message/audio/audio.component';
26
27
  import { UserTypingComponent } from './../chat21-core/utils/user-typing/user-typing.component';
27
28
  /** MESSAGE ATTACHMENTS COMPONENTS */
28
29
  import { MessageAttachmentComponent } from './component/message-attachment/message-attachment.component';
@@ -130,6 +131,8 @@ import { StarRatingWidgetService } from './providers/star-rating-widget.service'
130
131
  import { LikeUnlikeComponent } from './component/message/like-unlike/like-unlike.component';
131
132
  import { Rules } from './utils/rules';
132
133
  import { ScriptService } from 'src/chat21-core/providers/scripts/script.service';
134
+ import { CarouselComponent } from './component/message/carousel/carousel.component';
135
+
133
136
 
134
137
 
135
138
  const appInitializerFn = (appConfig: AppConfigService, logger: NGXLogger) => {
@@ -287,7 +290,9 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
287
290
  DateAgoPipe,
288
291
  SafeHtmlPipe,
289
292
  LikeUnlikeComponent,
290
- TooltipDirective
293
+ TooltipDirective,
294
+ AudioComponent,
295
+ CarouselComponent
291
296
  ],
292
297
  imports: [
293
298
  BrowserModule,
@@ -107,6 +107,16 @@
107
107
  (onAttachmentButtonClicked)="onAttachmentButtonClickedFN($event)">
108
108
  </chat-message-attachment>
109
109
  </div>
110
+
111
+ <!-- carousel -->
112
+ <!-- <div *ngIf="message?.attributes && message?.attributes?.attachment && message?.attributes?.attachment?.gallery" [ngClass]="{'slide-in-left': false}" class="carousel_container">
113
+ <chat-carousel class="carousel_container"
114
+ [message]="message"
115
+ [stylesMap]="stylesMap"
116
+ (onElementRendered)="onElementRenderedFN($event)"
117
+ (onAttachmentButtonClicked)="onAttachmentButtonClickedFN($event)">
118
+ </chat-carousel>
119
+ </div> -->
110
120
 
111
121
  </div>
112
122
 
@@ -135,6 +135,10 @@
135
135
  align-content: center;
136
136
  justify-content: flex-end;
137
137
  }
138
+ .carousel_container{
139
+ margin: 0px 20px;
140
+ }
141
+
138
142
  .msg_info_container{
139
143
  text-align: center;
140
144
  padding: 0px 0px 6px 0px
@@ -1 +1,11 @@
1
- <p>conversation-emojii works!</p>
1
+ <emoji-mart id="emoji-mart"
2
+ class="emoji-mart"
3
+ [showPreview]="emojiiOptions?.showPreview"
4
+ [color]="stylesMap?.get('themeColor')"
5
+ [perLine]="emojiiOptions?.emojiPerLine"
6
+ [totalFrequentLines]="emojiiOptions?.totalFrequentLines"
7
+ [enableSearch]="emojiiOptions?.enableSearch"
8
+ [darkMode]="emojiiOptions?.darkMode"
9
+ [include]="emojiiOptions?.include"
10
+ (emojiSelect)="addEmojiFN($event)">
11
+ </emoji-mart>
@@ -0,0 +1,8 @@
1
+ .emoji-mart {
2
+ position: absolute;
3
+ // bottom: 40px;
4
+ // left: 10px;
5
+ border: none;
6
+ margin: -2px -2px 0px;
7
+
8
+ }
@@ -1,10 +1,32 @@
1
- import { Component } from '@angular/core';
1
+ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
2
 
3
3
  @Component({
4
4
  selector: 'chat-conversation-emojii',
5
5
  templateUrl: './conversation-emojii.component.html',
6
6
  styleUrls: ['./conversation-emojii.component.scss']
7
7
  })
8
- export class ConversationEmojiiComponent {
8
+ export class ConversationEmojiiComponent implements OnInit {
9
+
10
+ @Input() var: string;
11
+ @Output() addEmoji = new EventEmitter();
12
+
13
+ emojiiOptions = {
14
+ emojiPerLine : 9,
15
+ totalFrequentLines: 1,
16
+ showPreview: false,
17
+ darkMode: false,
18
+ enableSearch: false,
19
+ include: [ 'recent', 'people', 'nature', 'activity', 'flags']
20
+ }
21
+
22
+ constructor(){}
23
+
24
+ ngOnInit(): void {
25
+ console.log('varrrrr', this.var)
26
+ }
27
+
28
+ addEmojiFN(event){
29
+ this.addEmoji.emit(event)
30
+ }
9
31
 
10
32
  }
@@ -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" width="24" height="24" viewBox="0 0 28 28" >
35
- <path d="M0 0h24v24H0V0z" fill="none"/>
36
- <circle cx="15.5" cy="9.5" r="1.5"/>
37
- <circle cx="8.5" cy="9.5" r="1.5"/>
38
- <path d="M12 16c-1.48 0-2.75-.81-3.45-2H6.88c.8 2.05 2.79 3.5 5.12 3.5s4.32-1.45 5.12-3.5h-1.67c-.7 1.19-1.97 2-3.45 2zm-.01-14C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/>
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>
@@ -79,6 +79,7 @@
79
79
 
80
80
  <!-- EMOJII PICKER-->
81
81
  <div [style.visibility]="isEmojiiPickerShow?'visible':'hidden'" class="emoji-container" id="emoji-mart-container" #emoji_mart_container>
82
+ <!-- <ng-container #emojii_container></ng-container> -->
82
83
  <emoji-mart id="emoji-mart"
83
84
  *ngIf="showEmojiPicker"
84
85
  class="emoji-mart"
@@ -48,6 +48,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
48
48
  @Output() onBackButton = new EventEmitter()
49
49
 
50
50
  @ViewChild('chat21_file') public chat21_file: ElementRef;
51
+ // @ViewChild('emojii_container', {read: ViewContainerRef}) selector;
51
52
  @ViewChild('emoji_mart_container', {read: ViewContainerRef}) public divEmojiiContainer: ViewContainerRef;
52
53
  // ========= begin:: send image ======= //
53
54
  selectedFiles: FileList;
@@ -454,12 +455,18 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
454
455
  async onEmojiiPickerClicked(){
455
456
  // if(this.loadPickerModule){
456
457
  // this.loadPickerModule = false;
457
- // const { default: PickerModule} = await import("@ctrl/ngx-emoji-mart");
458
+ // // this.divEmojiiContainer.clear();
459
+ // this.vcref.clear();
460
+ // const { PickerModule } = await import("@ctrl/ngx-emoji-mart");
458
461
  // import('../conversation-emojii/conversation-emojii.component').then(({ConversationEmojiiComponent})=> {
459
- // this.divEmojiiContainer.clear();
460
- // const instance = this.divEmojiiContainer.createComponent(ConversationEmojiiComponent);
461
- // this.divEmojiiContainer.createEmbeddedView()
462
- // this.divEmojiiContainer.insert(instance.hostView);
462
+ // // const instance = this.divEmojiiContainer.createComponent(ConversationEmojiiComponent);
463
+ // // // this.divEmojiiContainer.createEmbeddedView(instance.hostView)
464
+ // // this.divEmojiiContainer.insert(instance.hostView);
465
+ // // this.divEmojiiContainer = this.selector.createComponent(ConversationEmojiiComponent);
466
+ // let greetcomp = this.vcref.createComponent(
467
+ // this.cfr.resolveComponentFactory(ConversationEmojiiComponent)
468
+ // );
469
+ // greetcomp.instance.var = 'ssssss'
463
470
  // });
464
471
  // // this.divEmojiiContainer.nativeElement.insertAdjacentHTML('afterbegin', '<emoji-mart id="emoji-mart"' +
465
472
  // // // '*ngIf="showEmojiPicker"'+
@@ -148,8 +148,8 @@ export class ConversationPreviewComponent implements OnInit {
148
148
  const metadata = {
149
149
  'name': imageXLoad.title,
150
150
  'src': that.sanitizer.bypassSecurityTrustUrl(imageXLoad.src),
151
- 'width': 80,
152
- 'height': 106,
151
+ 'width': '80px',
152
+ 'height': '106px',
153
153
  'type': attachment.metadata.type,
154
154
  'uid': attachment.metadata.uid
155
155
  };
@@ -158,6 +158,7 @@ export class ConversationPreviewComponent implements OnInit {
158
158
  that.arrayFiles.push({metadata});
159
159
  if (!that.fileSelected) {
160
160
  that.fileSelected = Object.assign({}, metadata)
161
+ that.fileSelected = Object.assign(that.fileSelected, that.getMetadataSize(that.fileSelected))
161
162
  }
162
163
  };
163
164
  }
@@ -0,0 +1,20 @@
1
+
2
+
3
+ <div id="audio_container" #audio_container>
4
+
5
+ <audio aria-label="traccia audio" #audio_msg controls controlsList="nodownload" id="audio_msg" (pause)="pauseAudioMsg($event)" (play)="playAudioMsg($event)" (timeupdate)="updateTimeAudioMsg($event)">
6
+ <source [src]="metadata?.src" [type]="metadata?.type">
7
+ <!-- {{metadata?.src}} -->
8
+ <!-- controlsList="nodownload" -->
9
+ </audio>
10
+
11
+ <!-- <button id="play-icon" (click)="onPlayPause('play')" *ngIf="status === 'play'">
12
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 8.64L15.27 12 10 15.36V8.64M8 5v14l11-7L8 5z"/></svg>
13
+ </button>
14
+ <button id="pause-icon" (click)="onPlayPause('pause')" *ngIf="status === 'pause'">
15
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
16
+ </button>
17
+ <div id="duration" #duration>0:00</div>
18
+ <input type="range" id="seek-slider" max="100" value="0"> -->
19
+ </div>
20
+
@@ -0,0 +1,122 @@
1
+ #audio_container{
2
+ display: flex;
3
+ }
4
+
5
+ #play-icon,
6
+ #pause-icon {
7
+ margin: 20px 2.5% 10px 2.5%;
8
+ }
9
+
10
+ .time {
11
+ display: inline-block;
12
+ width: 37px;
13
+ text-align: center;
14
+ font-size: 20px;
15
+ margin: 28.5px 0 18.5px 0;
16
+ float: left;
17
+ }
18
+ output {
19
+ display: inline-block;
20
+ width: 32px;
21
+ text-align: center;
22
+ font-size: 20px;
23
+ margin: 10px 2.5% 0 5%;
24
+ float: left;
25
+ clear: left;
26
+ }
27
+
28
+ input[type="range"] {
29
+ position: relative;
30
+ -webkit-appearance: none;
31
+ width: 48%;
32
+ margin: 0;
33
+ padding: 0;
34
+ height: 19px;
35
+ margin: 30px 2.5% 20px 2.5%;
36
+ float: left;
37
+ outline: none;
38
+ }
39
+ input[type="range"]::-webkit-slider-runnable-track {
40
+ width: 100%;
41
+ height: 3px;
42
+ cursor: pointer;
43
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
44
+ }
45
+ input[type="range"]::before {
46
+ position: absolute;
47
+ content: "";
48
+ top: 8px;
49
+ left: 0;
50
+ width: var(--seek-before-width);
51
+ height: 3px;
52
+ background-color: #007db5;
53
+ cursor: pointer;
54
+ }
55
+ input[type="range"]::-webkit-slider-thumb {
56
+ position: relative;
57
+ -webkit-appearance: none;
58
+ box-sizing: content-box;
59
+ border: 1px solid #007db5;
60
+ height: 15px;
61
+ width: 15px;
62
+ border-radius: 50%;
63
+ background-color: #fff;
64
+ cursor: pointer;
65
+ margin: -7px 0 0 0;
66
+ }
67
+ input[type="range"]:active::-webkit-slider-thumb {
68
+ transform: scale(1.2);
69
+ background: #007db5;
70
+ }
71
+ input[type="range"]::-moz-range-track {
72
+ width: 100%;
73
+ height: 3px;
74
+ cursor: pointer;
75
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
76
+ }
77
+ input[type="range"]::-moz-range-progress {
78
+ background-color: #007db5;
79
+ }
80
+ input[type="range"]::-moz-focus-outer {
81
+ border: 0;
82
+ }
83
+ input[type="range"]::-moz-range-thumb {
84
+ box-sizing: content-box;
85
+ border: 1px solid #007db5;
86
+ height: 15px;
87
+ width: 15px;
88
+ border-radius: 50%;
89
+ background-color: #fff;
90
+ cursor: pointer;
91
+ }
92
+ input[type="range"]:active::-moz-range-thumb {
93
+ transform: scale(1.2);
94
+ background: #007db5;
95
+ }
96
+ input[type="range"]::-ms-track {
97
+ width: 100%;
98
+ height: 3px;
99
+ cursor: pointer;
100
+ background: transparent;
101
+ border: solid transparent;
102
+ color: transparent;
103
+ }
104
+ input[type="range"]::-ms-fill-lower {
105
+ background-color: #007db5;
106
+ }
107
+ input[type="range"]::-ms-fill-upper {
108
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
109
+ }
110
+ input[type="range"]::-ms-thumb {
111
+ box-sizing: content-box;
112
+ border: 1px solid #007db5;
113
+ height: 15px;
114
+ width: 15px;
115
+ border-radius: 50%;
116
+ background-color: #fff;
117
+ cursor: pointer;
118
+ }
119
+ input[type="range"]:active::-ms-thumb {
120
+ transform: scale(1.2);
121
+ background: #007db5;
122
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { AudioComponent } from './audio.component';
4
+
5
+ describe('AudioComponent', () => {
6
+ let component: AudioComponent;
7
+ let fixture: ComponentFixture<AudioComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ AudioComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(AudioComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,123 @@
1
+ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
2
+ // import lottieWeb from 'https://cdn.skypack.dev/lottie-web';
3
+
4
+ @Component({
5
+ selector: 'chat-audio',
6
+ templateUrl: './audio.component.html',
7
+ styleUrls: ['./audio.component.scss']
8
+ })
9
+ export class AudioComponent implements OnInit {
10
+
11
+ @Input() metadata: any;
12
+ @Output() onElementRendered = new EventEmitter<{element: string, status: boolean}>();
13
+
14
+ uidAudioPlayng: string = ''
15
+ divPlay: HTMLAudioElement
16
+ playState: HTMLElement
17
+ status: 'play' | 'pause' = 'play'
18
+
19
+ constructor(private elementRef: ElementRef) { }
20
+
21
+ ngOnInit() {
22
+ // console.log('metadataaaaaa', this.metadata)
23
+ // this.divPlay = this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#audio_msg')
24
+ // this.playState= this.elementRef.nativeElement.querySelector('#audio_container').querySelector('#duration')
25
+ }
26
+
27
+ onPlayPause(status: string){
28
+ // const divPlay = (<HTMLAudioElement>document.getElementById('audio_msg'));
29
+ if(status === 'play') {
30
+ this.divPlay.play();
31
+ this.status = 'pause'
32
+ } else {
33
+ this.divPlay.pause();
34
+ this.status = 'play'
35
+ }
36
+ }
37
+
38
+ pauseAudioMsg(e) {
39
+ try {
40
+ // stop all audio
41
+ if (this.uidAudioPlayng) {
42
+ const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
43
+ divPlay.pause();
44
+ // console.log('> pausa: ', divPlay);
45
+ }
46
+ } catch (error) {
47
+ console.log('> Error is: ', error);
48
+ }
49
+
50
+ try {
51
+ // console.log(e.target.id);
52
+ if (this.uidAudioPlayng) {
53
+ this.uidAudioPlayng = '';
54
+ }
55
+ } catch (error) {
56
+ console.log('> Error is: ', error);
57
+ }
58
+ }
59
+
60
+ playAudioMsg(e) {
61
+ // stop all audio
62
+ if (this.uidAudioPlayng) {
63
+ const divPlay = (<HTMLAudioElement>document.getElementById(this.uidAudioPlayng));
64
+ divPlay.pause();
65
+ // console.log('> pausa: ', divPlay);
66
+ }
67
+ try {
68
+ // console.log(e.target.id);
69
+ // set uid audio playng
70
+ this.uidAudioPlayng = e.target.id;
71
+ } catch (error) {
72
+ console.log('> Error is: ', error);
73
+ }
74
+ }
75
+
76
+ updateTimeAudioMsg(ev){
77
+ var currTime = Math.floor(ev.target.currentTime);
78
+ var duration = Math.floor(ev.target.duration);
79
+
80
+ let minutes = 0;
81
+ if(currTime > 60){
82
+ minutes = Math.floor(currTime / 60);
83
+ }
84
+ const seconds = currTime - minutes * 60
85
+ // console.log('timeeee', minutes + ':' + seconds )
86
+ // this.playState.innerHTML = minutes + ':' + seconds
87
+ }
88
+
89
+
90
+
91
+ /**
92
+ *
93
+ * @param uid
94
+ */
95
+ playPausaAudioMsg(uid: string) {
96
+ // console.log('playPausaAudioMsg: ', uid);
97
+ const that = this;
98
+ try {
99
+ const divPause = (<HTMLAudioElement>document.getElementById(that.uidAudioPlayng));
100
+ const divPlay = (<HTMLAudioElement>document.getElementById(uid));
101
+ if (divPause) {
102
+ divPause.pause();
103
+ }
104
+
105
+ if (that.uidAudioPlayng === uid) {
106
+ that.uidAudioPlayng = '';
107
+ } else {
108
+ if (divPlay) {
109
+ setTimeout(function() {
110
+ // if (that.g.autoplay_activated) {
111
+ // divPlay.play();
112
+ // }
113
+ this.uidAudioPlayng = uid;
114
+ }, 300);
115
+ }
116
+ }
117
+
118
+ } catch (error) {
119
+ console.log('> Error is: ', error);
120
+ }
121
+ }
122
+
123
+ }
@@ -36,6 +36,11 @@
36
36
  (onElementRendered)="onElementRenderedFN($event)">
37
37
  </chat-frame>
38
38
 
39
+ <chat-audio *ngIf="isAudio(message)"
40
+ [metadata]="message.metadata"
41
+ (onElementRendered)="onElementRenderedFN($event)">
42
+ </chat-audio>
43
+
39
44
  <!-- <chat-frame *ngIf="message.metadata && message.metadata.type && message.metadata.type.includes('video')"
40
45
  [metadata]="message.metadata"
41
46
  [width]="message.metadata.width"
@@ -5,7 +5,7 @@ import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service
5
5
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
6
6
  import { MAX_WIDTH_IMAGES, MESSAGE_TYPE_MINE, MESSAGE_TYPE_OTHERS, MIN_WIDTH_IMAGES } from 'src/chat21-core/utils/constants';
7
7
  import { convertColorToRGBA } from 'src/chat21-core/utils/utils';
8
- import { isFile, isFrame, isImage, messageType } from 'src/chat21-core/utils/utils-message';
8
+ import { isAudio, isFile, isFrame, isImage, messageType } from 'src/chat21-core/utils/utils-message';
9
9
  import { getColorBck } from 'src/chat21-core/utils/utils-user';
10
10
 
11
11
  @Component({
@@ -27,6 +27,7 @@ export class BubbleMessageComponent implements OnInit {
27
27
  isImage = isImage;
28
28
  isFile = isFile;
29
29
  isFrame = isFrame;
30
+ isAudio = isAudio;
30
31
  convertColorToRGBA = convertColorToRGBA
31
32
 
32
33
  // ========== begin:: check message type functions ======= //
@@ -0,0 +1,29 @@
1
+ <div class="wrapper">
2
+ <div id="left" class="arrow" (click)="goTo('previous')" >
3
+ <!-- *ngIf="activeElement > 1" -->
4
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
5
+ <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"/>
6
+ </svg>
7
+ </div>
8
+ <div class="carousel">
9
+ <div class="card" *ngFor="let card of gallery">
10
+ <div class="card-image">
11
+ <img [src]="card?.preview?.src" alt="img" draggable="false">
12
+ </div>
13
+ <div class="card-content">
14
+ <div class="card-title">{{card?.title}}</div>
15
+ <div class="card-description">{{card?.description}}</div>
16
+ </div>
17
+ <div class="buttons" *ngIf="card?.buttons && card?.buttons.length > 0">
18
+ <div class="single-button action" *ngFor="let button of card?.buttons">
19
+ <div>{{button.value}}</div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ <div id="right" class="arrow" (click)="goTo('next')" *ngIf="activeElement !== gallery.length">
25
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
26
+ <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"/>
27
+ </svg>
28
+ </div>
29
+ </div>