@chat21/chat21-web-widget 5.0.83 → 5.0.84-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/src/app/app.module.ts +5 -2
  4. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html +29 -0
  5. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.scss +103 -0
  6. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.spec.ts +23 -0
  7. package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.ts +96 -0
  8. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +14 -3
  9. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +26 -10
  10. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +131 -49
  11. package/src/app/component/message/audio-track/audio-track.component.html +32 -0
  12. package/src/app/component/message/audio-track/audio-track.component.scss +107 -0
  13. package/src/app/component/message/{audio/audio.component.spec.ts → audio-track/audio-track.component.spec.ts} +6 -6
  14. package/src/app/component/message/audio-track/audio-track.component.ts +147 -0
  15. package/src/app/component/message/bubble-message/bubble-message.component.html +31 -15
  16. package/src/app/component/message/bubble-message/bubble-message.component.scss +7 -0
  17. package/src/app/component/message/bubble-message/bubble-message.component.ts +1 -0
  18. package/src/app/utils/globals.ts +1 -1
  19. package/src/assets/twp/blank.html +3 -6
  20. package/src/assets/twp/chatbot-panel.html +5 -13
  21. package/src/assets/twp/index-dev.html +8 -16
  22. package/src/assets/twp/index.html +7 -13
  23. package/src/assets/twp/tiledesk_widget_files/bootstrap.min.css +4 -3
  24. package/src/assets/twp/tiledesk_widget_files/bootstrap.min.js +3 -4
  25. package/src/assets/twp/tiledesk_widget_files/jquery.min.js +2 -2
  26. package/src/app/component/message/audio/audio.component.html +0 -20
  27. package/src/app/component/message/audio/audio.component.scss +0 -122
  28. package/src/app/component/message/audio/audio.component.ts +0 -122
@@ -0,0 +1,147 @@
1
+ import { Component, ElementRef, AfterViewInit, Input, ViewChild } from '@angular/core';
2
+ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
3
+ import { convertColorToRGBA } from 'src/chat21-core/utils/utils';
4
+
5
+ @Component({
6
+ selector: 'chat-audio-track',
7
+ templateUrl: './audio-track.component.html',
8
+ styleUrls: ['./audio-track.component.scss']
9
+ })
10
+ export class AudioTrackComponent implements AfterViewInit {
11
+
12
+ @ViewChild('audioElement', { static: true }) audioElement!: ElementRef<HTMLAudioElement>;
13
+ @ViewChild('canvasElement', { static: true }) waveformCanvas!: ElementRef<HTMLCanvasElement>;
14
+
15
+ @Input() audioBlob: Blob | null = null;
16
+ @Input() metadata: any | null = null;
17
+ @Input() color: string;
18
+ @Input() fontSize: string;
19
+ @Input() stylesMap: Map<string, string>;
20
+
21
+ audioUrl: SafeUrl | null = null;
22
+ rawAudioUrl: string | null = null;
23
+ audioContext!: AudioContext;
24
+ audioBuffer!: AudioBuffer;
25
+ audioDuration: number | null = null;
26
+ currentTime: number = 0;
27
+ isPlaying: boolean = false;
28
+
29
+ constructor(private sanitizer: DomSanitizer) {}
30
+
31
+ ngAfterViewInit() {
32
+ console.log('stylesssss', this.stylesMap)
33
+ if (this.audioBlob) {
34
+ this.rawAudioUrl = URL.createObjectURL(this.audioBlob);
35
+ this.audioUrl = this.sanitizer.bypassSecurityTrustUrl(this.rawAudioUrl);
36
+ this.setupAudioContext();
37
+ } else {
38
+ this.rawAudioUrl = this.metadata.src;
39
+ this.audioUrl = this.sanitizer.bypassSecurityTrustUrl(this.rawAudioUrl);
40
+ this.setupAudioContext();
41
+ }
42
+ }
43
+
44
+ async setupAudioContext() {
45
+ this.audioContext = new AudioContext();
46
+ if (this.rawAudioUrl) {
47
+ const response = await fetch(this.rawAudioUrl);
48
+ const audioData = await response.arrayBuffer();
49
+ this.audioBuffer = await this.audioContext.decodeAudioData(audioData);
50
+ this.getAudioDuration();
51
+ this.drawWaveform(this.audioBuffer);
52
+ }
53
+ }
54
+
55
+ drawWaveform(audioBuffer: AudioBuffer) {
56
+ const canvas = this.waveformCanvas.nativeElement;
57
+ const canvasCtx = canvas.getContext('2d');
58
+ if (!canvasCtx) return;
59
+ const width = canvas.width;
60
+ const height = canvas.height;
61
+ const rawData = audioBuffer.getChannelData(0);
62
+
63
+ const samples = 60;
64
+ const blockSize = Math.floor(rawData.length / samples);
65
+ const waveform = new Float32Array(samples);
66
+
67
+ for (let i = 0; i < samples; i++) {
68
+ let sum = 0;
69
+ for (let j = 0; j < blockSize; j++) {
70
+ sum += Math.abs(rawData[i * blockSize + j]);
71
+ }
72
+ waveform[i] = sum / blockSize;
73
+ }
74
+
75
+ canvasCtx.clearRect(0, 0, width, height);
76
+ const padding = 1;
77
+ const barWidth = (width / samples) - padding * 2;
78
+ const audio = this.audioElement.nativeElement;
79
+ const playedPercent = audio.currentTime / this.audioDuration;
80
+ // console.log('playedPercent: ', audio.currentTime, this.audioDuration);
81
+
82
+ for (let i = 0; i < samples; i++) {
83
+ var barHeight = waveform[i] * height * 4;
84
+ if (barHeight < 4) barHeight = 4;
85
+ const x = i * (barWidth + padding * 2) + padding;
86
+
87
+ if (i / samples < playedPercent) {
88
+ canvasCtx.fillStyle = this.color;
89
+ } else {
90
+ canvasCtx.fillStyle = convertColorToRGBA(this.color, 50);;
91
+ }
92
+ canvasCtx.fillRect(x, height / 2 - barHeight, barWidth, barHeight);
93
+ canvasCtx.fillRect(x, height / 2, barWidth, barHeight);
94
+ }
95
+ }
96
+
97
+ playPauseAudio() {
98
+ const audio = this.audioElement.nativeElement;
99
+ if (audio.paused) {
100
+ this.isPlaying = true;
101
+ this.updateWaveform();
102
+ audio.play();
103
+ this.audioContext.resume();
104
+ } else {
105
+ audio.pause();
106
+ this.isPlaying = false;
107
+ }
108
+ audio.ontimeupdate = () => {
109
+ this.currentTime = audio.currentTime;
110
+ this.updateWaveform();
111
+ };
112
+ audio.onended = () => {
113
+ this.isPlaying = false;
114
+ };
115
+ }
116
+
117
+
118
+ updateWaveform() {
119
+ this.drawWaveform(this.audioBuffer);
120
+ if (this.isPlaying) {
121
+ requestAnimationFrame(() => this.updateWaveform());
122
+ }
123
+ }
124
+
125
+ formatTime(seconds: number): string {
126
+ const minutes = Math.floor(seconds / 60);
127
+ const sec = Math.floor(seconds % 60);
128
+ return `${minutes}:${sec < 10 ? '0' + sec : sec}`;
129
+ }
130
+
131
+ getAudioDuration() {
132
+ const audio = new Audio();
133
+ audio.src = this.rawAudioUrl!;
134
+ audio.addEventListener('loadedmetadata', () => {
135
+ if (audio.duration === Infinity) {
136
+ audio.currentTime = Number.MAX_SAFE_INTEGER;
137
+ audio.ontimeupdate = () => {
138
+ audio.ontimeupdate = null;
139
+ audio.currentTime = 0;
140
+ this.audioDuration = audio.duration;
141
+ };
142
+ } else {
143
+ this.audioDuration = audio.duration;
144
+ }
145
+ });
146
+ }
147
+ }
@@ -1,9 +1,26 @@
1
1
  <!-- [ngClass]="{'button-in-msg' : message.metadata && message.metadata.button}" -->
2
2
  <!-- ngStyle]="{'padding': (isImage(message) || isFrame(message))?'1px':'0 8px'}" -->
3
3
  <!-- 'width': (isImage(message) || isFrame(message))? sizeImage?.width + 'px': null -->
4
- <div id="bubble-message" [ngStyle]="{'padding': (isImage(message) || isFrame(message))?'0 0px':'0 8px'}" class="messages primary-color">
5
-
4
+
5
+
6
6
 
7
+ <!-- <div id="bubble-message" *ngIf="isAudio(message)" [ngStyle]="{'padding': '0'}" class="messages primary-color">
8
+ <div>
9
+ <chat-audio-track *ngIf="isAudio(message)"
10
+ [metadata]="message.metadata"
11
+ ></chat-audio-track>
12
+ </div>
13
+ </div>
14
+
15
+
16
+ [ngStyle]="{'padding': (isImage(message) || isFrame(message) || isAudio(message))?'0 0px':'0 8px'}"
17
+ -->
18
+
19
+
20
+
21
+
22
+
23
+ <div id="bubble-message" class="messages primary-color">
7
24
  <div>
8
25
 
9
26
  <div *ngIf="messageType(MESSAGE_TYPE_OTHERS, message) && !isSameSender"
@@ -36,10 +53,18 @@
36
53
  (onElementRendered)="onElementRenderedFN($event)">
37
54
  </chat-frame>
38
55
 
39
- <chat-audio *ngIf="isAudio(message)"
56
+ <!-- <chat-audio *ngIf="isAudio(message)"
40
57
  [metadata]="message.metadata"
41
58
  (onElementRendered)="onElementRenderedFN($event)">
42
- </chat-audio>
59
+ </chat-audio> -->
60
+
61
+ <chat-audio-track *ngIf="isAudio(message)"
62
+ [metadata]="message.metadata"
63
+ [color]="fontColor"
64
+ [fontSize]="fontSize"
65
+ [stylesMap]="stylesMap">
66
+ </chat-audio-track>
67
+
43
68
 
44
69
  <!-- <chat-frame *ngIf="message.metadata && message.metadata.type && message.metadata.type.includes('video')"
45
70
  [metadata]="message.metadata"
@@ -51,7 +76,7 @@
51
76
  <!-- <div *ngIf="message.type == 'text'"> -->
52
77
 
53
78
  <!-- tooltip="{{message.timestamp | dateAgo}} ({{message.timestamp | date:'shortDate'}} {{message.timestamp | date:'HH:mm:ss'}})" placement="bottom" -->
54
- <div *ngIf="message?.text" >
79
+ <div *ngIf="message?.text && !isAudio(message)" >
55
80
 
56
81
  <!-- [htmlEnabled]="(message?.type==='html')? true : false" -->
57
82
  <chat-text *ngIf="message?.type !=='html'"
@@ -69,16 +94,7 @@
69
94
  [themeColor]="stylesMap.get('themeColor')"
70
95
  [foregroundColor]="stylesMap.get('foregroundColor')">
71
96
  </chat-html>
72
- <!-- <p #messageEl class="message_innerhtml marked" [innerHTML]="printMessage(message, messageEl, this) | marked"></p> -->
73
- <!-- <div *ngIf="isPopupUrl(message.text); then contentPopup else contentNewTab">here
74
- is ignored</div>
75
- <ng-template #contentPopup>
76
- <p style="text-decoration: underline; padding:8px; cursor: pointer;"
77
- (click)="popupUrl(g.windowContext, message.text,'windowName')">{{strip_tags(message.text)}}</p>
78
- </ng-template>
79
- <ng-template #contentNewTab>
80
- <p #messageEl [innerHTML]="printMessage(message, messageEl, this) | linky"></p>
81
- </ng-template> -->
97
+
82
98
  </div>
83
99
 
84
100
  </div>
@@ -5,6 +5,9 @@
5
5
  border-radius: var(--border-radius-bubble-message);
6
6
  padding: 0;
7
7
  word-wrap: break-word;
8
+
9
+ background: transparent;
10
+
8
11
  // padding: 14px;
9
12
  // padding: 6px 6px 6px 6px;
10
13
  // box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -26,4 +29,8 @@
26
29
  height: auto;
27
30
  object-fit: cover;
28
31
  }
32
+
33
+ chat-audio-track {
34
+ display: flex;
35
+ }
29
36
  }
@@ -42,6 +42,7 @@ export class BubbleMessageComponent implements OnInit {
42
42
  constructor(public sanitizer: DomSanitizer) { }
43
43
 
44
44
  ngOnInit() {
45
+ // console.log("---- > MSG:", this.message);
45
46
  }
46
47
 
47
48
  ngOnChanges() {
@@ -388,7 +388,7 @@ export class Globals {
388
388
  /**enable user to set a facebook messanger page to chat with */
389
389
  this.telegramUsername = ''
390
390
  /**enable user to set a telegram number to chat with */
391
- this.fileUploadAccept = "image/*,.pdf,.txt"
391
+ this.fileUploadAccept = "image/*,.pdf,.txt,.mp3"
392
392
  /**enable auto disconnect from messaging after a defined amount of time (s)*/
393
393
  this.disconnetTime = 0
394
394
 
@@ -148,6 +148,9 @@
148
148
  <meta property="og:image" content="https://tiledesk.com/wp-content/uploads/2022/12/6029654-02-min.png" />
149
149
  <meta property="og:locale" content="en">
150
150
 
151
+ <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
152
+ <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
153
+
151
154
 
152
155
  <script type="application/javascript">
153
156
  window.tiledeskSettings = {
@@ -307,11 +310,5 @@
307
310
  <div id="preloader">
308
311
  <div class="loader"></div>
309
312
  </div>
310
-
311
- <div>
312
- <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
313
- <!-- <link href="./tiledesk_widget_files/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
314
- <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
315
- </div>
316
313
  </body>
317
314
  </html>
@@ -438,10 +438,12 @@
438
438
  <meta property="og:locale" content="en">
439
439
 
440
440
  <link rel="icon" type="image/png" href="./tiledesk_widget_files/logo-short.png">
441
- <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
441
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" rel="stylesheet">
442
+ <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
443
+ <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
442
444
  <script defer="" src="./tiledesk_widget_files/jquery.min.js"></script>
443
445
  <script defer="" src="./tiledesk_widget_files/bootstrap.min.js"></script>
444
-
446
+
445
447
  <!-- <script type="application/javascript">
446
448
  window.tiledeskSettings = {
447
449
  marginX: "100px",
@@ -592,7 +594,7 @@
592
594
  }
593
595
 
594
596
  window.onload = function() {
595
- document.getElementById("tiledesk_widgetTitle").innerHTML = tiledesk_widgetTitle;
597
+ document.getElementById("tiledesk_widgetTitle").value = tiledesk_widgetTitle;
596
598
  }
597
599
 
598
600
 
@@ -712,15 +714,5 @@
712
714
  </script>
713
715
 
714
716
  <!-- Google Analytics -->
715
-
716
-
717
-
718
-
719
- <div>
720
- <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
721
- <!-- <link href="./tiledesk_widget_files/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
722
- <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
723
- <!-- <link href="./tiledesk_widget_files/css" rel="stylesheet" type="text/css"> -->
724
- </div>
725
717
  </body>
726
718
  </html>
@@ -469,8 +469,10 @@
469
469
 
470
470
  <link rel="icon" type="image/png" href="./tiledesk_widget_files/logo-short.png">
471
471
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" rel="stylesheet">
472
- <script defer="" src="./tiledesk_widget_files/jquery.min.js"></script>
472
+ <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
473
+ <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
473
474
  <script defer="" src="./tiledesk_widget_files/bootstrap.min.js"></script>
475
+ <script defer="" src="./tiledesk_widget_files/jquery.min.js"></script>
474
476
 
475
477
  <script type="application/javascript">
476
478
  window.tiledeskSettings = {
@@ -504,8 +506,8 @@
504
506
  document.getElementById('events').scrollTop = document.getElementById('events').scrollHeight
505
507
  }
506
508
 
507
- document.getElementById("project_id").innerHTML = '"' + tiledesk_projectid + '"';
508
- document.getElementById("project_name").innerHTML = project_name;
509
+ document.getElementById("project_id").value = '"' + tiledesk_projectid + '"';
510
+ document.getElementById("project_name").value = project_name;
509
511
  });
510
512
 
511
513
  window.Tiledesk('onBeforeInit', function(event_data) {
@@ -518,7 +520,7 @@
518
520
 
519
521
  var enbedJs = event_data.detail.appConfigs.enbedJs? event_data.detail.appConfigs.enbedJs : false;
520
522
  document.getElementById("enbed").style.display = enbedJs? "inline-block": "none";
521
- document.getElementById("base_url").innerHTML = enbedJs ? window.tiledesk.getBaseLocation() + '/launch.js': null;
523
+ document.getElementById("base_url").value = enbedJs ? window.tiledesk.getBaseLocation() + '/launch.js': null;
522
524
 
523
525
  baseUrlConsole = event_data.detail.appConfigs.dashboardUrl? event_data.detail.appConfigs.dashboardUrl : baseUrlConsole;
524
526
  }
@@ -1444,8 +1446,8 @@
1444
1446
  // console.log('project_name: ', project_name);
1445
1447
 
1446
1448
  // window.onload = function() {
1447
- // document.getElementById("project_id").innerHTML = '"' + tiledesk_projectid + '"';
1448
- // document.getElementById("project_name").innerHTML = project_name;
1449
+ // document.getElementById("project_id").value = '"' + tiledesk_projectid + '"';
1450
+ // document.getElementById("project_name").value = project_name;
1449
1451
  // }
1450
1452
 
1451
1453
 
@@ -2616,15 +2618,5 @@
2616
2618
  </script> -->
2617
2619
 
2618
2620
  <!-- Google Analytics -->
2619
-
2620
-
2621
-
2622
-
2623
- <div>
2624
- <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
2625
- <!-- <link href="./tiledesk_widget_files/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
2626
- <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
2627
- <!-- <link href="./tiledesk_widget_files/css" rel="stylesheet" type="text/css"> -->
2628
- </div>
2629
2621
  </body>
2630
2622
  </html>
@@ -245,7 +245,10 @@
245
245
  <meta property="og:locale" content="en">
246
246
 
247
247
  <link rel="icon" type="image/png" href="./tiledesk_widget_files/logo-short.png">
248
- <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
248
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" rel="stylesheet">
249
+ <!-- <link href="./tiledesk_widget_files/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
250
+ <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
251
+ <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
249
252
  <script defer="" src="./tiledesk_widget_files/jquery.min.js"></script>
250
253
  <script defer="" src="./tiledesk_widget_files/bootstrap.min.js"></script>
251
254
 
@@ -297,7 +300,7 @@
297
300
 
298
301
  var enbedJs = event_data.detail.appConfigs.enbedJs? event_data.detail.appConfigs.enbedJs : false;
299
302
  document.getElementById("enbed").style.display = enbedJs? "inline-block": "none";
300
- document.getElementById("base_url").innerHTML = enbedJs ? window.tiledesk.getBaseLocation() + '/launch.js': null;
303
+ document.getElementById("base_url").value = enbedJs ? window.tiledesk.getBaseLocation() + '/launch.js': null;
301
304
 
302
305
  baseUrlConsole = event_data.detail.appConfigs.dashboardUrl? event_data.detail.appConfigs.dashboardUrl : baseUrlConsole;
303
306
  }
@@ -436,8 +439,8 @@
436
439
  // console.log('project_name: ', project_name);
437
440
 
438
441
  window.onload = function() {
439
- document.getElementById("project_id").innerHTML = '"' + tiledesk_projectid + '"';
440
- document.getElementById("project_name").innerHTML = project_name;
442
+ document.getElementById("project_id").value = '"' + tiledesk_projectid + '"';
443
+ document.getElementById("project_name").value = project_name;
441
444
 
442
445
  if(role !== 'agent'){
443
446
  document.getElementById("testPageButton").style.display = 'block'
@@ -629,14 +632,5 @@
629
632
  </script> -->
630
633
 
631
634
  <!-- Google Analytics -->
632
-
633
-
634
-
635
-
636
- <div>
637
- <link href="./tiledesk_widget_files/bootstrap.min.css" rel="stylesheet" type="text/css">
638
- <!-- <link href="./tiledesk_widget_files/font-awesome.min.css" rel="stylesheet" type="text/css"> -->
639
- <link href="./tiledesk_widget_files/website-poly.min.css" rel="stylesheet" type="text/css">
640
- </div>
641
635
  </body>
642
636
  </html>