@chat21/chat21-web-widget 5.0.65 → 5.0.67

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 (22) 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 +4 -1
  5. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.html +11 -0
  6. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.scss +8 -0
  7. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.spec.ts +23 -0
  8. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.ts +32 -0
  9. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +2 -1
  10. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +34 -3
  11. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.ts +3 -2
  12. package/src/app/component/message/audio/audio.component.html +20 -0
  13. package/src/app/component/message/audio/audio.component.scss +118 -0
  14. package/src/app/component/message/audio/audio.component.spec.ts +23 -0
  15. package/src/app/component/message/audio/audio.component.ts +123 -0
  16. package/src/app/component/message/bubble-message/bubble-message.component.html +5 -0
  17. package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
  18. package/src/app/utils/globals.ts +1 -1
  19. package/src/assets/js/chat21client.js +6 -6
  20. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +63 -56
  21. package/src/chat21-core/providers/mqtt/mqtt-presence.service.ts +3 -3
  22. package/src/chat21-core/utils/utils-message.ts +13 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # chat21-web-widget ver 5.0
2
2
 
3
+ ### 5.0.67 in PROD
4
+ - bug-fixed: when refresh the page and an already open conversation is selected, footer is blocked
5
+ - bug-fix: pdf preview image is not contained into its container
6
+ - bug-fixed: cannot push isHere() for presence management if user is disconnected and a notification is received
7
+
8
+ ### 5.0.66 in PROD
9
+ - added: LWT e imHere() for presence management
10
+
3
11
  ### 5.0.65 in PROD
4
12
 
5
13
  ### 5.0.65-rc.1
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.65",
4
+ "version": "5.0.67",
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';
@@ -132,6 +133,7 @@ import { Rules } from './utils/rules';
132
133
  import { ScriptService } from 'src/chat21-core/providers/scripts/script.service';
133
134
 
134
135
 
136
+
135
137
  const appInitializerFn = (appConfig: AppConfigService, logger: NGXLogger) => {
136
138
  return () => {
137
139
  let customLogger = new CustomLogger(logger)
@@ -287,7 +289,8 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
287
289
  DateAgoPipe,
288
290
  SafeHtmlPipe,
289
291
  LikeUnlikeComponent,
290
- TooltipDirective
292
+ TooltipDirective,
293
+ AudioComponent
291
294
  ],
292
295
  imports: [
293
296
  BrowserModule,
@@ -0,0 +1,11 @@
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
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ConversationEmojiiComponent } from './conversation-emojii.component';
4
+
5
+ describe('ConversationEmojiiComponent', () => {
6
+ let component: ConversationEmojiiComponent;
7
+ let fixture: ComponentFixture<ConversationEmojiiComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ ConversationEmojiiComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ConversationEmojiiComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,32 @@
1
+ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'chat-conversation-emojii',
5
+ templateUrl: './conversation-emojii.component.html',
6
+ styleUrls: ['./conversation-emojii.component.scss']
7
+ })
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
+ }
31
+
32
+ }
@@ -78,7 +78,8 @@
78
78
 
79
79
 
80
80
  <!-- EMOJII PICKER-->
81
- <div [style.visibility]="isEmojiiPickerShow?'visible':'hidden'" class="emoji-container">
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"
@@ -1,4 +1,4 @@
1
- import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
1
+ import { Component, ComponentFactoryResolver, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core';
2
2
  import { Globals } from 'src/app/utils/globals';
3
3
  import { MessageModel } from 'src/chat21-core/models/message';
4
4
  import { UploadModel } from 'src/chat21-core/models/upload';
@@ -48,7 +48,8 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
48
48
  @Output() onBackButton = new EventEmitter()
49
49
 
50
50
  @ViewChild('chat21_file') public chat21_file: ElementRef;
51
-
51
+ // @ViewChild('emojii_container', {read: ViewContainerRef}) selector;
52
+ @ViewChild('emoji_mart_container', {read: ViewContainerRef}) public divEmojiiContainer: ViewContainerRef;
52
53
  // ========= begin:: send image ======= //
53
54
  selectedFiles: FileList;
54
55
  isFilePendingToUpload: Boolean = false;
@@ -62,6 +63,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
62
63
  conversationHandlerService: ConversationHandlerService
63
64
 
64
65
  showEmojiPicker: boolean = false; //To show/hide emoji picker
66
+ loadPickerModule: boolean = true;
65
67
  emojiiOptions = {
66
68
  emojiPerLine : 9,
67
69
  totalFrequentLines: 1,
@@ -450,7 +452,36 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
450
452
  }
451
453
  }
452
454
 
453
- onEmojiiPickerClicked(){
455
+ async onEmojiiPickerClicked(){
456
+ // if(this.loadPickerModule){
457
+ // this.loadPickerModule = false;
458
+ // // this.divEmojiiContainer.clear();
459
+ // this.vcref.clear();
460
+ // const { PickerModule } = await import("@ctrl/ngx-emoji-mart");
461
+ // import('../conversation-emojii/conversation-emojii.component').then(({ConversationEmojiiComponent})=> {
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'
470
+ // });
471
+ // // this.divEmojiiContainer.nativeElement.insertAdjacentHTML('afterbegin', '<emoji-mart id="emoji-mart"' +
472
+ // // // '*ngIf="showEmojiPicker"'+
473
+ // // 'class="emoji-mart"'+
474
+ // // '[showPreview]="emojiiOptions?.showPreview"'+
475
+ // // // '[color]="stylesMap?.get("themeColor")"' +
476
+ // // '[perLine]="emojiiOptions?.emojiPerLine"'+
477
+ // // '[totalFrequentLines]="emojiiOptions?.totalFrequentLines"'+
478
+ // // '[enableSearch]="emojiiOptions?.enableSearch"'+
479
+ // // '[darkMode]="emojiiOptions?.darkMode"'+
480
+ // // '[include]="emojiiOptions?.include"'+
481
+ // // '(emojiSelect)="addEmoji($event)">'+
482
+ // // '</emoji-mart>')
483
+
484
+ // }
454
485
  //OPEN EMOJII PICKER
455
486
  this.onEmojiiPickerShow.emit(!this.isEmojiiPickerShow)
456
487
  }
@@ -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,118 @@
1
+ #play-icon,
2
+ #pause-icon {
3
+ margin: 20px 2.5% 10px 2.5%;
4
+ }
5
+
6
+ .time {
7
+ display: inline-block;
8
+ width: 37px;
9
+ text-align: center;
10
+ font-size: 20px;
11
+ margin: 28.5px 0 18.5px 0;
12
+ float: left;
13
+ }
14
+ output {
15
+ display: inline-block;
16
+ width: 32px;
17
+ text-align: center;
18
+ font-size: 20px;
19
+ margin: 10px 2.5% 0 5%;
20
+ float: left;
21
+ clear: left;
22
+ }
23
+
24
+ input[type="range"] {
25
+ position: relative;
26
+ -webkit-appearance: none;
27
+ width: 48%;
28
+ margin: 0;
29
+ padding: 0;
30
+ height: 19px;
31
+ margin: 30px 2.5% 20px 2.5%;
32
+ float: left;
33
+ outline: none;
34
+ }
35
+ input[type="range"]::-webkit-slider-runnable-track {
36
+ width: 100%;
37
+ height: 3px;
38
+ cursor: pointer;
39
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
40
+ }
41
+ input[type="range"]::before {
42
+ position: absolute;
43
+ content: "";
44
+ top: 8px;
45
+ left: 0;
46
+ width: var(--seek-before-width);
47
+ height: 3px;
48
+ background-color: #007db5;
49
+ cursor: pointer;
50
+ }
51
+ input[type="range"]::-webkit-slider-thumb {
52
+ position: relative;
53
+ -webkit-appearance: none;
54
+ box-sizing: content-box;
55
+ border: 1px solid #007db5;
56
+ height: 15px;
57
+ width: 15px;
58
+ border-radius: 50%;
59
+ background-color: #fff;
60
+ cursor: pointer;
61
+ margin: -7px 0 0 0;
62
+ }
63
+ input[type="range"]:active::-webkit-slider-thumb {
64
+ transform: scale(1.2);
65
+ background: #007db5;
66
+ }
67
+ input[type="range"]::-moz-range-track {
68
+ width: 100%;
69
+ height: 3px;
70
+ cursor: pointer;
71
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
72
+ }
73
+ input[type="range"]::-moz-range-progress {
74
+ background-color: #007db5;
75
+ }
76
+ input[type="range"]::-moz-focus-outer {
77
+ border: 0;
78
+ }
79
+ input[type="range"]::-moz-range-thumb {
80
+ box-sizing: content-box;
81
+ border: 1px solid #007db5;
82
+ height: 15px;
83
+ width: 15px;
84
+ border-radius: 50%;
85
+ background-color: #fff;
86
+ cursor: pointer;
87
+ }
88
+ input[type="range"]:active::-moz-range-thumb {
89
+ transform: scale(1.2);
90
+ background: #007db5;
91
+ }
92
+ input[type="range"]::-ms-track {
93
+ width: 100%;
94
+ height: 3px;
95
+ cursor: pointer;
96
+ background: transparent;
97
+ border: solid transparent;
98
+ color: transparent;
99
+ }
100
+ input[type="range"]::-ms-fill-lower {
101
+ background-color: #007db5;
102
+ }
103
+ input[type="range"]::-ms-fill-upper {
104
+ background: linear-gradient(to right, rgba(0, 125, 181, 0.6) var(--buffered-width), rgba(0, 125, 181, 0.2) var(--buffered-width));
105
+ }
106
+ input[type="range"]::-ms-thumb {
107
+ box-sizing: content-box;
108
+ border: 1px solid #007db5;
109
+ height: 15px;
110
+ width: 15px;
111
+ border-radius: 50%;
112
+ background-color: #fff;
113
+ cursor: pointer;
114
+ }
115
+ input[type="range"]:active::-ms-thumb {
116
+ transform: scale(1.2);
117
+ background: #007db5;
118
+ }
@@ -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 ======= //
@@ -389,7 +389,7 @@ export class Globals {
389
389
  /**enable user to set a telegram number to chat with */
390
390
  this.fileUploadAccept = "image/*,.pdf,.txt"
391
391
  /**enable auto disconnect from messaging after a defined amount of time (s)*/
392
- this.disconnetTime = 10
392
+ this.disconnetTime = 60
393
393
 
394
394
  this.showWaitTime = true;
395
395
 
@@ -979,12 +979,12 @@ class Chat21Client {
979
979
  // clean: true,
980
980
  reconnectPeriod: 1000,
981
981
  // connectTimeout: 30 * 1000,
982
- // will: {
983
- // topic: this.presence_topic,
984
- // payload: '{"disconnected":true}',
985
- // qos: 1,
986
- // retain: true
987
- // },
982
+ will: {
983
+ topic: this.presence_topic,
984
+ payload: '{"disconnected":true}',
985
+ qos: 1,
986
+ retain: true
987
+ },
988
988
  clientId: this.client_id,
989
989
  username: 'JWT',
990
990
  password: jwt,
@@ -101,11 +101,14 @@ export class MQTTConversationHandler extends ConversationHandlerService {
101
101
  this.logger.error('[MQTTConversationHandlerSERVICE] cant connect invalid this.conversationWith', this.conversationWith);
102
102
  return;
103
103
  }
104
- this.chat21Service.chatClient.lastMessages(this.conversationWith, (err, messages) => {
104
+ this.chat21Service.chatClient.lastMessages(this.conversationWith, async (err, messages) => {
105
105
  if (!err) {
106
106
  this.logger.log('[MQTTConversationHandlerSERVICE] message lastMessages:', messages);
107
107
  messages.sort(compareValues('timestamp', 'asc'));
108
- messages.forEach(async (message) => {
108
+ const that = this
109
+
110
+ // messages.forEach(async (message) => {
111
+ for (const message of messages){
109
112
  // this.addedMessage(msg);
110
113
  const msg: MessageModel = message;
111
114
  msg.uid = message.message_id;
@@ -115,18 +118,18 @@ export class MQTTConversationHandler extends ConversationHandlerService {
115
118
  return;
116
119
  }
117
120
 
118
- if (msg.attributes && msg.attributes.commands && msg.attributes.commands.lenght > 0 ) {
121
+ if (msg.attributes && msg.attributes.commands) {
119
122
  this.logger.debug('[MQTTConversationHandlerSERVICE] splitted message::::', this.messages, msg)
120
- this.addCommandMessage(msg)
123
+ await this.addCommandMessage(msg)
121
124
  } else {
122
125
  this.logger.debug('[MQTTConversationHandlerSERVICE] NOT splitted message::::', msg)
123
126
  this.addedMessage(msg)
124
127
  }
125
- });
128
+ };
126
129
  }
127
130
  });
128
131
  const handler_message_added = this.chat21Service.chatClient.onMessageAddedInConversation(
129
- this.conversationWith, (message, topic) => {
132
+ this.conversationWith, async (message, topic) => {
130
133
  this.logger.log('[MQTTConversationHandlerSERVICE] message added:', message, 'on topic:', topic, this.messages);
131
134
  // this.addedMessage(msg);
132
135
  const msg: MessageModel = message;
@@ -143,9 +146,9 @@ export class MQTTConversationHandler extends ConversationHandlerService {
143
146
  // return;
144
147
  // }
145
148
 
146
- if (msg.attributes && msg.attributes.commands && msg.attributes.commands.lenght > 0) {
149
+ if (msg.attributes && msg.attributes.commands) {
147
150
  this.logger.debug('[MQTTConversationHandlerSERVICE] splitted message::::', msg)
148
- this.addCommandMessage(msg)
151
+ await this.addCommandMessage(msg)
149
152
  } else {
150
153
  this.logger.debug('[MQTTConversationHandlerSERVICE] NOT splitted message::::', msg)
151
154
  this.addedMessage(msg)
@@ -264,7 +267,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
264
267
  }
265
268
 
266
269
  /** */
267
- private addedMessage(messageSnapshot: MessageModel) {
270
+ private addedMessage(messageSnapshot: MessageModel): Promise<boolean> {
268
271
  const msg = this.messageGenerate(messageSnapshot);
269
272
  let isInfoMessage = messageType(MESSAGE_TYPE_INFO, msg)
270
273
  if(isInfoMessage){
@@ -461,60 +464,64 @@ export class MQTTConversationHandler extends ConversationHandlerService {
461
464
  });
462
465
  }
463
466
 
464
- private addCommandMessage(msg: MessageModel){
467
+ private async addCommandMessage(msg: MessageModel): Promise<boolean>{
465
468
  const that = this;
466
469
  const commands = msg.attributes.commands;
467
470
  let i=0;
468
- function execute(command){
469
- if(command.type === "message"){
470
- that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
471
- if (i >= 2) {
472
-
473
- //check if previus wait message type has time value, otherwize set to 1000ms
474
- !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
475
- command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
476
-
477
- /** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
478
- if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
479
- let previewsTimeMsg = msg.timestamp;
480
- commands[i-2]? previewsTimeMsg = commands[i-2].message.timestamp : null;
481
- command.message.timestamp = previewsTimeMsg + 100
482
- commands[i+1]? commands[i+1].time = 0 : null
483
- }
484
- } else { /**MANAGE FIRST MESSAGE */
485
- command.message.timestamp = msg.timestamp;
486
- if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
487
- commands[i+1]? commands[i+1].time = 0 : null
488
- }
489
- }
490
- that.generateMessageObject(msg, command.message, i, function () {
491
- i += 1
492
- if (i < commands.length) {
493
- execute(commands[i])
471
+ return new Promise((resolve, reject)=>{
472
+ function execute(command){
473
+ if(command.type === "message"){
474
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
475
+ if (i >= 2) {
476
+
477
+ //check if previus wait message type has time value, otherwize set to 1000ms
478
+ !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
479
+ command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
480
+
481
+ /** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
482
+ if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
483
+ let previewsTimeMsg = msg.timestamp;
484
+ commands[i-2]? previewsTimeMsg = commands[i-2].message.timestamp : null;
485
+ command.message.timestamp = previewsTimeMsg + 100
486
+ commands[i+1]? commands[i+1].time = 0 : null
487
+ }
488
+ } else { /**MANAGE FIRST MESSAGE */
489
+ command.message.timestamp = msg.timestamp;
490
+ if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
491
+ commands[i+1]? commands[i+1].time = 0 : null
492
+ }
494
493
  }
495
- else {
496
- that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> last command executed (wait), exit')
494
+ that.generateMessageObject(msg, command.message, i, function () {
495
+ i += 1
496
+ if (i < commands.length) {
497
+ execute(commands[i])
498
+ }
499
+ else {
500
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> last command executed (wait), exit')
501
+ resolve(true)
502
+ }
503
+ })
504
+ }else if(command.type === "wait"){
505
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
506
+ //publish waiting event to simulate user typing
507
+ if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
508
+ // console.log('message just received::', command, i, commands)
509
+ that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
497
510
  }
498
- })
499
- }else if(command.type === "wait"){
500
- that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
501
- //publish waiting event to simulate user typing
502
- if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
503
- // console.log('message just received::', command, i, commands)
504
- that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
511
+ setTimeout(function() {
512
+ i += 1
513
+ if (i < commands.length) {
514
+ execute(commands[i])
515
+ }
516
+ else {
517
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
518
+ resolve(true)
519
+ }
520
+ },command.time)
505
521
  }
506
- setTimeout(function() {
507
- i += 1
508
- if (i < commands.length) {
509
- execute(commands[i])
510
- }
511
- else {
512
- that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
513
- }
514
- },command.time)
515
522
  }
516
- }
517
- execute(commands[0]) //START render first message
523
+ execute(commands[0]) //START render first message
524
+ })
518
525
  }
519
526
 
520
527
  private generateMessageObject(message, command_message, index, callback) {
@@ -72,9 +72,9 @@ export class MQTTPresenceService extends PresenceService {
72
72
 
73
73
  public imHere(): void {
74
74
  this.logger.debug('[MQTT-PRESENCE] imHere', this.tenant);
75
- // setTimeout(() => {
76
- // this.chat21Service.chatClient.ImHere()
77
- // }, 2000);
75
+ setTimeout(() => {
76
+ this.chat21Service.chatClient.ImHere()
77
+ }, 2000);
78
78
  }
79
79
 
80
80
  /**
@@ -12,14 +12,14 @@ import {
12
12
 
13
13
  /** */
14
14
  export function isImage(message: any) {
15
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'image') {
15
+ if (message && message.type && message.type === 'image' && message.metadata && message.metadata.src) {
16
16
  return true;
17
17
  }
18
18
  return false;
19
19
  }
20
20
 
21
21
  export function isFrame(message: any) {
22
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'frame') {
22
+ if (message && message.type && message.type === 'frame' && message.metadata && message.metadata.src) {
23
23
  return true;
24
24
  }
25
25
  return false;
@@ -27,10 +27,17 @@ export function isFrame(message: any) {
27
27
 
28
28
  /** */
29
29
  export function isFile(message: any) {
30
- if (message && message.type && message.metadata && message.metadata.src && message.type === 'file') {
31
- return true;
32
- }
33
- return false;
30
+ if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && !message.metadata.includes('audio')) {
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ export function isAudio(message: any) {
37
+ if (message && message.type && message.type === 'file' && message.metadata && message.metadata.src && message.metadata.includes('audio') ) {
38
+ return true;
39
+ }
40
+ return false;
34
41
  }
35
42
 
36
43
  /** */