@chat21/chat21-web-widget 5.1.32-rc4 → 5.1.33

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 (59) hide show
  1. package/.github/workflows/docker-community-push-latest.yml +13 -23
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +12 -22
  3. package/CHANGELOG.md +7 -50
  4. package/Dockerfile +5 -4
  5. package/angular.json +2 -5
  6. package/deploy_amazon_beta.sh +7 -17
  7. package/deploy_amazon_prod.sh +41 -0
  8. package/docs/changelog/this-branch.md +0 -36
  9. package/nginx.conf +2 -22
  10. package/package.json +1 -4
  11. package/src/app/app.component.ts +9 -10
  12. package/src/app/app.module.ts +0 -9
  13. package/src/app/component/conversation-detail/conversation/conversation.component.html +2 -8
  14. package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -12
  15. package/src/app/component/conversation-detail/conversation/conversation.component.ts +5 -45
  16. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +1 -1
  17. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -10
  18. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +0 -1
  19. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +79 -146
  20. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +13 -140
  21. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +7 -124
  22. package/src/app/component/last-message/last-message.component.ts +1 -4
  23. package/src/app/component/message/audio/audio.component.ts +5 -0
  24. package/src/app/component/message/bubble-message/bubble-message.component.html +1 -6
  25. package/src/app/component/message/bubble-message/bubble-message.component.ts +1 -2
  26. package/src/app/providers/global-settings.service.ts +0 -21
  27. package/src/app/providers/translator.service.ts +0 -2
  28. package/src/app/sass/_variables.scss +0 -3
  29. package/src/app/utils/globals.ts +1 -7
  30. package/src/assets/i18n/en.json +0 -1
  31. package/src/assets/i18n/es.json +0 -1
  32. package/src/assets/i18n/fr.json +0 -1
  33. package/src/assets/i18n/it.json +0 -1
  34. package/src/chat21-core/models/message.ts +1 -2
  35. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +2 -3
  36. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +0 -12
  37. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  38. package/src/chat21-core/utils/utils-message.ts +0 -7
  39. package/src/chat21-core/utils/utils.ts +2 -5
  40. package/src/launch.js +41 -32
  41. package/src/launch_template.js +41 -32
  42. package/tsconfig.json +0 -5
  43. package/src/app/component/message/audio-sync/audio-sync.component.html +0 -19
  44. package/src/app/component/message/audio-sync/audio-sync.component.scss +0 -65
  45. package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +0 -23
  46. package/src/app/component/message/audio-sync/audio-sync.component.ts +0 -197
  47. package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +0 -12
  48. package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +0 -171
  49. package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +0 -39
  50. package/src/app/providers/voice/audio.types.ts +0 -34
  51. package/src/app/providers/voice/vad.service.spec.ts +0 -28
  52. package/src/app/providers/voice/vad.service.ts +0 -70
  53. package/src/app/providers/voice/voice.service.spec.ts +0 -60
  54. package/src/app/providers/voice/voice.service.ts +0 -294
  55. package/src/app/shims/onnxruntime-web-wasm.ts +0 -4
  56. package/src/assets/onnx/ort-wasm-simd-threaded.mjs +0 -59
  57. package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
  58. package/src/assets/vad/silero_vad_legacy.onnx +0 -0
  59. package/src/assets/vad/vad.worklet.bundle.min.js +0 -1
@@ -161,10 +161,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
161
161
  membersConversation = ['SYSTEM'];
162
162
  // ========== end:: typying =======
163
163
 
164
- // ========== begin:: stream audio ======= //
165
- public isStreamAudioActive = false;
166
- // ========== end:: stream audio ======= //
167
-
168
164
  @ViewChild(ConversationFooterComponent) conversationFooter: ConversationFooterComponent
169
165
  @ViewChild(ConversationContentComponent) conversationContent: ConversationContentComponent
170
166
  conversationHandlerService: ConversationHandlerService
@@ -250,8 +246,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
250
246
  'CONTINUE',
251
247
  'EMOJI_NOT_ELLOWED',
252
248
  'ATTACHMENT',
253
- 'EMOJI',
254
- 'CLOSE_CHAT'
249
+ 'EMOJI'
255
250
  ];
256
251
 
257
252
  const keysContent = [
@@ -506,7 +501,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
506
501
  return this.isConversationArchived;
507
502
  }
508
503
 
509
- // //FALLBACK TO TILEDESK
504
+ //FALLBACK TO TILEDESK
510
505
  const requests_list = await this.tiledeskRequestService.getMyRequests().catch(err => {
511
506
  this.logger.error('[CONV-COMP] getConversationDetail: error getting request from Tiledesk', err);
512
507
  this.isConversationArchived=true
@@ -524,9 +519,9 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
524
519
  return this.isConversationArchived
525
520
  }
526
521
 
527
- this.isConversationArchived = false;
528
- return null;
529
- }
522
+ this.isConversationArchived = true;
523
+ return null;
524
+ }
530
525
 
531
526
  /**
532
527
  * this.g.recipientId:
@@ -827,10 +822,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
827
822
  this.showThinkingMessage = false;
828
823
  }
829
824
 
830
- if (this.isStreamAudioActive && msg.sender !== this.senderId) {
831
- this.conversationFooter?.interruptStreamDueToPeerMessage();
832
- }
833
-
834
825
  that.newMessageAdded(msg);
835
826
  // Update badge based on the latest message received from the server.
836
827
  // We rely on `messages` being kept in-sync by the conversation handler.
@@ -886,20 +877,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
886
877
  this.subscriptions.push(subscribe);
887
878
  }
888
879
 
889
- subscribtionKey = 'conversationsAdded';
890
- subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
891
- if(!subscribtion){
892
-
893
- subscribtion = this.chatManager.conversationsHandlerService.conversationChanged.pipe(takeUntil(this.unsubscribe$)).subscribe((conversation) => {
894
- this.logger.debug('[CONV-COMP] ***** DATAIL conversationsChanged *****', conversation, this.conversationWith, this.isConversationArchived);
895
- if(conversation && conversation.recipient === this.conversationId){
896
- this.isConversationArchived = false
897
- }
898
- });
899
- const subscribe = {key: subscribtionKey, value: subscribtion };
900
- this.subscriptions.push(subscribe);
901
- }
902
-
903
880
  subscribtionKey = 'messageWait';
904
881
  subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
905
882
  if (!subscribtion) {
@@ -1406,25 +1383,8 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
1406
1383
  this.logger.debug('[CONV-COMP] floating onNewConversationButtonClicked')
1407
1384
  this.onNewConversationButtonClicked.emit()
1408
1385
  }
1409
-
1410
- /** CALLED BY: conv-footer streaming audio button */
1411
- onStreamAudioActiveChange(event: boolean){
1412
- this.isStreamAudioActive = event
1413
- }
1414
- /** CALLED BY: conv-footer component */
1415
- onCloseChatButtonClickedFN(event){
1416
- this.logger.debug('[CONV-COMP] onCloseChatButtonClicked::::', event)
1417
- this.onCloseChat()
1418
- }
1419
1386
  // =========== END: event emitter function ====== //
1420
1387
 
1421
- /**
1422
- * True quando è visibile il pulsante chiudi stream (`.close-stream-button`, `isStreamAudioActive`).
1423
- * Solo in quel caso il bottom del foglio include `--chat-footer-stream-button-height`.
1424
- */
1425
- closeStreamButtonActiveForSheetBottom(): boolean {
1426
- return !!(this.g?.showAudioStreamFooterButton && this.isStreamAudioActive);
1427
- }
1428
1388
 
1429
1389
  openInputFiles() {
1430
1390
  alert('ok');
@@ -22,7 +22,7 @@
22
22
  <div *ngFor="let message of messages; let first = first; let last = last; let i = index" tabindex="1521" class="rowMsg">
23
23
 
24
24
  <!-- message SENDER:: -->
25
- <div role="messaggio" *ngIf="messageType(MESSAGE_TYPE_MINE, message) && (!isStreamAudioActive && !message.isJustRecived)" class="msg_container base_sent">
25
+ <div role="messaggio" *ngIf="messageType(MESSAGE_TYPE_MINE, message)" class="msg_container base_sent">
26
26
 
27
27
  <!--backgroundColor non viene ancora usato -->
28
28
  <!-- class="messages msg_sent slide-in-right" -->
@@ -44,7 +44,7 @@
44
44
  top: 0;
45
45
  right: 0;
46
46
  left: 0;
47
- bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height));
47
+ bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height));
48
48
  overflow: hidden;
49
49
  .time{
50
50
  margin-bottom: 20px;
@@ -270,15 +270,6 @@
270
270
  }// end c21-body-container
271
271
  }// end c21-body
272
272
 
273
- /* Solo con pulsante chiudi stream (stream in ascolto): altezza extra come #streamAudioAlert */
274
- :host-context(#chat21-conversation-component.chat21-conversation--close-stream-active) .c21-body .c21-body-container .c21-body-content .chat21-sheet-content {
275
- bottom: calc(
276
- var(--chat-footer-logo-height) +
277
- var(--chat-footer-height) +
278
- var(--chat-footer-stream-button-height)
279
- );
280
- }
281
-
282
273
  @keyframes thinking-dot {
283
274
  0%, 80%, 100% {
284
275
  opacity: 0.2;
@@ -26,7 +26,6 @@ export class ConversationContentComponent implements OnInit {
26
26
  @Input() showThinkingMessage: boolean;
27
27
  @Input() lastServerSenderKind: 'bot' | 'human' | null;
28
28
  @Input() fullscreenMode: boolean;
29
- @Input() isStreamAudioActive: boolean;
30
29
  @Input() translationMap: Map< string, string>;
31
30
  @Input() stylesMap: Map<string, string>;
32
31
  @Output() onBeforeMessageRender = new EventEmitter();
@@ -12,164 +12,97 @@
12
12
  <div tabindex="-1" class="alertText">{{translationMap.get('EMOJI_NOT_ELLOWED')}}</div>
13
13
  </div>
14
14
 
15
- <!-- STREAM AUDIO: cerchio con onde animate -->
16
- <div id="streamAudioAlert" *ngIf="!hideTextAreaContent && isStreamAudioActive" class="fade-in-bottom stream-audio-alert" [class.hideTextReply]="hideTextReply" role="status" [attr.aria-label]="translationMap?.get('STREAM_AUDIO_LISTENING') || 'Stream audio attivo'">
17
- <div class="stream-audio-alert__orb" [ngStyle]="{ color: stylesMap?.get('themeColor') }">
18
- <svg class="stream-audio-alert__svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
19
- <circle cx="50" cy="50" r="46" fill="currentColor" opacity="0.14"/>
20
- <g class="stream-audio-alert__waves" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
21
- <g class="stream-audio-alert__wave-layer stream-audio-alert__wave-layer--1">
22
- <path [attr.d]="wavePath1"></path>
23
- </g>
24
-
25
- <g class="stream-audio-alert__wave-layer stream-audio-alert__wave-layer--2">
26
- <path [attr.d]="wavePath2"></path>
27
- </g>
28
-
29
- <g class="stream-audio-alert__wave-layer stream-audio-alert__wave-layer--3">
30
- <path [attr.d]="wavePath3"></path>
31
- </g>
32
- </g>
33
- </svg>
34
- </div>
35
- </div>
36
-
37
15
  </div>
38
16
 
39
- <div class="textarea-container-wrapper" *ngIf="!hideTextAreaContent && !hideTextReply">
40
- <!-- TEXTAREA + ICONS: conv active-->
41
- <div class="textarea-container">
42
-
43
- <div *ngIf="!isStopRec" class="icons-container">
44
- <!-- ICON ATTACHMENT -->
45
- <label *ngIf="showAttachmentFooterButton" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
46
- <span class="v-align-center">
47
- <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
48
- <path d="M9.9,22.7c0,0-.1,0-.2,0-1.9.3-3.7-.2-5.2-1.4-3-2.3-3.6-6.4-1.4-9.5L9.5,2.5c.4-.5,1.1-.6,1.6-.3.5.4.6,1.1.3,1.6l-6.5,9.4c-1.4,2-1,4.8.9,6.3,1,.8,2.2,1.1,3.5.9,1.3-.2,2.4-.9,3.1-1.9l6-8.7c.9-1.2.6-3-.6-3.9-.6-.5-1.4-.6-2.1-.5-.8.1-1.4.5-1.9,1.1l-5.8,8.2c-.3.5-.2,1.1.2,1.5.2.2.5.3.8.2.3,0,.6-.2.7-.4l4.7-6.2c.4-.5,1.1-.6,1.6-.2.5.4.6,1.1.2,1.6l-4.7,6.2c-.5.7-1.4,1.2-2.3,1.3-.9.1-1.8-.2-2.5-.7-1.4-1.1-1.6-3.1-.6-4.6l5.8-8.2c.8-1.1,2-1.9,3.4-2.1,1.4-.2,2.7.1,3.8,1,2.2,1.7,2.7,4.8,1.1,7.1l-6,8.7c-1.1,1.5-2.6,2.5-4.4,2.8h0Z"/>
49
- <title id="altIconTitle">{{ 'MAX_ATTACHMENT' | translate: { FILE_SIZE_LIMIT: file_size_limit } }}</title>
50
- </svg>
51
-
52
- </span>
53
- <input
54
- [attr.disabled] = "(isFilePendingToUpload || isConversationArchived || hideTextReply)? true : null"
55
- tabindex="1503"
56
- type="file"
57
- aria-label="seleziona allegato"
58
- [accept]="fileUploadAccept"
59
- name="chat21-file"
60
- id="chat21-file"
61
- #chat21_file
62
- class="inputfile"
63
- [ngStyle]="{'display': 'block', height:'1px', width:'1px', overflow: 'hidden' }"
64
- (change)="detectFiles($event)"/>
65
- </label>
66
- <!-- ICON EMOJII -->
67
- <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()">
68
- <span class="v-align-center">
69
- <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
70
- <path stroke-width=".4px" stroke="currentColor" d="M12,20.8c-5.1,0-9.3-4.2-9.3-9.3S6.9,2.2,12,2.2s9.3,4.2,9.3,9.3-4.2,9.3-9.3,9.3ZM12,3.6c-4.4,0-7.9,3.6-7.9,7.9s3.6,7.9,7.9,7.9,7.9-3.6,7.9-7.9-3.6-7.9-7.9-7.9Z"/>
71
- <path stroke-width=".4px" stroke="currentColor" d="M12,17.2c-2.7,0-4.3-1.9-4.6-2.3-.2-.3-.2-.7.1-1s.7-.2,1,.1c.1.2,1.4,1.8,3.5,1.8s2.2,0,3.5-1.8c.2-.3.7-.4,1-.1s.4.7.1,1c-1.7,2.2-4.1,2.3-4.6,2.3Z"/>
72
- <path d="M8.7,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
73
- <path d="M15.5,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
74
- <title id="altIconTitle">{{ translationMap?.get('EMOJI') }}</title>
75
-
76
- <!-- <path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
77
- <circle cx="15.02" cy="9.86" r="1.29"/>
78
- <circle cx="9.02" cy="9.86" r="1.29"/>
79
- <path d="M12.02,15.43c-1.27,0-2.36-.69-2.96-1.71h-1.43c.69,1.76,2.39,3,4.39,3s3.7-1.24,4.39-3h-1.43c-.6,1.02-1.69,1.71-2.96,1.71Zm0-12C7.28,3.43,3.45,7.27,3.45,12s3.83,8.57,8.56,8.57,8.58-3.84,8.58-8.57S16.75,3.43,12.01,3.43Zm0,15.43c-3.79,0-6.86-3.07-6.86-6.86s3.07-6.86,6.86-6.86,6.86,3.07,6.86,6.86-3.07,6.86-6.86,6.86Z"/> -->
80
- </svg>
81
- </span>
82
- </label>
83
- </div>
84
-
85
-
86
-
87
-
88
- <div *ngIf="!isStopRec" class="visible-text-area" [class.hasError]="showAlertEmoji" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
89
- <!-- isFilePendingToUpload || -->
90
- <textarea
91
- [attr.disabled] = "(hideTextReply)? true : null"
92
- [attr.placeholder] ="(footerMessagePlaceholder)? footerMessagePlaceholder : translationMap?.get('LABEL_PLACEHOLDER')"
93
- start-focus-chat21-conversation-component
94
- inputTextArea
95
- #textbox
96
- tabindex="1501"
97
- aria-labelledby="altTextArea"
98
- rows="1"
99
- id="chat21-main-message-context"
100
- class='f21textarea c21-button-clean'
101
- [(ngModel)]="textInputTextArea"
102
- (ngModelChange)="onTextAreaChange()"
103
- (keypress)="onkeypress($event)"
104
- (keydown)="onkeydown($event)"
105
- (paste)="onPaste($event)">
106
- </textarea>
107
-
108
- </div>
109
-
110
- <!-- ICON SEND -->
111
- <div *ngIf="(textInputTextArea !== '' && !isStopRec) || !showAudioRecorderFooterButton" tabindex="-1" class="chat21-textarea-button" [class.disabled]="showAlertEmoji" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
17
+ <!-- TEXTAREA + ICONS: conv active-->
18
+ <div class="textarea-container" *ngIf="!hideTextAreaContent && !hideTextReply">
19
+
20
+ <div *ngIf="!isStopRec" class="icons-container">
21
+ <!-- ICON ATTACHMENT -->
22
+ <label *ngIf="showAttachmentFooterButton" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
112
23
  <span class="v-align-center">
113
- <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" fill="currentColor">
114
- <path d="M1.8,20.6V3.4l20.2,8.6L1.8,20.6ZM3.9,17.3l12.6-5.4L3.9,6.6v3.7l6.4,1.6-6.4,1.6v3.8ZM3.9,17.3V6.6v10.7Z"/>
115
- </svg>
116
- </span>
117
- </div>
118
-
119
- <!-- ICON REC -->
120
- <div *ngIf="showAudioRecorderFooterButton && !textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
121
- <chat-audio-recorder
122
- (startRecordingEvent)="onStartRecording()"
123
- (deleteRecordingEvent)="onDeleteRecording()"
124
- (endRecordingEvent)="onEndRecording($event)"
125
- (sendRecordingEvent)="onSendRecording($event)"
126
- [stylesMap]="stylesMap">
127
- </chat-audio-recorder>
128
- </div>
129
-
130
- <!-- ICON STREAM / CHIUDI STREAM (cerchio, icone bianche su iconColor) -->
131
- <div *ngIf="showAudioStreamFooterButton" tabindex="-1" id="chat21-button-stream"
132
- class="chat21-textarea-button chat21-stream-button" [class.active]="isStreamAudioActive || (!textInputTextArea && !hideTextReply)"
133
- (click)="onStreamPressed($event)" [attr.aria-label]="isStreamAudioActive ? (translationMap?.get('CLOSE') || 'Chiudi stream') : (translationMap?.get('STREAM_AUDIO') || 'Stream audio')"
134
- [ngStyle]="{ 'background-color': stylesMap?.get('iconColor') || stylesMap?.get('themeColor') }">
135
- <span class="v-align-center chat21-stream-button__icon" *ngIf="!isStreamAudioActive">
136
- <svg role="img" xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 30 30" fill="#ffffff" aria-hidden="true" preserveAspectRatio="xMidYMid meet">
137
- <path class="s0" d="m5.21 7.41c-1.21 0-2.21 0.99-2.21 2.21v8.14c0 1.21 0.99 2.21 2.21 2.21 1.22 0 2.21-0.99 2.21-2.21v-8.14c0-1.21-0.99-2.21-2.21-2.21z"/>
138
- <path class="s0" d="m11.64 3.01c-1.22 0-2.21 0.99-2.21 2.2v16.94c0 1.21 0.99 2.2 2.21 2.2 1.22 0 2.21-0.98 2.21-2.2v-16.94c0-1.21-0.99-2.21-2.21-2.21z"/>
139
- <path class="s0" d="m15.86 9.25v8.88c0 1.21 0.99 2.21 2.21 2.21 1.22 0 2.21-0.99 2.21-2.21v-8.88c0-1.22-0.99-2.21-2.21-2.21-1.22 0-2.21 0.99-2.21 2.21z"/>
140
- <path class="s0" d="m24.5 8.97c-1.22 0-2.21 0.99-2.21 2.21v5.02c0 1.22 0.99 2.21 2.21 2.21 1.22 0 2.21-0.99 2.21-2.21v-5.02c0-1.21-0.99-2.21-2.21-2.21z"/>
24
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
25
+ <path d="M9.9,22.7c0,0-.1,0-.2,0-1.9.3-3.7-.2-5.2-1.4-3-2.3-3.6-6.4-1.4-9.5L9.5,2.5c.4-.5,1.1-.6,1.6-.3.5.4.6,1.1.3,1.6l-6.5,9.4c-1.4,2-1,4.8.9,6.3,1,.8,2.2,1.1,3.5.9,1.3-.2,2.4-.9,3.1-1.9l6-8.7c.9-1.2.6-3-.6-3.9-.6-.5-1.4-.6-2.1-.5-.8.1-1.4.5-1.9,1.1l-5.8,8.2c-.3.5-.2,1.1.2,1.5.2.2.5.3.8.2.3,0,.6-.2.7-.4l4.7-6.2c.4-.5,1.1-.6,1.6-.2.5.4.6,1.1.2,1.6l-4.7,6.2c-.5.7-1.4,1.2-2.3,1.3-.9.1-1.8-.2-2.5-.7-1.4-1.1-1.6-3.1-.6-4.6l5.8-8.2c.8-1.1,2-1.9,3.4-2.1,1.4-.2,2.7.1,3.8,1,2.2,1.7,2.7,4.8,1.1,7.1l-6,8.7c-1.1,1.5-2.6,2.5-4.4,2.8h0Z"/>
26
+ <title id="altIconTitle">{{ 'MAX_ATTACHMENT' | translate: { FILE_SIZE_LIMIT: file_size_limit } }}</title>
141
27
  </svg>
28
+
142
29
  </span>
143
- <span class="v-align-center chat21-stream-button__icon" *ngIf="isStreamAudioActive">
144
- <svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#ffffff" aria-hidden="true">
145
- <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>
30
+ <input
31
+ [attr.disabled] = "(isFilePendingToUpload || isConversationArchived || hideTextReply)? true : null"
32
+ tabindex="1503"
33
+ type="file"
34
+ aria-label="seleziona allegato"
35
+ [accept]="fileUploadAccept"
36
+ name="chat21-file"
37
+ id="chat21-file"
38
+ #chat21_file
39
+ class="inputfile"
40
+ [ngStyle]="{'display': 'block', height:'1px', width:'1px', overflow: 'hidden' }"
41
+ (change)="detectFiles($event)"/>
42
+ </label>
43
+ <!-- ICON EMOJII -->
44
+ <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()">
45
+ <span class="v-align-center">
46
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
47
+ <path stroke-width=".4px" stroke="currentColor" d="M12,20.8c-5.1,0-9.3-4.2-9.3-9.3S6.9,2.2,12,2.2s9.3,4.2,9.3,9.3-4.2,9.3-9.3,9.3ZM12,3.6c-4.4,0-7.9,3.6-7.9,7.9s3.6,7.9,7.9,7.9,7.9-3.6,7.9-7.9-3.6-7.9-7.9-7.9Z"/>
48
+ <path stroke-width=".4px" stroke="currentColor" d="M12,17.2c-2.7,0-4.3-1.9-4.6-2.3-.2-.3-.2-.7.1-1s.7-.2,1,.1c.1.2,1.4,1.8,3.5,1.8s2.2,0,3.5-1.8c.2-.3.7-.4,1-.1s.4.7.1,1c-1.7,2.2-4.1,2.3-4.6,2.3Z"/>
49
+ <path d="M8.7,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
50
+ <path d="M15.5,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
51
+ <title id="altIconTitle">{{ translationMap?.get('EMOJI') }}</title>
52
+
53
+ <!-- <path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
54
+ <circle cx="15.02" cy="9.86" r="1.29"/>
55
+ <circle cx="9.02" cy="9.86" r="1.29"/>
56
+ <path d="M12.02,15.43c-1.27,0-2.36-.69-2.96-1.71h-1.43c.69,1.76,2.39,3,4.39,3s3.7-1.24,4.39-3h-1.43c-.6,1.02-1.69,1.71-2.96,1.71Zm0-12C7.28,3.43,3.45,7.27,3.45,12s3.83,8.57,8.56,8.57,8.58-3.84,8.58-8.57S16.75,3.43,12.01,3.43Zm0,15.43c-3.79,0-6.86-3.07-6.86-6.86s3.07-6.86,6.86-6.86,6.86,3.07,6.86,6.86-3.07,6.86-6.86,6.86Z"/> -->
146
57
  </svg>
147
58
  </span>
148
- </div>
59
+ </label>
149
60
  </div>
150
61
 
151
62
 
152
- <div class="close-chat-container" *ngIf="closeChatInConversation">
153
- <button tabindex="1040" aflistconv #aflistconv class="c21-button-primary c21-close" (click)="onCloseChat($event)" [ngStyle]="{'background-color': stylesMap.get('themeColor'), 'border-color': stylesMap.get('themeColor'), 'color': stylesMap?.get('foregroundColor')}">
154
- <span class="v-align-center">
155
- <!-- <svg [ngStyle]="{'fill': 'yellow' }" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
156
- <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" [ngStyle]="{'fill': stylesMap?.get('foregroundColor')}"/>
157
- </svg> -->
158
- <svg [ngStyle]="{'stroke': stylesMap?.get('foregroundColor'), 'fill': stylesMap?.get('foregroundColor') }" role="img" id="archive" aria-labelledby="altIconTitle" class="icon-menu" xmlns="http://www.w3.org/2000/svg"
159
- width="15px" height="15px" viewBox="0 0 512 512">
160
- <path d="M80 152v256a40.12 40.12 0 0040 40h272a40.12 40.12 0 0040-40V152" stroke-linecap="round" stroke-linejoin="round" stroke-width="50px" fill="none"></path>
161
- <rect x="48" y="64" width="416" height="80" rx="28" ry="28" stroke-linejoin="round" stroke-width="50px" fill="none" ></rect>
162
- <path stroke-linecap="round" stroke-linejoin="round" d="M320 304l-64 64-64-64M256 345.89V224" stroke-width="50px" fill="none"></path>
163
- <title id="altIconTitle">{{ translationMap?.get('CLOSE_CHAT') }}</title>
164
- </svg>
165
- </span>
166
- <span class="v-align-center c21-label-button">
167
- {{translationMap?.get('CLOSE_CHAT')}}
168
- </span>
169
- <div class="clear"></div>
170
- </button>
63
+
64
+
65
+ <div *ngIf="!isStopRec" class="visible-text-area" [class.hasError]="showAlertEmoji" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
66
+ <!-- isFilePendingToUpload || -->
67
+ <textarea
68
+ [attr.disabled] = "(hideTextReply)? true : null"
69
+ [attr.placeholder] ="(footerMessagePlaceholder)? footerMessagePlaceholder : translationMap?.get('LABEL_PLACEHOLDER')"
70
+ start-focus-chat21-conversation-component
71
+ inputTextArea
72
+ #textbox
73
+ tabindex="1501"
74
+ aria-labelledby="altTextArea"
75
+ rows="1"
76
+ id="chat21-main-message-context"
77
+ class='f21textarea c21-button-clean'
78
+ [(ngModel)]="textInputTextArea"
79
+ (ngModelChange)="onTextAreaChange()"
80
+ (keypress)="onkeypress($event)"
81
+ (keydown)="onkeydown($event)"
82
+ (paste)="onPaste($event)">
83
+ </textarea>
84
+
171
85
  </div>
172
86
 
87
+ <!-- ICON SEND -->
88
+ <div *ngIf="(textInputTextArea !== '' && !isStopRec) || !showAudioRecorderFooterButton" tabindex="-1" class="chat21-textarea-button" [class.disabled]="showAlertEmoji" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
89
+ <span class="v-align-center">
90
+ <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" fill="currentColor">
91
+ <path d="M1.8,20.6V3.4l20.2,8.6L1.8,20.6ZM3.9,17.3l12.6-5.4L3.9,6.6v3.7l6.4,1.6-6.4,1.6v3.8ZM3.9,17.3V6.6v10.7Z"/>
92
+ </svg>
93
+ </span>
94
+ </div>
95
+
96
+ <!-- ICON REC -->
97
+ <div *ngIf="showAudioRecorderFooterButton && !textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
98
+ <chat-audio-recorder
99
+ (startRecordingEvent)="onStartRecording()"
100
+ (deleteRecordingEvent)="onDeleteRecording()"
101
+ (endRecordingEvent)="onEndRecording($event)"
102
+ (sendRecordingEvent)="onSendRecording($event)"
103
+ [stylesMap]="stylesMap">
104
+ </chat-audio-recorder>
105
+ </div>
173
106
  </div>
174
107
 
175
108
 
@@ -1,25 +1,23 @@
1
- .textarea-container-wrapper{
2
- display: flex;
3
- flex-direction: column;
4
- gap: 8px;
5
- }
1
+
6
2
  .textarea-container{
3
+ // padding: 8px 34px;
4
+ // padding-left: 70px;
5
+ // padding-right: 45px;
7
6
  display: flex;
7
+ // width: 100%;
8
8
  align-items: center;
9
9
  justify-content: space-between;
10
10
  gap: 8px;
11
- }
12
- .close-chat-container{
13
- display: flex;
14
- flex-direction: column;
15
- align-items: center;
16
- justify-content: center;
17
- gap: 8px;
18
11
 
19
- .c21-close{
20
- height: 30px !important;
21
- margin: 0px !important;
12
+ //if attachment icon OR emoji icon is not in DOM -> increment textarea width
13
+ &:has(:not(#chat21-start-upload-doc), :not(#chat21-emoticon-picker)) .visible-text-area {
14
+ width: 80%;
22
15
  }
16
+ //if attachment icon AND emoji icon is not in DOM -> increment textarea width
17
+ &:has(:not(#chat21-start-upload-doc)):has(:not(#chat21-emoticon-picker)) .visible-text-area {
18
+ width: 90%;
19
+ }
20
+
23
21
  }
24
22
 
25
23
  .icons-container{
@@ -84,30 +82,6 @@
84
82
  border-radius: 50%;
85
83
  }
86
84
 
87
- /** Stream audio: cerchio pieno, glyph bianco su sfondo iconColor (stylesMap) */
88
- .chat21-stream-button.chat21-textarea-button {
89
- width: 36px;
90
- height: 36px;
91
- min-width: 36px;
92
- border-radius: 50%;
93
- box-sizing: border-box;
94
- flex-shrink: 0;
95
- color: #ffffff;
96
-
97
- .chat21-stream-button__icon svg {
98
- width: 20px;
99
- height: 20px;
100
- path {
101
- fill: #ffffff;
102
- }
103
- }
104
-
105
- &.chat21-textarea-button span svg:hover {
106
- background: rgba(255, 255, 255, 0.2) !important;
107
- border-radius: 50%;
108
- }
109
- }
110
-
111
85
  textarea,
112
86
  textarea:visited,
113
87
  textarea:focus,
@@ -390,82 +364,6 @@ textarea:active{
390
364
  }
391
365
  }
392
366
 
393
- #streamAudioAlert {
394
- bottom: 100%;
395
- width: 100%;
396
- min-height: var(--chat-footer-stream-button-height);
397
- display: flex;
398
- align-items: center;
399
- justify-content: center;
400
- position: absolute;
401
- padding: var(--chat-footer-stream-button-padding);
402
- /* Satinato / vetro: più trasparenza, blur più marcato */
403
- background-color: color-mix(in srgb, var(--content-background-color) 34%, transparent);
404
- backdrop-filter: blur(20px) saturate(1.2);
405
- -webkit-backdrop-filter: blur(20px) saturate(1.2);
406
- box-shadow:
407
- inset 0 1px 0 rgba(255, 255, 255, 0.28),
408
- 0 1px 0 rgba(0, 0, 0, 0.05);
409
-
410
- &.hideTextReply {
411
- position: unset;
412
- min-height: auto;
413
- padding: 16px 0;
414
- box-shadow: none;
415
- backdrop-filter: none;
416
- -webkit-backdrop-filter: none;
417
- background-color: var(--content-background-color);
418
- }
419
- }
420
-
421
- .stream-audio-alert__orb {
422
- display: flex;
423
- align-items: center;
424
- justify-content: center;
425
- width: 88px;
426
- height: 88px;
427
- border-radius: 50%;
428
- border: 2px solid currentColor;
429
- background: var(--content-background-color);
430
- box-shadow: inset 0 0 24px rgba(0, 0, 0, 0.04);
431
- }
432
-
433
- .stream-audio-alert__svg {
434
- width: 72px;
435
- height: 72px;
436
- display: block;
437
- }
438
-
439
- .stream-audio-alert__wave-layer {
440
- transform-origin: 50px 50px;
441
- transform-box: fill-box;
442
- animation: stream-wave-float 1.35s ease-in-out infinite;
443
- }
444
-
445
- .stream-audio-alert__wave-layer--1 {
446
- animation-delay: 0s;
447
- }
448
-
449
- .stream-audio-alert__wave-layer--2 {
450
- animation-delay: 0.18s;
451
- }
452
-
453
- .stream-audio-alert__wave-layer--3 {
454
- animation-delay: 0.36s;
455
- }
456
-
457
- @keyframes stream-wave-float {
458
- 0%,
459
- 100% {
460
- transform: translateY(0);
461
- opacity: 0.85;
462
- }
463
- 50% {
464
- transform: translateY(-6px);
465
- opacity: 1;
466
- }
467
- }
468
-
469
367
  #textAlert{
470
368
  bottom: 100%;
471
369
  width: 100%;
@@ -521,28 +419,3 @@ textarea:active{
521
419
  border: none;
522
420
  // margin: -2px -2px 0px;
523
421
  }
524
-
525
-
526
- // aggiungi un'animazione di fade in e fade out quando .star-rating-widget è visibile con transition
527
- .star-rating-widget {
528
- transition: all 0.5s ease-in-out;
529
- }
530
-
531
- .star-rating-widget {
532
- position: absolute;
533
- left: 0;
534
- right: 0;
535
- bottom: -52px;
536
- height: 100%;
537
- width: 100%;
538
- flex-direction: row;
539
- justify-content: center;
540
- background-color: rgb(255, 255, 255);
541
- flex-wrap: nowrap;
542
- &.active {
543
- bottom: 0px;
544
- }
545
- &.inactive {
546
- bottom: -52px;
547
- }
548
- }