@chat21/chat21-web-widget 5.0.86 → 5.0.89-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 +22 -1
- package/package.json +1 -1
- package/src/app/app.module.ts +5 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +16 -16
- 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 +168 -77
- 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/app/utils/utils.ts +45 -0
- package/src/assets/twp/blank.html +3 -6
- package/src/assets/twp/chatbot-panel.html +5 -13
- package/src/assets/twp/index-dev.html +8 -15
- package/src/assets/twp/index.html +7 -13
- package/src/assets/twp/tiledesk_widget_files/bootstrap.min.css +4 -3
- package/src/assets/twp/tiledesk_widget_files/bootstrap.min.js +3 -4
- package/src/assets/twp/tiledesk_widget_files/jquery.min.js +2 -2
- 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/CHANGELOG.md
CHANGED
|
@@ -6,10 +6,31 @@
|
|
|
6
6
|
### **Copyrigth**:
|
|
7
7
|
*Tiledesk SRL*
|
|
8
8
|
|
|
9
|
-
# 5.0.
|
|
9
|
+
# 5.0.89-rc.1
|
|
10
|
+
- **added**: remove recipientId from storage after conversation is closed
|
|
11
|
+
|
|
12
|
+
# 5.0.85-rc.2
|
|
13
|
+
- **added**: loading progress indicator while closing a conversation
|
|
14
|
+
|
|
15
|
+
# 5.0.85-rc.1
|
|
16
|
+
- **added**: hide header restart menu option if conversation is closed
|
|
17
|
+
- **removed**: continueConversationBeforeTime settings property
|
|
10
18
|
|
|
11
19
|
# 5.0.85 in PROD
|
|
12
20
|
|
|
21
|
+
# 5.0.84-rc.4
|
|
22
|
+
- **added**: checkAcceptedFile fn on dragleave event conversation-content component
|
|
23
|
+
- **added**: checkAcceptedFile fn in conversation-footer component
|
|
24
|
+
|
|
25
|
+
# 5.0.84-rc.3
|
|
26
|
+
- **changed**: index-dev lib order import
|
|
27
|
+
|
|
28
|
+
# 5.0.84-rc.2
|
|
29
|
+
- **changed**: bootstrap, jquery and font-awesome libs
|
|
30
|
+
|
|
31
|
+
# 5.0.84-rc.1
|
|
32
|
+
- **removed**: innerHtml from document element
|
|
33
|
+
|
|
13
34
|
# 5.0.83 in PROD
|
|
14
35
|
|
|
15
36
|
# 5.0.83-rc.4
|
package/package.json
CHANGED
package/src/app/app.module.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { ConversationContentComponent } from './component/conversation-detail/co
|
|
|
15
15
|
import { ConversationFooterComponent } from './component/conversation-detail/conversation-footer/conversation-footer.component';
|
|
16
16
|
import { ConversationInternalFrameComponent } from './component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component';
|
|
17
17
|
import { ConversationPreviewComponent } from './component/conversation-detail/conversation-preview/conversation-preview.component';
|
|
18
|
+
import { ConversationAudioRecorderComponent } from './component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component';
|
|
18
19
|
/** CONVERSATION-DETAIL COMPONENTS */
|
|
19
20
|
import { BubbleMessageComponent } from './component/message/bubble-message/bubble-message.component';
|
|
20
21
|
import { AvatarComponent } from './component/message/avatar/avatar.component';
|
|
@@ -23,7 +24,7 @@ import { ImageComponent } from './component/message/image/image.component';
|
|
|
23
24
|
import { InfoMessageComponent } from './component/message/info-message/info-message.component';
|
|
24
25
|
import { HtmlComponent } from './component/message/html/html.component';
|
|
25
26
|
import { FrameComponent } from './component/message/frame/frame.component';
|
|
26
|
-
import {
|
|
27
|
+
import { AudioTrackComponent } from './component/message/audio-track/audio-track.component';
|
|
27
28
|
import { UserTypingComponent } from './../chat21-core/utils/user-typing/user-typing.component';
|
|
28
29
|
/** MESSAGE ATTACHMENTS COMPONENTS */
|
|
29
30
|
import { MessageAttachmentComponent } from './component/message-attachment/message-attachment.component';
|
|
@@ -138,6 +139,7 @@ import { ConfirmCloseComponent } from './modals/confirm-close/confirm-close.comp
|
|
|
138
139
|
|
|
139
140
|
|
|
140
141
|
|
|
142
|
+
|
|
141
143
|
const appInitializerFn = (appConfig: AppConfigService, brandService: BrandService, logger: NGXLogger) => {
|
|
142
144
|
return async() => {
|
|
143
145
|
let customLogger = new CustomLogger(logger)
|
|
@@ -276,6 +278,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
276
278
|
ConversationFooterComponent,
|
|
277
279
|
ConversationPreviewComponent,
|
|
278
280
|
ConversationInternalFrameComponent,
|
|
281
|
+
ConversationAudioRecorderComponent,
|
|
279
282
|
BubbleMessageComponent,
|
|
280
283
|
AvatarComponent,
|
|
281
284
|
FrameComponent,
|
|
@@ -287,6 +290,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
287
290
|
ActionButtonComponent,
|
|
288
291
|
LinkButtonComponent,
|
|
289
292
|
TextButtonComponent,
|
|
293
|
+
AudioTrackComponent,
|
|
290
294
|
UserTypingComponent,
|
|
291
295
|
/**DIRECTIVES */
|
|
292
296
|
HtmlEntitiesEncodePipe,
|
|
@@ -295,7 +299,6 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
295
299
|
SafeHtmlPipe,
|
|
296
300
|
LikeUnlikeComponent,
|
|
297
301
|
TooltipDirective,
|
|
298
|
-
AudioComponent,
|
|
299
302
|
CarouselComponent,
|
|
300
303
|
NetworkOfflineComponent,
|
|
301
304
|
ConfirmCloseComponent
|
|
@@ -39,6 +39,7 @@ import { CustomTranslateService } from 'src/chat21-core/providers/custom-transla
|
|
|
39
39
|
import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
|
|
40
40
|
import { TiledeskRequestsService } from 'src/chat21-core/providers/tiledesk/tiledesk-requests.service';
|
|
41
41
|
import { ConversationContentComponent } from '../conversation-content/conversation-content.component';
|
|
42
|
+
import { checkAcceptedFile } from 'src/app/utils/utils';
|
|
42
43
|
// import { TranslateService } from '@ngx-translate/core';
|
|
43
44
|
|
|
44
45
|
@Component({
|
|
@@ -1002,7 +1003,8 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
1002
1003
|
case 'confirm':
|
|
1003
1004
|
this.tiledeskRequestService.closeSupportGroup(this.conversationId).then(data => {
|
|
1004
1005
|
if(data === 'closed'){
|
|
1005
|
-
this.mydialog.nativeElement.close()
|
|
1006
|
+
this.mydialog.nativeElement.close();
|
|
1007
|
+
this.appStorageService.removeItem('recipientId');
|
|
1006
1008
|
this.logger.debug('[CONV-COMP] chat closed successfully with uid ', this.conversationId)
|
|
1007
1009
|
}
|
|
1008
1010
|
}).catch(error => {
|
|
@@ -1346,34 +1348,32 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
|
|
|
1346
1348
|
var mimeType = fileList[0].type
|
|
1347
1349
|
this.logger.log('[CONV-COMP] ----> FILE - DROP mimeType files ', mimeType)
|
|
1348
1350
|
|
|
1349
|
-
// if (mimeType.startsWith("image") || mimeType.startsWith("application")) {
|
|
1350
|
-
// this.logger.log('[CONV-COMP] ----> FILE - DROP mimeType files: ', this.appConfigProvider.getConfig().fileUploadAccept);
|
|
1351
|
-
// this.checkAcceptedFile(mimeType);
|
|
1352
|
-
// const isAccepted = this.checkAcceptedFile(mimeType)
|
|
1353
|
-
// this.logger.log('[CONV-COMP] > checkAcceptedFile - fileUploadAccept isAcceptFile FILE - DROP',isAccepted)
|
|
1354
|
-
// if (isAccepted === true) {
|
|
1355
1351
|
this.dropEvent = event
|
|
1356
|
-
// } else {
|
|
1357
|
-
// this.logger.log( '[CONV-COMP] ----> FILE - DROP mimeType files ', mimeType,'NOT SUPPORTED FILE TYPE')
|
|
1358
|
-
// this.presentToast(this.translationsMap.get('FAILED_TO_UPLOAD_THE_FORMAT_IS_NOT_SUPPORTED'), 'danger','toast-custom-class', 5000 )
|
|
1359
|
-
// // this.presentToastOnlyImageFilesAreAllowedToDrag()
|
|
1360
|
-
// }
|
|
1361
1352
|
|
|
1362
1353
|
}
|
|
1363
1354
|
}
|
|
1364
1355
|
|
|
1365
1356
|
allowDrop(event: any) {
|
|
1366
|
-
event.preventDefault()
|
|
1367
|
-
event.stopPropagation()
|
|
1357
|
+
event.preventDefault();
|
|
1358
|
+
event.stopPropagation();
|
|
1368
1359
|
this.logger.log('[CONV-COMP] ----> FILE - (dragover) allowDrop ev ', event)
|
|
1369
1360
|
this.isHovering = true
|
|
1370
1361
|
}
|
|
1371
1362
|
|
|
1372
1363
|
drag(event){
|
|
1373
|
-
event.preventDefault()
|
|
1364
|
+
event.preventDefault();
|
|
1365
|
+
this.logger.log('[CONV-COMP] ----> FILE - (dragleave) drag ev ', event)
|
|
1366
|
+
if (event.dataTransfer && event.dataTransfer.files) {
|
|
1367
|
+
const files = event.dataTransfer.files;
|
|
1368
|
+
const canUploadFile = checkAcceptedFile(files[0].type, this.appConfigService.getConfig().fileUploadAccept)
|
|
1369
|
+
if(!canUploadFile){
|
|
1370
|
+
this.logger.error('[IMAGE-UPLOAD] detectFiles: can not upload current file type--> NOT ALLOWED', this.appConfigService.getConfig().fileUploadAccept)
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
1374
|
event.stopPropagation()
|
|
1375
|
-
console.log('dragleave-->', event)
|
|
1376
1375
|
this.isHovering = false
|
|
1377
1376
|
}
|
|
1378
1377
|
|
|
1379
1378
|
}
|
|
1379
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<div class="audio-recorder">
|
|
2
|
+
<button *ngIf="audioUrl" (click)="deleteRecording()">
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm80-160h80v-360h-80v360Zm160 0h80v-360h-80v360Z"/></svg>
|
|
4
|
+
<!-- <i class="material-icons">delete_outline</i> -->
|
|
5
|
+
</button>
|
|
6
|
+
|
|
7
|
+
<chat-audio-track *ngIf="audioBlob && audioUrl"
|
|
8
|
+
[audioBlob] = "audioBlob"
|
|
9
|
+
[color]="stylesMap.get('themeColor')"
|
|
10
|
+
[fontSize]="stylesMap.get('fontSize')"
|
|
11
|
+
[stylesMap]="stylesMap">
|
|
12
|
+
</chat-audio-track>
|
|
13
|
+
|
|
14
|
+
<button *ngIf="!audioUrl" class="mic-button" (mousedown)="startRecording()" (mouseup)="stopRecording()">
|
|
15
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
16
|
+
<path d="M480-400q-50 0-85-35t-35-85v-240q0-50 35-85t85-35q50 0 85 35t35 85v240q0 50-35 85t-85 35Zm0-240Zm-40 520v-123q-104-14-172-93t-68-184h80q0 83 58.5 141.5T480-320q83 0 141.5-58.5T680-520h80q0 105-68 184t-172 93v123h-80Zm40-360q17 0 28.5-11.5T520-520v-240q0-17-11.5-28.5T480-800q-17 0-28.5 11.5T440-760v240q0 17 11.5 28.5T480-480Z"/>
|
|
17
|
+
</svg>
|
|
18
|
+
</button>
|
|
19
|
+
<!-- <button *ngIf="isRecording" (click)="stopRecording()"><i class="material-icons">pause_circle_outline</i></button> -->
|
|
20
|
+
|
|
21
|
+
<button *ngIf="audioUrl" (click)="sendMessage()">
|
|
22
|
+
<span class="v-align-center">
|
|
23
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="20" width="24" viewBox="0 0 24 20" xml:space="preserve">
|
|
24
|
+
<path d="M1.8,18.9V1.7L22,10.3L1.8,18.9z M3.9,15.6l12.6-5.4L3.9,4.9v3.7l6.4,1.6l-6.4,1.6V15.6z M3.9,15.6V4.9v7V15.6z"/>
|
|
25
|
+
</svg>
|
|
26
|
+
</span>
|
|
27
|
+
</button>
|
|
28
|
+
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
|
|
2
|
+
@font-face {
|
|
3
|
+
font-family: 'Material Icons';
|
|
4
|
+
src: url('https://fonts.googleapis.com/icon?family=Material+Icons');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.material-icons.mic_none::before {
|
|
8
|
+
content: 'mic_none';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.audio-recorder {
|
|
12
|
+
text-align: center;
|
|
13
|
+
margin: 0px;
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
float: left;
|
|
20
|
+
gap: 10px
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
chat-audio-track {
|
|
24
|
+
display: flex;
|
|
25
|
+
width: 70%;
|
|
26
|
+
margin: 8px 0;
|
|
27
|
+
pointer-events: auto;
|
|
28
|
+
border-radius: var(--chat-footer-border-radius);
|
|
29
|
+
background-color: var(--chat-footer-background-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
button {
|
|
33
|
+
margin: 0px;
|
|
34
|
+
padding: 0px;
|
|
35
|
+
font-size: 16px;
|
|
36
|
+
border: none;
|
|
37
|
+
background-color: transparent;
|
|
38
|
+
color: var(--icon-fill-color);
|
|
39
|
+
fill: var(--icon-fill-color);
|
|
40
|
+
height: var(--chat-footer-height);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.mic-button {
|
|
44
|
+
position: relative;
|
|
45
|
+
background-color: transparent;
|
|
46
|
+
border: none;
|
|
47
|
+
outline: none;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
padding: 20px;
|
|
50
|
+
border-radius: 50%;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
display: inline-flex;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.mic-button svg {
|
|
58
|
+
width: 24px;
|
|
59
|
+
height: 24px;
|
|
60
|
+
fill: var(--icon-fill-color);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.mic-button::before {
|
|
64
|
+
content: '';
|
|
65
|
+
position: absolute;
|
|
66
|
+
top: auto;
|
|
67
|
+
left: auto;
|
|
68
|
+
width: 35px;
|
|
69
|
+
height: 35px;
|
|
70
|
+
background-color: var(--icon-fill-color);
|
|
71
|
+
border-radius: 50%;
|
|
72
|
+
transform: scale(0);
|
|
73
|
+
transition: transform 0.3s ease;
|
|
74
|
+
transform-origin: center;
|
|
75
|
+
z-index: -1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.mic-button:active::before {
|
|
79
|
+
transform: scale(0.5);
|
|
80
|
+
animation: pulse 1s infinite ease-in-out;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.mic-button:active {
|
|
84
|
+
svg {
|
|
85
|
+
color: #fff;
|
|
86
|
+
fill: #fff;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@keyframes pulse {
|
|
91
|
+
0% {
|
|
92
|
+
transform: scale(1);
|
|
93
|
+
opacity: 1;
|
|
94
|
+
}
|
|
95
|
+
50% {
|
|
96
|
+
transform: scale(0.9);
|
|
97
|
+
opacity: 0.7;
|
|
98
|
+
}
|
|
99
|
+
100% {
|
|
100
|
+
transform: scale(1);
|
|
101
|
+
opacity: 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { ConversationAudioRecorderComponent } from './conversation-audio-recorder.component';
|
|
4
|
+
|
|
5
|
+
describe('AudioRecorderComponent', () => {
|
|
6
|
+
let component: ConversationAudioRecorderComponent;
|
|
7
|
+
let fixture: ComponentFixture<ConversationAudioRecorderComponent>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
declarations: [ ConversationAudioRecorderComponent ]
|
|
12
|
+
})
|
|
13
|
+
.compileComponents();
|
|
14
|
+
|
|
15
|
+
fixture = TestBed.createComponent(ConversationAudioRecorderComponent);
|
|
16
|
+
component = fixture.componentInstance;
|
|
17
|
+
fixture.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
expect(component).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'chat-audio-recorder',
|
|
6
|
+
templateUrl: './conversation-audio-recorder.component.html',
|
|
7
|
+
styleUrls: ['./conversation-audio-recorder.component.scss']
|
|
8
|
+
})
|
|
9
|
+
export class ConversationAudioRecorderComponent {
|
|
10
|
+
|
|
11
|
+
@Input() stylesMap: Map<string, string>;
|
|
12
|
+
@Output() startRecordingEvent = new EventEmitter<void>();
|
|
13
|
+
@Output() deleteRecordingEvent = new EventEmitter<void>();
|
|
14
|
+
@Output() endRecordingEvent = new EventEmitter<Blob | null>();
|
|
15
|
+
@Output() sendRecordingEvent = new EventEmitter<Blob | null>();
|
|
16
|
+
|
|
17
|
+
mediaRecorder: MediaRecorder | null = null;
|
|
18
|
+
audioChunks: Blob[] = [];
|
|
19
|
+
audioBlob: Blob | null = null;
|
|
20
|
+
audioUrl: SafeUrl | null = null;
|
|
21
|
+
|
|
22
|
+
isRecording = false;
|
|
23
|
+
rawAudioUrl: string | null = null;
|
|
24
|
+
isPlaying: boolean = false;
|
|
25
|
+
startTime: number;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
constructor(private sanitizer: DomSanitizer) {}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
startRecording() {
|
|
33
|
+
// console.log('startRecording');
|
|
34
|
+
this.startTime = Date.now();
|
|
35
|
+
navigator.mediaDevices.getUserMedia({ audio: true })
|
|
36
|
+
.then(stream => {
|
|
37
|
+
this.mediaRecorder = new MediaRecorder(stream);
|
|
38
|
+
this.mediaRecorder.start();
|
|
39
|
+
this.isRecording = true;
|
|
40
|
+
this.startRecordingEvent.emit();
|
|
41
|
+
this.mediaRecorder.addEventListener('dataavailable', (event) => {
|
|
42
|
+
this.audioChunks.push(event.data);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.mediaRecorder.addEventListener('stop', () => {
|
|
46
|
+
this.audioBlob = new Blob(this.audioChunks, { type: 'audio/mpeg' });
|
|
47
|
+
this.rawAudioUrl = URL.createObjectURL(this.audioBlob);
|
|
48
|
+
this.audioUrl = this.sanitizer.bypassSecurityTrustUrl(this.rawAudioUrl);
|
|
49
|
+
this.audioChunks = [];
|
|
50
|
+
this.endRecordingEvent.emit(this.audioBlob);
|
|
51
|
+
});
|
|
52
|
+
})
|
|
53
|
+
.catch(error => {
|
|
54
|
+
console.error('Errore nell’accesso al microfono:', error);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
stopRecording() {
|
|
59
|
+
let endTime = Date.now();
|
|
60
|
+
let time = endTime - this.startTime;
|
|
61
|
+
if(time > 500){
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
if (this.mediaRecorder) {
|
|
64
|
+
this.mediaRecorder.stop();
|
|
65
|
+
this.isRecording = false;
|
|
66
|
+
}
|
|
67
|
+
}, 300);
|
|
68
|
+
|
|
69
|
+
} else {
|
|
70
|
+
this.audioUrl = null;
|
|
71
|
+
this.isPlaying = false;
|
|
72
|
+
this.rawAudioUrl = null;
|
|
73
|
+
this.audioUrl = null;
|
|
74
|
+
this.audioBlob = null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
deleteRecording() {
|
|
81
|
+
this.audioUrl = null;
|
|
82
|
+
this.isPlaying = false;
|
|
83
|
+
this.rawAudioUrl = null;
|
|
84
|
+
this.audioUrl = null;
|
|
85
|
+
this.audioBlob = null;
|
|
86
|
+
this.deleteRecordingEvent.emit(null);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
sendMessage(){
|
|
90
|
+
if (this.audioUrl) {
|
|
91
|
+
this.sendRecordingEvent.emit(this.audioBlob);
|
|
92
|
+
this.audioUrl = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<!-- TEXTAREA + ICONS: conv active-->
|
|
8
8
|
<div class="textarea-container" *ngIf="!hideTextAreaContent && !hideTextReply">
|
|
9
9
|
|
|
10
|
-
<div class="icons-container">
|
|
10
|
+
<div *ngIf="!isStopRec" class="icons-container">
|
|
11
11
|
<!-- ICON ATTACHMENT -->
|
|
12
12
|
<label *ngIf="showAttachmentButton == true" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
|
|
13
13
|
<span class="v-align-center">
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
<div class="visible-text-area" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
|
|
47
|
+
<div *ngIf="!isStopRec" class="visible-text-area" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
|
|
48
48
|
<!-- isFilePendingToUpload || -->
|
|
49
49
|
<textarea
|
|
50
50
|
[attr.disabled] = "(hideTextReply)? true : null"
|
|
@@ -67,13 +67,24 @@
|
|
|
67
67
|
</div>
|
|
68
68
|
|
|
69
69
|
<!-- ICON SEND -->
|
|
70
|
-
<div tabindex="-1" class="chat21-textarea-button" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
|
|
70
|
+
<div *ngIf="textInputTextArea && !isStopRec" tabindex="-1" class="chat21-textarea-button" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
|
|
71
71
|
<span class="v-align-center">
|
|
72
72
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="24" width="24" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
|
73
73
|
<path d="M1.8,18.9V1.7L22,10.3L1.8,18.9z M3.9,15.6l12.6-5.4L3.9,4.9v3.7l6.4,1.6l-6.4,1.6V15.6z M3.9,15.6V4.9v7V15.6z"/>
|
|
74
74
|
</svg>
|
|
75
75
|
</span>
|
|
76
76
|
</div>
|
|
77
|
+
|
|
78
|
+
<!-- ICON REC -->
|
|
79
|
+
<div *ngIf="!textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
|
|
80
|
+
<chat-audio-recorder
|
|
81
|
+
(startRecordingEvent)="onStartRecording()"
|
|
82
|
+
(deleteRecordingEvent)="onDeleteRecording()"
|
|
83
|
+
(endRecordingEvent)="onEndRecording($event)"
|
|
84
|
+
(sendRecordingEvent)="onSendRecording($event)"
|
|
85
|
+
[stylesMap]="stylesMap">
|
|
86
|
+
</chat-audio-recorder>
|
|
87
|
+
</div>
|
|
77
88
|
</div>
|
|
78
89
|
|
|
79
90
|
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss
CHANGED
|
@@ -7,14 +7,16 @@
|
|
|
7
7
|
display: flex;
|
|
8
8
|
width: 100%;
|
|
9
9
|
align-items: center;
|
|
10
|
-
gap:
|
|
10
|
+
gap: 0px;
|
|
11
11
|
justify-content: space-between;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.icons-container{
|
|
15
15
|
display: flex;
|
|
16
16
|
align-self: flex-end;
|
|
17
|
-
margin-left: 8px
|
|
17
|
+
margin-left: 8px;
|
|
18
|
+
gap: 2px;
|
|
19
|
+
margin-right: 8px;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
.visible-text-area {
|
|
@@ -31,7 +33,6 @@
|
|
|
31
33
|
.chat21-textarea-button {
|
|
32
34
|
fill: var(--icon-fill-color);
|
|
33
35
|
pointer-events: auto;
|
|
34
|
-
|
|
35
36
|
height: var(--chat-footer-height);
|
|
36
37
|
bottom: 22px;
|
|
37
38
|
opacity: 0.3;
|
|
@@ -185,11 +186,29 @@ textarea:active{
|
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
#chat21-button-send {
|
|
188
|
-
// right: 8px;
|
|
189
|
-
// bottom: 0;
|
|
190
189
|
display: flex;
|
|
191
190
|
align-self: flex-end;
|
|
192
|
-
margin: 0 8px
|
|
191
|
+
margin: 0 8px;
|
|
192
|
+
width: 34px;
|
|
193
|
+
text-align: center;
|
|
194
|
+
justify-content: center;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#chat21-button-rec {
|
|
198
|
+
display: flex;
|
|
199
|
+
width: 34px;
|
|
200
|
+
text-align: center;
|
|
201
|
+
justify-content: center;
|
|
202
|
+
height: var(--chat-footer-height);
|
|
203
|
+
&.active{
|
|
204
|
+
width: 100%;
|
|
205
|
+
}
|
|
206
|
+
chat-audio-recorder {
|
|
207
|
+
width: 100%;
|
|
208
|
+
display: flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
justify-content: center;
|
|
211
|
+
}
|
|
193
212
|
}
|
|
194
213
|
|
|
195
214
|
#chat21-file{
|
|
@@ -337,7 +356,4 @@ textarea:active{
|
|
|
337
356
|
// left: 10px;
|
|
338
357
|
border: none;
|
|
339
358
|
margin: -2px -2px 0px;
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
359
|
+
}
|