@chat21/chat21-web-widget 5.0.83 → 5.0.84-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 +3 -0
- package/package.json +1 -1
- package/src/app/app.module.ts +5 -2
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html +29 -0
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.scss +103 -0
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.spec.ts +23 -0
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.ts +96 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +14 -3
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +26 -10
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +131 -49
- package/src/app/component/message/audio-track/audio-track.component.html +32 -0
- package/src/app/component/message/audio-track/audio-track.component.scss +107 -0
- package/src/app/component/message/{audio/audio.component.spec.ts → audio-track/audio-track.component.spec.ts} +6 -6
- package/src/app/component/message/audio-track/audio-track.component.ts +147 -0
- package/src/app/component/message/bubble-message/bubble-message.component.html +31 -15
- package/src/app/component/message/bubble-message/bubble-message.component.scss +7 -0
- package/src/app/component/message/bubble-message/bubble-message.component.ts +1 -0
- package/src/app/utils/globals.ts +1 -1
- package/src/assets/twp/chatbot-panel.html +1 -1
- package/src/assets/twp/index-dev.html +5 -5
- package/src/assets/twp/index.html +3 -3
- package/src/app/component/message/audio/audio.component.html +0 -20
- package/src/app/component/message/audio/audio.component.scss +0 -122
- package/src/app/component/message/audio/audio.component.ts +0 -122
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts
CHANGED
|
@@ -59,6 +59,8 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
59
59
|
// ========= end:: send image ========= //
|
|
60
60
|
|
|
61
61
|
// isNewConversation = true;
|
|
62
|
+
isStartRec: boolean = false;
|
|
63
|
+
isStopRec: boolean = false;
|
|
62
64
|
textInputTextArea: string;
|
|
63
65
|
conversationHandlerService: ConversationHandlerService
|
|
64
66
|
|
|
@@ -98,7 +100,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
ngAfterViewInit() {
|
|
101
|
-
this.logger.
|
|
103
|
+
this.logger.log('[CONV-FOOTER] --------ngAfterViewInit: conversation-footer-------- ');
|
|
102
104
|
// setTimeout(() => {
|
|
103
105
|
this.showEmojiPicker = true
|
|
104
106
|
// }, 500);
|
|
@@ -108,19 +110,18 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
108
110
|
// START LOAD IMAGE //
|
|
109
111
|
/** load the selected image locally and open the pop up preview */
|
|
110
112
|
detectFiles(event) {
|
|
111
|
-
this.logger.
|
|
112
|
-
|
|
113
|
+
this.logger.log('[CONV-FOOTER] detectFiles: ', event);
|
|
113
114
|
if (event) {
|
|
114
115
|
this.selectedFiles = event.target.files;
|
|
115
|
-
this.logger.
|
|
116
|
+
this.logger.log('[CONV-FOOTER] AppComponent:detectFiles::selectedFiles', this.selectedFiles);
|
|
116
117
|
// this.onAttachmentButtonClicked.emit(this.selectedFiles)
|
|
117
118
|
if (this.selectedFiles == null) {
|
|
118
119
|
this.isFilePendingToUpload = false;
|
|
119
120
|
} else {
|
|
120
121
|
this.isFilePendingToUpload = true;
|
|
121
122
|
}
|
|
122
|
-
this.logger.
|
|
123
|
-
this.logger.
|
|
123
|
+
this.logger.log('[CONV-FOOTER] AppComponent:detectFiles::selectedFiles::isFilePendingToUpload', this.isFilePendingToUpload);
|
|
124
|
+
this.logger.log('[CONV-FOOTER] fileChange: ', event.target.files);
|
|
124
125
|
if (event.target.files.length <= 0) {
|
|
125
126
|
this.isFilePendingToUpload = false;
|
|
126
127
|
} else {
|
|
@@ -133,27 +134,27 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
133
134
|
const typeFile = event.target.files[0].type;
|
|
134
135
|
const size = event.target.files[0].size
|
|
135
136
|
const reader = new FileReader();
|
|
136
|
-
that.logger.
|
|
137
|
+
that.logger.log('[CONV-FOOTER] OK preload: ', nameFile, typeFile, reader);
|
|
137
138
|
reader.addEventListener('load', function () {
|
|
138
|
-
that.logger.
|
|
139
|
+
that.logger.log('[CONV-FOOTER] addEventListener load', reader.result);
|
|
139
140
|
that.isFileSelected = true;
|
|
140
141
|
// se inizia con image
|
|
141
142
|
if (typeFile.startsWith('image') && !typeFile.includes('svg')) {
|
|
142
143
|
const imageXLoad = new Image;
|
|
143
|
-
that.logger.
|
|
144
|
+
that.logger.log('[CONV-FOOTER] onload ', imageXLoad);
|
|
144
145
|
imageXLoad.src = reader.result.toString();
|
|
145
146
|
imageXLoad.title = nameFile;
|
|
146
147
|
imageXLoad.onload = function () {
|
|
147
|
-
that.logger.
|
|
148
|
+
that.logger.log('[CONV-FOOTER] onload image');
|
|
148
149
|
// that.arrayFilesLoad.push(imageXLoad);
|
|
149
150
|
const uid = (new Date().getTime()).toString(36); // imageXLoad.src.substring(imageXLoad.src.length - 16);
|
|
150
151
|
that.arrayFilesLoad[0] = { uid: uid, file: imageXLoad, type: typeFile, size: size };
|
|
151
|
-
that.logger.
|
|
152
|
+
that.logger.log('[CONV-FOOTER] OK: ', that.arrayFilesLoad[0]);
|
|
152
153
|
// SEND MESSAGE
|
|
153
154
|
that.loadFile();
|
|
154
155
|
};
|
|
155
156
|
} else {
|
|
156
|
-
that.logger.
|
|
157
|
+
that.logger.log('[CONV-FOOTER] onload file');
|
|
157
158
|
const fileXLoad = {
|
|
158
159
|
src: reader.result.toString(),
|
|
159
160
|
title: nameFile
|
|
@@ -161,7 +162,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
161
162
|
// that.arrayFilesLoad.push(imageXLoad);
|
|
162
163
|
const uid = (new Date().getTime()).toString(36); // imageXLoad.src.substring(imageXLoad.src.length - 16);
|
|
163
164
|
that.arrayFilesLoad[0] = { uid: uid, file: fileXLoad, type: typeFile, size: size };
|
|
164
|
-
that.logger.
|
|
165
|
+
that.logger.log('[CONV-FOOTER] OK: ', that.arrayFilesLoad[0]);
|
|
165
166
|
// SEND MESSAGE
|
|
166
167
|
that.loadFile();
|
|
167
168
|
}
|
|
@@ -169,22 +170,24 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
169
170
|
|
|
170
171
|
if (event.target.files[0]) {
|
|
171
172
|
reader.readAsDataURL(event.target.files[0]);
|
|
172
|
-
that.logger.
|
|
173
|
+
that.logger.log('[CONV-FOOTER] reader-result: ', event.target.files[0]);
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
|
|
179
|
+
|
|
180
|
+
|
|
178
181
|
|
|
179
182
|
loadFile() {
|
|
180
|
-
this.logger.
|
|
183
|
+
this.logger.log('[CONV-FOOTER] that.fileXLoad: ', this.arrayFilesLoad);
|
|
181
184
|
// at the moment I only manage the upload of one image at a time
|
|
182
185
|
if (this.arrayFilesLoad[0] && this.arrayFilesLoad[0].file) {
|
|
183
186
|
const fileXLoad = this.arrayFilesLoad[0].file;
|
|
184
187
|
const uid = this.arrayFilesLoad[0].uid;
|
|
185
188
|
const type = this.arrayFilesLoad[0].type;
|
|
186
189
|
const size = this.arrayFilesLoad[0].size
|
|
187
|
-
this.logger.
|
|
190
|
+
this.logger.log('[CONV-FOOTER] that.fileXLoad: ', type);
|
|
188
191
|
let metadata;
|
|
189
192
|
if (type.startsWith('image') && !type.includes('svg')) {
|
|
190
193
|
metadata = {
|
|
@@ -205,7 +208,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
205
208
|
'size': size
|
|
206
209
|
};
|
|
207
210
|
}
|
|
208
|
-
this.logger.
|
|
211
|
+
this.logger.log('[CONV-FOOTER] metadata -------> ', metadata);
|
|
209
212
|
// this.scrollToBottom();
|
|
210
213
|
// 1 - aggiungo messaggio localmente
|
|
211
214
|
// this.addLocalMessageImage(metadata);
|
|
@@ -222,17 +225,20 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
222
225
|
|
|
223
226
|
uploadSingle(metadata, file, messageText?: string) {
|
|
224
227
|
const that = this;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
try {
|
|
229
|
+
const send_order_btn = <HTMLInputElement>document.getElementById('chat21-start-upload-doc');
|
|
230
|
+
send_order_btn.disabled = true;
|
|
231
|
+
} catch (error) {
|
|
232
|
+
that.logger.log('[CONV-FOOTER] error::', error);
|
|
233
|
+
}
|
|
234
|
+
that.logger.log('[CONV-FOOTER] AppComponent::uploadSingle::', metadata, file);
|
|
228
235
|
// const file = this.selectedFiles.item(0);
|
|
229
236
|
const currentUpload = new UploadModel(file);
|
|
230
|
-
|
|
231
237
|
// const uploadTask = this.upSvc.pushUpload(currentUpload);
|
|
232
238
|
// uploadTask.then(snapshot => {
|
|
233
239
|
// return snapshot.ref.getDownloadURL(); // Will return a promise with the download link
|
|
234
240
|
// }).then(downloadURL => {
|
|
235
|
-
// that.logger.
|
|
241
|
+
// that.logger.log('[CONV-FOOTER] AppComponent::uploadSingle:: downloadURL', downloadURL]);
|
|
236
242
|
// that.g.wdLog([`Successfully uploaded file and got download link - ${downloadURL}`]);
|
|
237
243
|
|
|
238
244
|
// metadata.src = downloadURL;
|
|
@@ -252,8 +258,8 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
252
258
|
// this.resetLoadImage();
|
|
253
259
|
|
|
254
260
|
this.uploadService.upload(this.senderId, currentUpload).then(data => {
|
|
255
|
-
that.logger.
|
|
256
|
-
that.logger.
|
|
261
|
+
that.logger.log('[CONV-FOOTER] AppComponent::uploadSingle:: downloadURL', data);
|
|
262
|
+
that.logger.log(`[CONV-FOOTER] Successfully uploaded file and got download link - ${data}`);
|
|
257
263
|
|
|
258
264
|
metadata.src = data.src;
|
|
259
265
|
metadata.downloadURL = data.downloadURL;
|
|
@@ -282,7 +288,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
282
288
|
that.logger.error(`[CONV-FOOTER] uploadSingle:: Failed to upload file and get link - ${error}`);
|
|
283
289
|
that.isFilePendingToUpload = false;
|
|
284
290
|
});
|
|
285
|
-
that.logger.
|
|
291
|
+
that.logger.log('[CONV-FOOTER] reader-result: ', file);
|
|
286
292
|
}
|
|
287
293
|
|
|
288
294
|
/**
|
|
@@ -295,7 +301,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
295
301
|
sendMessage(msg: string, type: string, metadata?: any, additional_attributes?: any) { // sponziello
|
|
296
302
|
(metadata) ? metadata = metadata : metadata = '';
|
|
297
303
|
this.onEmojiiPickerShow.emit(false)
|
|
298
|
-
this.logger.
|
|
304
|
+
this.logger.log('[CONV-FOOTER] SEND MESSAGE: ', msg, type, metadata, additional_attributes);
|
|
299
305
|
if (msg && msg.trim() !== '' || type === TYPE_MSG_IMAGE || type === TYPE_MSG_FILE ) {
|
|
300
306
|
|
|
301
307
|
// msg = htmlEntities(msg);
|
|
@@ -378,7 +384,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
378
384
|
}
|
|
379
385
|
|
|
380
386
|
private restoreTextArea() {
|
|
381
|
-
// that.logger.
|
|
387
|
+
// that.logger.log('[CONV-FOOTER] AppComponent:restoreTextArea::restoreTextArea');
|
|
382
388
|
this.resizeInputField();
|
|
383
389
|
const textArea = (<HTMLInputElement>document.getElementById('chat21-main-message-context'));
|
|
384
390
|
this.textInputTextArea = ''; // clear the textarea
|
|
@@ -388,7 +394,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
388
394
|
if(textArea.style.height > this.HEIGHT_DEFAULT){
|
|
389
395
|
document.getElementById('chat21-button-send').style.removeProperty('right')
|
|
390
396
|
}
|
|
391
|
-
this.logger.
|
|
397
|
+
this.logger.log('[CONV-FOOTER] AppComponent:restoreTextArea::restoreTextArea::textArea:', 'restored');
|
|
392
398
|
}
|
|
393
399
|
this.setFocusOnId('chat21-main-message-context');
|
|
394
400
|
}
|
|
@@ -402,7 +408,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
402
408
|
try {
|
|
403
409
|
const target = document.getElementById('chat21-main-message-context') as HTMLInputElement;
|
|
404
410
|
// tslint:disable-next-line:max-line-length
|
|
405
|
-
// that.logger.
|
|
411
|
+
// that.logger.log('[CONV-FOOTER] H:: this.textInputTextArea', (document.getElementById('chat21-main-message-context') as HTMLInputElement).value , target.style.height, target.scrollHeight, target.offsetHeight, target.clientHeight);
|
|
406
412
|
target? target.style.height = '100%': null;
|
|
407
413
|
if (target && target.value === '\n') {
|
|
408
414
|
target.value = '';
|
|
@@ -422,28 +428,104 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
422
428
|
}
|
|
423
429
|
}
|
|
424
430
|
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
onStartRecording() {
|
|
434
|
+
this.isStartRec = true;
|
|
435
|
+
this.isStopRec = false;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
onDeleteRecording(){
|
|
439
|
+
this.isStartRec = false;
|
|
440
|
+
this.isStopRec = false;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
onEndRecording(audioBlob: Blob | null) {
|
|
444
|
+
this.isStartRec = false;
|
|
445
|
+
this.isStopRec = true;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
onSendRecording(audioBlob: Blob | null) {
|
|
451
|
+
this.isStartRec = false;
|
|
452
|
+
if (audioBlob) {
|
|
453
|
+
this.convertBlobToBase64(audioBlob);
|
|
454
|
+
this.isStopRec = false;
|
|
455
|
+
} else {
|
|
456
|
+
this.isStopRec = false;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
// Funzione per convertire Blob in Base64 usando FileReader
|
|
463
|
+
async convertBlobToBase64(audioBlob: Blob) {
|
|
464
|
+
let that = this;
|
|
465
|
+
if (audioBlob) {
|
|
466
|
+
this.isFilePendingToUpload = true;
|
|
467
|
+
} else {
|
|
468
|
+
this.isFilePendingToUpload = false;
|
|
469
|
+
}
|
|
470
|
+
const type = audioBlob.type;
|
|
471
|
+
const size = audioBlob.size;
|
|
472
|
+
const reader = new FileReader();
|
|
473
|
+
reader.readAsDataURL(audioBlob);
|
|
474
|
+
//reader.addEventListener('load', function () {
|
|
475
|
+
reader.onloadend = () => {
|
|
476
|
+
that.isFileSelected = true;
|
|
477
|
+
// const base64data = reader.result as string;
|
|
478
|
+
that.logger.log('[CONV-FOOTER] onload file');
|
|
479
|
+
const fileXLoad = {
|
|
480
|
+
src: reader.result.toString(),
|
|
481
|
+
title: 'audio-file'
|
|
482
|
+
};
|
|
483
|
+
const uid = (new Date().getTime()).toString(36);
|
|
484
|
+
that.arrayFilesLoad[0] = { uid: uid, file: fileXLoad, type: type, size: size };
|
|
485
|
+
that.logger.log('[CONV-FOOTER] OK: ', that.arrayFilesLoad[0]);
|
|
486
|
+
// SEND MESSAGE
|
|
487
|
+
let metadata = {
|
|
488
|
+
'name': 'audio-file',
|
|
489
|
+
'src': fileXLoad.src,
|
|
490
|
+
'type': type,
|
|
491
|
+
'uid': uid,
|
|
492
|
+
'size': size
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const file = new File([audioBlob], "audio-file.mp3", {
|
|
496
|
+
type: audioBlob.type,
|
|
497
|
+
lastModified: Date.now()
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
that.uploadSingle(metadata, file, '');
|
|
501
|
+
};
|
|
502
|
+
//}, false);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
425
507
|
onTextAreaChange(){
|
|
426
508
|
this.resizeInputField()
|
|
427
509
|
this.setWritingMessages(this.textInputTextArea)
|
|
428
510
|
}
|
|
429
511
|
|
|
430
512
|
onSendPressed(event) {
|
|
431
|
-
this.logger.
|
|
513
|
+
this.logger.log('[CONV-FOOTER] onSendPressed:event', event);
|
|
432
514
|
event.preventDefault();
|
|
433
|
-
this.logger.
|
|
515
|
+
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed::isFilePendingToUpload:', this.isFilePendingToUpload);
|
|
434
516
|
if (this.isFilePendingToUpload) {
|
|
435
|
-
this.logger.
|
|
517
|
+
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed', 'is a file');
|
|
436
518
|
// its a file
|
|
437
519
|
this.loadFile();
|
|
438
520
|
this.isFilePendingToUpload = false;
|
|
439
521
|
// disabilito pulsanti
|
|
440
|
-
this.logger.
|
|
522
|
+
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed::isFilePendingToUpload:', this.isFilePendingToUpload);
|
|
441
523
|
} else {
|
|
442
524
|
if ( this.textInputTextArea && this.textInputTextArea.length > 0 ) {
|
|
443
|
-
this.logger.
|
|
525
|
+
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed', 'is a message');
|
|
444
526
|
// its a message
|
|
445
527
|
if (this.textInputTextArea.trim() !== '') {
|
|
446
|
-
// that.logger.
|
|
528
|
+
// that.logger.log('[CONV-FOOTER] sendMessage -> ', this.textInputTextArea);
|
|
447
529
|
// this.resizeInputField();
|
|
448
530
|
// this.messagingService.sendMessage(msg, TYPE_MSG_TEXT);
|
|
449
531
|
// this.setDepartment();
|
|
@@ -517,7 +599,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
517
599
|
setTimeout(function () {
|
|
518
600
|
const textarea = document.getElementById(id);
|
|
519
601
|
if (textarea) {
|
|
520
|
-
// that.logger.
|
|
602
|
+
// that.logger.log('[CONV-FOOTER] 1--------> FOCUSSSSSS : ', textarea);
|
|
521
603
|
textarea.setAttribute('value', ' ');
|
|
522
604
|
textarea.focus();
|
|
523
605
|
}
|
|
@@ -557,7 +639,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
557
639
|
this.textInputTextArea = ((document.getElementById('chat21-main-message-context') as HTMLInputElement).value);
|
|
558
640
|
if (keyCode === 13) { // ENTER pressed
|
|
559
641
|
if (this.textInputTextArea && this.textInputTextArea.trim() !== '') {
|
|
560
|
-
// that.logger.
|
|
642
|
+
// that.logger.log('[CONV-FOOTER] sendMessage -> ', this.textInputTextArea);
|
|
561
643
|
// this.resizeInputField();
|
|
562
644
|
// this.messagingService.sendMessage(msg, TYPE_MSG_TEXT);
|
|
563
645
|
// this.setDepartment();
|
|
@@ -589,14 +671,14 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
589
671
|
this.resizeInputField()
|
|
590
672
|
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
|
591
673
|
let file = null;
|
|
592
|
-
this.logger.
|
|
674
|
+
this.logger.log('[CONV-FOOTER] onPaste items ', items);
|
|
593
675
|
for (const item of items) {
|
|
594
|
-
this.logger.
|
|
595
|
-
this.logger.
|
|
676
|
+
this.logger.log('[CONV-FOOTER] onPaste item ', item);
|
|
677
|
+
this.logger.log('[CONV-FOOTER] onPaste item.type ', item.type);
|
|
596
678
|
if (item.type.startsWith("image")) {
|
|
597
679
|
// SEND TEXT MESSAGE IF EXIST
|
|
598
680
|
// if(this.textInputTextArea){
|
|
599
|
-
// this.logger.
|
|
681
|
+
// this.logger.log('[CONV-FOOTER] onPaste texttt ', this.textInputTextArea);
|
|
600
682
|
// this.sendMessage(this.textInputTextArea, TYPE_MSG_TEXT)
|
|
601
683
|
// }
|
|
602
684
|
|
|
@@ -606,12 +688,12 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
606
688
|
this.logger.error('[CONV-FOOTER] onPaste - error while restoring textArea:',e)
|
|
607
689
|
}
|
|
608
690
|
|
|
609
|
-
this.logger.
|
|
691
|
+
this.logger.log('[CONV-FOOTER] onPaste item.type', item.type);
|
|
610
692
|
file = item.getAsFile();
|
|
611
693
|
const data = {target: new ClipboardEvent('').clipboardData || new DataTransfer()};
|
|
612
694
|
data.target.items.add(new File([file], file.name, { type: file.type }));
|
|
613
|
-
this.logger.
|
|
614
|
-
this.logger.
|
|
695
|
+
this.logger.log('[CONV-FOOTER] onPaste data', data);
|
|
696
|
+
this.logger.log('[CONV-FOOTER] onPaste file ', file);
|
|
615
697
|
this.detectFiles(data)
|
|
616
698
|
}
|
|
617
699
|
}
|
|
@@ -620,15 +702,15 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
620
702
|
onDrop(event){
|
|
621
703
|
const items = event.dataTransfer.files;
|
|
622
704
|
let file = null;
|
|
623
|
-
this.logger.
|
|
705
|
+
this.logger.log('[CONV-FOOTER] onDrop items ', items);
|
|
624
706
|
for (const item of items) {
|
|
625
|
-
this.logger.
|
|
626
|
-
this.logger.
|
|
707
|
+
this.logger.log('[CONV-FOOTER] onDrop item ', item);
|
|
708
|
+
this.logger.log('[CONV-FOOTER] onDrop item.type ', item.type);
|
|
627
709
|
|
|
628
710
|
const data = {target: {files: new DataTransfer()}}
|
|
629
711
|
data.target.files = items
|
|
630
|
-
this.logger.
|
|
631
|
-
this.logger.
|
|
712
|
+
this.logger.log('[CONV-FOOTER] onDrop data', data);
|
|
713
|
+
this.logger.log('[CONV-FOOTER] onDrop file ', file);
|
|
632
714
|
this.detectFiles(data)
|
|
633
715
|
}
|
|
634
716
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
<!-- <audio *ngIf="metadata" controls>
|
|
3
|
+
<source [src]="metadata.src" type="audio/mpeg">
|
|
4
|
+
</audio> *ngIf="!metadata"-->
|
|
5
|
+
<div class="audio-container">
|
|
6
|
+
|
|
7
|
+
<div class="audio-track">
|
|
8
|
+
<button *ngIf="!isPlaying" class="play-pause" (click)="playPauseAudio()">
|
|
9
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
10
|
+
<path d="M320-200v-560l440 280-440 280Z"/>
|
|
11
|
+
</svg>
|
|
12
|
+
<!-- <i class="material-icons">play_arrow</i> -->
|
|
13
|
+
</button>
|
|
14
|
+
<button *ngIf="isPlaying" class="play-pause" (click)="playPauseAudio()">
|
|
15
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
16
|
+
<path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/>
|
|
17
|
+
</svg>
|
|
18
|
+
<!-- <i class="material-icons">pause</i> -->
|
|
19
|
+
</button>
|
|
20
|
+
<div class="duration" [style.color]="color" [style.font-size]="fontSize" >
|
|
21
|
+
<span *ngIf="!isPlaying">{{ audioDuration ? formatTime(audioDuration) : '00:00' }}</span>
|
|
22
|
+
<span *ngIf="isPlaying">{{ formatTime(currentTime) }}</span>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div class="audio-player-custom">
|
|
28
|
+
<audio #audioElement [src]="audioUrl"></audio>
|
|
29
|
+
<canvas #canvasElement class="waveformCanvas"></canvas>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
</div>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
|
|
2
|
+
:host {
|
|
3
|
+
--backgroundColor: #{var(--blue)};
|
|
4
|
+
--textColor: #{var(--bck-msg-sent)};
|
|
5
|
+
--hoverBackgroundColor: #{var(--bck-msg-sent)};
|
|
6
|
+
--hoverTextColor: #{var(--blue)};
|
|
7
|
+
--max-width: #{var(--button-in-msg-max-width)};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.audio-container{
|
|
11
|
+
position: relative;
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
width: 100%;
|
|
14
|
+
padding: 0px 12px;
|
|
15
|
+
margin: 6px 0px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
audio {
|
|
19
|
+
width: 272px;
|
|
20
|
+
height: 30px;
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 10px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.audio-recorder {
|
|
26
|
+
text-align: center;
|
|
27
|
+
margin: 0px;
|
|
28
|
+
display: inline-flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
height: 100%;
|
|
32
|
+
width: 100%;
|
|
33
|
+
float: left;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
button {
|
|
37
|
+
margin: 0px;
|
|
38
|
+
padding: 0px;
|
|
39
|
+
font-size: 16px;
|
|
40
|
+
border: none;
|
|
41
|
+
background-color: transparent;
|
|
42
|
+
color: var(--icon-fill-color);
|
|
43
|
+
fill: var(--icon-fill-color);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.waveformCanvas {
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 28px;
|
|
49
|
+
z-index: 1;
|
|
50
|
+
padding: 0px;
|
|
51
|
+
margin: 0%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.audio-track {
|
|
55
|
+
// width: 247px;//272px;
|
|
56
|
+
// height: 30px;
|
|
57
|
+
position: relative;
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
// margin: 0 13px;
|
|
61
|
+
margin: 0px;
|
|
62
|
+
.play-pause {
|
|
63
|
+
font-size: 20px;
|
|
64
|
+
width: 30px;
|
|
65
|
+
background-color: transparent;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
height: 30px;
|
|
68
|
+
margin: 0px;
|
|
69
|
+
transition: background-color 0.5s ease;
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
.play-pause:hover {
|
|
73
|
+
// background-color: #ddd;
|
|
74
|
+
// background-color: rgb(82, 160, 252);
|
|
75
|
+
background-color: #fff;
|
|
76
|
+
svg{
|
|
77
|
+
//fill:#fff;
|
|
78
|
+
fill: rgb(82, 160, 252);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
.duration {
|
|
82
|
+
padding: 0 3px;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.audio-player-custom {
|
|
87
|
+
// width: 200px;
|
|
88
|
+
// height: 32px;
|
|
89
|
+
// margin-left: 75px;
|
|
90
|
+
// position: absolute;
|
|
91
|
+
// overflow: hidden;
|
|
92
|
+
// z-index: 1;
|
|
93
|
+
// display: flex;
|
|
94
|
+
// align-items: center;
|
|
95
|
+
|
|
96
|
+
// width: calc(100% - 75px);
|
|
97
|
+
// height: 32px;
|
|
98
|
+
// margin-left: 65px;
|
|
99
|
+
// position: absolute;
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
z-index: 1;
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
width: 100%;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { AudioTrackComponent } from './audio-track.component';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
6
|
-
let component:
|
|
7
|
-
let fixture: ComponentFixture<
|
|
5
|
+
describe('AudioTrackComponent', () => {
|
|
6
|
+
let component: AudioTrackComponent;
|
|
7
|
+
let fixture: ComponentFixture<AudioTrackComponent>;
|
|
8
8
|
|
|
9
9
|
beforeEach(async () => {
|
|
10
10
|
await TestBed.configureTestingModule({
|
|
11
|
-
declarations: [
|
|
11
|
+
declarations: [ AudioTrackComponent ]
|
|
12
12
|
})
|
|
13
13
|
.compileComponents();
|
|
14
14
|
|
|
15
|
-
fixture = TestBed.createComponent(
|
|
15
|
+
fixture = TestBed.createComponent(AudioTrackComponent);
|
|
16
16
|
component = fixture.componentInstance;
|
|
17
17
|
fixture.detectChanges();
|
|
18
18
|
});
|