@chat21/chat21-web-widget 5.0.89 → 5.0.90-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.
- package/CHANGELOG.md +11 -3
- package/package.json +1 -1
- package/src/app/app.component.ts +15 -11
- package/src/app/app.module.ts +5 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.html +2 -1
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.html +31 -0
- package/src/app/component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component.scss +108 -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 +16 -5
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +38 -11
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +125 -42
- 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 +30 -5
- 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/providers/global-settings.service.ts +32 -32
- package/src/app/utils/globals.ts +12 -6
- package/src/assets/twp/index-dev.html +26 -9
- 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,13 +6,21 @@
|
|
|
6
6
|
### **Copyrigth**:
|
|
7
7
|
*Tiledesk SRL*
|
|
8
8
|
|
|
9
|
+
# 5.0.90-rc.2
|
|
10
|
+
- **added**: ability to manage footer attachment and emoji buttons
|
|
11
|
+
|
|
12
|
+
# 5.0.90-rc.1
|
|
13
|
+
- **bug-fixed**: if autoStart is false, container page is blocked on mobile when onPageChangeVisibilityMobile is set to 'open'
|
|
14
|
+
|
|
9
15
|
# 5.0.89 in PROD
|
|
10
16
|
|
|
11
17
|
# 5.0.88 in PROD
|
|
12
18
|
|
|
13
|
-
# 5.0.
|
|
19
|
+
# 5.0.89-rc.2
|
|
20
|
+
- minor fix
|
|
14
21
|
|
|
15
|
-
# 5.0.
|
|
22
|
+
# 5.0.89-rc.1
|
|
23
|
+
- **added**: remove recipientId from storage after conversation is closed
|
|
16
24
|
|
|
17
25
|
# 5.0.85-rc.2
|
|
18
26
|
- **added**: loading progress indicator while closing a conversation
|
|
@@ -21,7 +29,7 @@
|
|
|
21
29
|
- **added**: hide header restart menu option if conversation is closed
|
|
22
30
|
- **removed**: continueConversationBeforeTime settings property
|
|
23
31
|
|
|
24
|
-
# 5.0.
|
|
32
|
+
# 5.0.85 in PROD
|
|
25
33
|
|
|
26
34
|
# 5.0.84-rc.4
|
|
27
35
|
- **added**: checkAcceptedFile fn on dragleave event conversation-content component
|
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -267,17 +267,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
267
267
|
this.disposeWidget()
|
|
268
268
|
return;
|
|
269
269
|
}
|
|
270
|
-
|
|
271
|
-
if(this.g.isMobile && this.g.onPageChangeVisibilityMobile !== 'last'){
|
|
272
|
-
let isOpen = this.g.onPageChangeVisibilityMobile === 'open'? true: false
|
|
273
|
-
this.g.setIsOpen(isOpen)
|
|
274
|
-
this.appStorageService.setItem('isOpen', isOpen)
|
|
275
|
-
}
|
|
276
|
-
if(!this.g.isMobile && this.g.onPageChangeVisibilityDesktop !== 'last'){
|
|
277
|
-
let isOpen = this.g.onPageChangeVisibilityDesktop === 'open'? true: false
|
|
278
|
-
this.g.setIsOpen(isOpen)
|
|
279
|
-
this.appStorageService.setItem('isOpen', isOpen)
|
|
280
|
-
}
|
|
270
|
+
|
|
281
271
|
|
|
282
272
|
/**CHECK IF JWT IS IN URL PARAMETERS */
|
|
283
273
|
this.logger.debug('[APP-COMP] check if token is passed throw url: ', this.g.jwt);
|
|
@@ -433,6 +423,20 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
433
423
|
that.listenToWidgetClick()
|
|
434
424
|
}
|
|
435
425
|
|
|
426
|
+
|
|
427
|
+
//set status (open /close)
|
|
428
|
+
if(this.g.isMobile && this.g.onPageChangeVisibilityMobile !== 'last'){
|
|
429
|
+
let isOpen = this.g.onPageChangeVisibilityMobile === 'open'? true: false
|
|
430
|
+
this.g.setIsOpen(isOpen)
|
|
431
|
+
this.appStorageService.setItem('isOpen', isOpen)
|
|
432
|
+
}
|
|
433
|
+
if(!this.g.isMobile && this.g.onPageChangeVisibilityDesktop !== 'last'){
|
|
434
|
+
let isOpen = this.g.onPageChangeVisibilityDesktop === 'open'? true: false
|
|
435
|
+
this.g.setIsOpen(isOpen)
|
|
436
|
+
this.appStorageService.setItem('isOpen', isOpen)
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
|
|
436
440
|
} else if (state && state === AUTH_STATE_OFFLINE && !this.forceDisconnect) {
|
|
437
441
|
/** non sono loggato */
|
|
438
442
|
that.logger.info('[APP-COMP] OFFLINE - NO CURRENT USER AUTENTICATE: ');
|
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
|
|
@@ -117,7 +117,8 @@
|
|
|
117
117
|
[channelType]="g?.channelType"
|
|
118
118
|
[userFullname]="g?.userFullname"
|
|
119
119
|
[userEmail]="g?.userEmail"
|
|
120
|
-
[
|
|
120
|
+
[showAttachmentFooterButton]="g?.showAttachmentFooterButton"
|
|
121
|
+
[showEmojiFooterButton]="g?.showEmojiFooterButton"
|
|
121
122
|
[hideTextAreaContent]="(g?.singleConversation && hideTextAreaContent) || (isConversationArchived && !g?.allowReopen)"
|
|
122
123
|
[isConversationArchived]="isConversationArchived"
|
|
123
124
|
[hideTextReply]="hideFooterTextReply"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<div class="audio-recorder">
|
|
2
|
+
<button *ngIf="audioUrl" (click)="deleteRecording()">
|
|
3
|
+
<span class="v-align-center">
|
|
4
|
+
<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>
|
|
5
|
+
<!-- <i class="material-icons">delete_outline</i> -->
|
|
6
|
+
</span>
|
|
7
|
+
</button>
|
|
8
|
+
|
|
9
|
+
<chat-audio-track *ngIf="audioBlob && audioUrl"
|
|
10
|
+
[audioBlob] = "audioBlob"
|
|
11
|
+
[color]="stylesMap.get('themeColor')"
|
|
12
|
+
[fontSize]="stylesMap.get('fontSize')"
|
|
13
|
+
[stylesMap]="stylesMap">
|
|
14
|
+
</chat-audio-track>
|
|
15
|
+
|
|
16
|
+
<button *ngIf="!audioUrl" class="mic-button" (mousedown)="startRecording()" (mouseup)="stopRecording()">
|
|
17
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
18
|
+
<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"/>
|
|
19
|
+
</svg>
|
|
20
|
+
</button>
|
|
21
|
+
<!-- <button *ngIf="isRecording" (click)="stopRecording()"><i class="material-icons">pause_circle_outline</i></button> -->
|
|
22
|
+
|
|
23
|
+
<button *ngIf="audioUrl" (click)="sendMessage()">
|
|
24
|
+
<span class="v-align-center">
|
|
25
|
+
<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">
|
|
26
|
+
<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"/>
|
|
27
|
+
</svg>
|
|
28
|
+
</span>
|
|
29
|
+
</button>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
@@ -0,0 +1,108 @@
|
|
|
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: 8px
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
chat-audio-track {
|
|
24
|
+
display: flex;
|
|
25
|
+
width: 80%;
|
|
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
|
+
font-size: 16px;
|
|
34
|
+
border: none;
|
|
35
|
+
background-color: transparent;
|
|
36
|
+
color: var(--icon-fill-color);
|
|
37
|
+
fill: var(--icon-fill-color);
|
|
38
|
+
height: var(--chat-footer-height);
|
|
39
|
+
|
|
40
|
+
display: flex;
|
|
41
|
+
align-self: flex-end;
|
|
42
|
+
// margin: 0 8px;
|
|
43
|
+
width: 34px;
|
|
44
|
+
text-align: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.mic-button {
|
|
49
|
+
position: relative;
|
|
50
|
+
background-color: transparent;
|
|
51
|
+
border: none;
|
|
52
|
+
outline: none;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
// padding: 20px;
|
|
55
|
+
border-radius: 50%;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
justify-content: center;
|
|
59
|
+
align-items: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.mic-button svg {
|
|
63
|
+
width: 24px;
|
|
64
|
+
height: 24px;
|
|
65
|
+
fill: var(--icon-fill-color);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.mic-button::before {
|
|
69
|
+
content: '';
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: auto;
|
|
72
|
+
left: auto;
|
|
73
|
+
width: 35px;
|
|
74
|
+
height: 35px;
|
|
75
|
+
background-color: var(--icon-fill-color);
|
|
76
|
+
border-radius: 50%;
|
|
77
|
+
transform: scale(0);
|
|
78
|
+
transition: transform 0.3s ease;
|
|
79
|
+
transform-origin: center;
|
|
80
|
+
z-index: -1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.mic-button:active::before {
|
|
84
|
+
transform: scale(0.5);
|
|
85
|
+
animation: pulse 1s infinite ease-in-out;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.mic-button:active {
|
|
89
|
+
svg {
|
|
90
|
+
color: #fff;
|
|
91
|
+
fill: #fff;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@keyframes pulse {
|
|
96
|
+
0% {
|
|
97
|
+
transform: scale(1);
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
50% {
|
|
101
|
+
transform: scale(0.9);
|
|
102
|
+
opacity: 0.7;
|
|
103
|
+
}
|
|
104
|
+
100% {
|
|
105
|
+
transform: scale(1);
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -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,9 +7,9 @@
|
|
|
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
|
-
<label *ngIf="
|
|
12
|
+
<label *ngIf="showAttachmentFooterButton" 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">
|
|
14
14
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 28 28" transform="rotate(45)">
|
|
15
15
|
<path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z" />
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
(change)="detectFiles($event)"/>
|
|
30
30
|
</label>
|
|
31
31
|
<!-- ICON EMOJII -->
|
|
32
|
-
<label tabindex="1504" aria-label="emojii" for="chat21-emojii" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-emoticon-picker" (click)="onEmojiiPickerClicked()">
|
|
32
|
+
<label *ngIf="showEmojiFooterButton" tabindex="1504" aria-label="emojii" for="chat21-emojii" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-emoticon-picker" (click)="onEmojiiPickerClicked()">
|
|
33
33
|
<span class="v-align-center">
|
|
34
34
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
|
|
35
35
|
<path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
|
|
@@ -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
|
@@ -5,16 +5,29 @@
|
|
|
5
5
|
// padding-left: 70px;
|
|
6
6
|
// padding-right: 45px;
|
|
7
7
|
display: flex;
|
|
8
|
-
width: 100%;
|
|
8
|
+
// width: 100%;
|
|
9
9
|
align-items: center;
|
|
10
|
-
gap:
|
|
10
|
+
gap: 8px;
|
|
11
11
|
justify-content: space-between;
|
|
12
|
+
margin: 0px 8px;
|
|
13
|
+
|
|
14
|
+
//if attachment icon OR emoji icon is not in DOM -> increment textarea width
|
|
15
|
+
&:has(:not(#chat21-start-upload-doc), :not(#chat21-emoticon-picker)) .visible-text-area {
|
|
16
|
+
width: 80%;
|
|
17
|
+
}
|
|
18
|
+
//if attachment icon AND emoji icon is not in DOM -> increment textarea width
|
|
19
|
+
&:has(:not(#chat21-start-upload-doc)):has(:not(#chat21-emoticon-picker)) .visible-text-area {
|
|
20
|
+
width: 90%;
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
.icons-container{
|
|
15
26
|
display: flex;
|
|
16
27
|
align-self: flex-end;
|
|
17
|
-
margin-left: 8px
|
|
28
|
+
// margin-left: 8px;
|
|
29
|
+
// margin-right: 8px;
|
|
30
|
+
gap: 8px;
|
|
18
31
|
}
|
|
19
32
|
|
|
20
33
|
.visible-text-area {
|
|
@@ -31,7 +44,6 @@
|
|
|
31
44
|
.chat21-textarea-button {
|
|
32
45
|
fill: var(--icon-fill-color);
|
|
33
46
|
pointer-events: auto;
|
|
34
|
-
|
|
35
47
|
height: var(--chat-footer-height);
|
|
36
48
|
bottom: 22px;
|
|
37
49
|
opacity: 0.3;
|
|
@@ -185,11 +197,29 @@ textarea:active{
|
|
|
185
197
|
}
|
|
186
198
|
|
|
187
199
|
#chat21-button-send {
|
|
188
|
-
// right: 8px;
|
|
189
|
-
// bottom: 0;
|
|
190
200
|
display: flex;
|
|
191
201
|
align-self: flex-end;
|
|
192
|
-
margin: 0 8px
|
|
202
|
+
// margin: 0 8px;
|
|
203
|
+
width: 34px;
|
|
204
|
+
text-align: center;
|
|
205
|
+
justify-content: center;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
#chat21-button-rec {
|
|
209
|
+
display: flex;
|
|
210
|
+
width: 34px;
|
|
211
|
+
text-align: center;
|
|
212
|
+
justify-content: center;
|
|
213
|
+
height: var(--chat-footer-height);
|
|
214
|
+
&.active{
|
|
215
|
+
width: 100%;
|
|
216
|
+
}
|
|
217
|
+
chat-audio-recorder {
|
|
218
|
+
width: 100%;
|
|
219
|
+
display: flex;
|
|
220
|
+
align-items: center;
|
|
221
|
+
justify-content: center;
|
|
222
|
+
}
|
|
193
223
|
}
|
|
194
224
|
|
|
195
225
|
#chat21-file{
|
|
@@ -337,7 +367,4 @@ textarea:active{
|
|
|
337
367
|
// left: 10px;
|
|
338
368
|
border: none;
|
|
339
369
|
margin: -2px -2px 0px;
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
370
|
+
}
|