@chat21/chat21-web-widget 5.1.6 → 5.1.7-rc7

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 (34) hide show
  1. package/.github/workflows/docker-community-push-latest.yml +23 -13
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
  3. package/CHANGELOG.md +26 -0
  4. package/Dockerfile +4 -5
  5. package/angular.json +2 -1
  6. package/package.json +1 -1
  7. package/src/app/app.component.ts +0 -6
  8. package/src/app/component/conversation-detail/conversation/conversation.component.scss +1 -1
  9. package/src/app/component/conversation-detail/conversation/conversation.component.ts +33 -5
  10. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -0
  11. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +16 -2
  12. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +25 -0
  13. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +43 -1
  14. package/src/app/component/message/buttons/action-button/action-button.component.scss +6 -6
  15. package/src/app/component/message/buttons/action-button/action-button.component.ts +1 -1
  16. package/src/app/component/message/buttons/link-button/link-button.component.scss +5 -5
  17. package/src/app/component/message/buttons/link-button/link-button.component.ts +2 -2
  18. package/src/app/component/message/buttons/text-button/text-button.component.scss +9 -12
  19. package/src/app/component/message/buttons/text-button/text-button.component.ts +4 -4
  20. package/src/app/component/message-attachment/message-attachment.component.html +3 -7
  21. package/src/app/component/network-offline/network-offline.component.html +1 -1
  22. package/src/app/component/network-offline/network-offline.component.ts +3 -2
  23. package/src/app/providers/translator.service.ts +8 -2
  24. package/src/app/sass/_variables.scss +1 -1
  25. package/src/app/utils/utils.ts +8 -10
  26. package/src/assets/i18n/en.json +4 -1
  27. package/src/assets/i18n/es.json +6 -1
  28. package/src/assets/i18n/fr.json +6 -1
  29. package/src/assets/i18n/it.json +6 -3
  30. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +2 -2
  31. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +22 -11
  32. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  33. package/src/chat21-core/utils/utils.ts +15 -4
  34. package/src/iframe-style.css +1 -1
@@ -1,10 +1,10 @@
1
1
  name: Docker Image Community latest CI
2
2
 
3
- on:
4
- push:
3
+ on:
4
+ push:
5
5
  branches: [ master ]
6
- pull_request:
7
- branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
8
 
9
9
  jobs:
10
10
  push_to_registry:
@@ -12,12 +12,22 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@v2
16
- name: Check out the repo
17
- - uses: docker/build-push-action@v1
18
- with:
19
- username: ${{ secrets.DOCKERHUB_USERNAME }}
20
- password: ${{ secrets.DOCKERHUB_TOKEN }}
21
- repository: chat21/chat21-web-widget
22
- push: true
23
- tags: latest
15
+ - name: Check out the repo
16
+ uses: actions/checkout@v2
17
+
18
+ - name: Set up Docker Buildx
19
+ uses: docker/setup-buildx-action@v2
20
+
21
+ - name: Log in to Docker Hub
22
+ uses: docker/login-action@v2
23
+ with:
24
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
25
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
26
+
27
+ - name: Build and push multiarch Docker image
28
+ uses: docker/build-push-action@v3
29
+ with:
30
+ context: .
31
+ push: true
32
+ platforms: linux/amd64,linux/arm64
33
+ tags: chat21/chat21-web-widget:latest
@@ -3,20 +3,30 @@ name: Publish Docker Community image tags
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - '**' # Push events to every tag including hierarchical tags like
7
- jobs:
6
+ - '**' # Trigger su qualsiasi tag
8
7
 
8
+ jobs:
9
9
  push_to_registry:
10
10
  name: Push Docker image to Docker Hub
11
11
  runs-on: ubuntu-latest
12
+
12
13
  steps:
13
- - name: Check out the repo
14
- uses: actions/checkout@v2
15
- - name: Push to Docker Hub
16
- uses: docker/build-push-action@v1
17
- with:
18
- username: ${{ secrets.DOCKERHUB_USERNAME }}
19
- password: ${{ secrets.DOCKERHUB_TOKEN }}
20
- repository: chat21/chat21-web-widget
21
- push: true
22
- tag_with_ref: true
14
+ - name: Check out the repo
15
+ uses: actions/checkout@v2
16
+
17
+ - name: Set up Docker Buildx
18
+ uses: docker/setup-buildx-action@v2
19
+
20
+ - name: Log in to Docker Hub
21
+ uses: docker/login-action@v2
22
+ with:
23
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
24
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
25
+
26
+ - name: Build and push multiarch Docker image
27
+ uses: docker/build-push-action@v3
28
+ with:
29
+ context: .
30
+ push: true
31
+ platforms: linux/amd64,linux/arm64
32
+ tags: chat21/chat21-web-widget:${{ github.ref_name }}
package/CHANGELOG.md CHANGED
@@ -6,6 +6,32 @@
6
6
  ### **Copyrigth**:
7
7
  *Tiledesk SRL*
8
8
 
9
+ # 5.1.7-rc7
10
+ - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
11
+
12
+ # 5.1.7-rc6
13
+ - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
14
+
15
+ # 5.1.7-rc5
16
+ - **bug-fixed**: bug fixed BUTTON STYLES
17
+
18
+ # 5.1.7-rc4
19
+ - **bug-fixed**: bug fixed widget fullscreen style
20
+
21
+ # 5.1.7-rc3
22
+ - **changed**: replace extractUrls
23
+
24
+ # 5.1.7-rc2
25
+ - **bug-fixed**: translations completed
26
+ - **changed**: set wait to 0 if messages have already been read
27
+
28
+ # 5.1.7-rc1
29
+ - **changed**: replace fullname with firstname
30
+ - **added**: added tooltip on attachment an emoji
31
+ - **bug-fixed**: bug fixed button color
32
+ - **bug-fixed**: bug fixed min-height message-receive
33
+ - **bug-fixed**: bug-fixed css footer
34
+
9
35
  # 5.1.6
10
36
 
11
37
  # 5.1.5
package/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ### STAGE 1: Build ###
2
2
 
3
3
  # We label our stage as ‘builder’
4
- FROM node:20.12.2-alpine3.19 as builder
4
+ FROM --platform=$BUILDPLATFORM node:20.12.2-alpine3.19 as builder
5
5
 
6
6
  COPY package.json package-lock.json ./
7
7
 
@@ -15,12 +15,11 @@ COPY . .
15
15
 
16
16
  ## Build the angular app in production mode and store the artifacts in dist folder
17
17
 
18
- RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
19
18
 
19
+ RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
20
20
 
21
21
  ### STAGE 2: Setup ###
22
-
23
- FROM nginx:1.14.1-alpine
22
+ FROM --platform=$BUILDPLATFORM nginx:1.14.1-alpine
24
23
 
25
24
  ## Copy our default nginx config
26
25
  COPY nginx.conf /etc/nginx/nginx.conf
@@ -33,4 +32,4 @@ COPY --from=builder /ng-app/dist/browser /usr/share/nginx/html
33
32
 
34
33
  RUN echo "Chat21 Web Widget Started!!"
35
34
 
36
- CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
35
+ CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
package/angular.json CHANGED
@@ -44,7 +44,8 @@
44
44
  "src/environments/real_data/widget-config-docker.json",
45
45
  "src/environments/real_data/widget-config-native-mqtt.json",
46
46
  "src/environments/real_data/widget-config-native-prod.json",
47
- "src/environments/real_data/widget-config-aws-stage.json"
47
+ "src/environments/real_data/widget-config-aws-stage.json",
48
+ "src/environments/real_data/widget-config-aws-aruba.json"
48
49
  ],
49
50
  "styles": [
50
51
  "src/app/sass/styles.scss"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-web-widget",
3
3
  "author": "Tiledesk SRL",
4
- "version": "5.1.6",
4
+ "version": "5.1.7-rc7",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -2189,12 +2189,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
2189
2189
  this.el.nativeElement.style.setProperty('--chat-header-height', this.g.hideHeaderConversation? '0px': null)
2190
2190
  this.el.nativeElement.style.setProperty('--font-size-bubble-message', this.g.fontSize)
2191
2191
  this.el.nativeElement.style.setProperty('--font-family-bubble-message', this.g.fontFamily)
2192
-
2193
-
2194
- this.styleMapConversation.set('buttonBackgroundColor', this.g.bubbleReceivedBackground)
2195
- this.styleMapConversation.set('buttonTextColor', this.g.bubbleReceivedTextColor)
2196
- this.styleMapConversation.set('buttonHoverBackgroundColor',this.g.bubbleSentBackground)
2197
- this.styleMapConversation.set('buttonHoverTextColor', this.g.bubbleSentTextColor)
2198
2192
 
2199
2193
  }
2200
2194
 
@@ -89,7 +89,7 @@
89
89
  left: 0px;
90
90
  right: 0px;
91
91
  margin: 0px;
92
- padding: 12px;
92
+ padding: 0 12px 12px 12px;
93
93
  // box-shadow: 0 -1px 0px 0px $trasp-light-gray;
94
94
  background: white;
95
95
  min-height: 40px;
@@ -234,7 +234,10 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
234
234
  'LABEL_START_NW_CONV',
235
235
  'CONTINUE',
236
236
  'EMOJI_NOT_ELLOWED',
237
- 'DOMAIN_NOT_ALLOWED'
237
+ 'DOMAIN_NOT_ALLOWED',
238
+ 'MAX_ATTACHMENT',
239
+ 'MAX_ATTACHMENT_ERROR',
240
+ 'EMOJI'
238
241
  ];
239
242
 
240
243
  const keysContent = [
@@ -456,12 +459,13 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
456
459
  return this.isConversationArchived;
457
460
  }
458
461
 
459
- //FALLBACK TO TILEDESK
462
+ // //FALLBACK TO TILEDESK
460
463
  const requests_list = await this.tiledeskRequestService.getMyRequests().catch(err => {
461
464
  this.logger.error('[CONV-COMP] getConversationDetail: error getting request from Tiledesk', err);
462
465
  this.isConversationArchived=true
463
466
  return { requests: [] }
464
467
  });
468
+ console.log('requesttttttt', requests_list)
465
469
  if (requests_list && requests_list.requests.length > 0) {
466
470
  this.logger.debug('[CONV-COMP] getConversationDetail: request exist on Tiledesk', requests_list);
467
471
  let conversation = requests_list.requests.find((request)=> request.request_id === this.conversationId)
@@ -474,9 +478,9 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
474
478
  return this.isConversationArchived
475
479
  }
476
480
 
477
- this.isConversationArchived = true;
478
- return null;
479
- }
481
+ this.isConversationArchived = false;
482
+ return null;
483
+ }
480
484
 
481
485
  /**
482
486
  * this.g.recipientId:
@@ -826,6 +830,30 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
826
830
  this.subscriptions.push(subscribe);
827
831
  }
828
832
 
833
+ subscribtionKey = 'conversationsAdded';
834
+ subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
835
+ if(!subscribtion){
836
+
837
+ subscribtion = this.chatManager.conversationsHandlerService.conversationChanged.pipe(takeUntil(this.unsubscribe$)).subscribe((conversation) => {
838
+ this.logger.debug('[CONV-COMP] ***** DATAIL conversationsChanged *****', conversation, this.conversationWith, this.isConversationArchived);
839
+ // if(conversation && conversation.recipient === this.g.senderId && isUserBanned(conversation)){
840
+ // return;
841
+ // }
842
+ // if(conversation && conversation.sender !== this.senderId){
843
+ // const checkContentScrollPosition = that.conversationContent.checkContentScrollPosition();
844
+ // if(checkContentScrollPosition && conversation.is_new){ //update conversation if scroolToBottom is to the end
845
+ // this.logger.debug('[CONV-COMP] updateConversationBadge...')
846
+ // that.updateConversationBadge();
847
+ // }
848
+ // }
849
+ if(conversation && conversation.recipient === this.conversationId){
850
+ this.isConversationArchived = false
851
+ }
852
+ });
853
+ const subscribe = {key: subscribtionKey, value: subscribtion };
854
+ this.subscriptions.push(subscribe);
855
+ }
856
+
829
857
  subscribtionKey = 'messageWait';
830
858
  subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
831
859
  if (!subscribtion) {
@@ -223,6 +223,7 @@
223
223
  .msg_receive {
224
224
  background-color: var(--light-white);
225
225
  color: var(--black);
226
+ min-height: 38px;
226
227
  // max-width: 260px;
227
228
  max-width: calc(100% - 70px);
228
229
  min-width: 14px;
@@ -27,9 +27,11 @@
27
27
  <!-- ICON ATTACHMENT -->
28
28
  <label *ngIf="showAttachmentFooterButton" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
29
29
  <span class="v-align-center">
30
- <svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
30
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
31
31
  <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"/>
32
+ <title id="altIconTitle">{{ attachmentTooltip || translationMap?.get('MAX_ATTACHMENT') }}</title>
32
33
  </svg>
34
+
33
35
  </span>
34
36
  <input
35
37
  [attr.disabled] = "(isFilePendingToUpload || isConversationArchived || hideTextReply)? true : null"
@@ -47,11 +49,12 @@
47
49
  <!-- ICON EMOJII -->
48
50
  <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()">
49
51
  <span class="v-align-center">
50
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
52
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
51
53
  <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"/>
52
54
  <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"/>
53
55
  <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"/>
54
56
  <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"/>
57
+ <title id="altIconTitle">{{ translationMap?.get('EMOJI') }}</title>
55
58
 
56
59
  <!-- <path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
57
60
  <circle cx="15.02" cy="9.86" r="1.29"/>
@@ -146,3 +149,14 @@
146
149
  <div class="clear"></div>
147
150
  </button> -->
148
151
  </div>
152
+
153
+
154
+ <!--
155
+ ****************************************
156
+ ******* MODALE OFFLINE NETWORK *********
157
+ ****************************************
158
+ -->
159
+
160
+ <div class="star-rating-widget" [class.active]="isErrorNetwork" [class.inactive]="!isErrorNetwork">
161
+ <chat-network-offline [keyErrorMessage]="'MAX_ATTACHMENT_ERROR'"></chat-network-offline>
162
+ </div>
@@ -418,3 +418,28 @@ textarea:active{
418
418
  border: none;
419
419
  // margin: -2px -2px 0px;
420
420
  }
421
+
422
+
423
+ // aggiungi un'animazione di fade in e fade out quando .star-rating-widget è visibile con transition
424
+ .star-rating-widget {
425
+ transition: all 0.5s ease-in-out;
426
+ }
427
+
428
+ .star-rating-widget {
429
+ position: absolute;
430
+ left: 0;
431
+ right: 0;
432
+ bottom: -52px;
433
+ height: 100%;
434
+ width: 100%;
435
+ flex-direction: row;
436
+ justify-content: center;
437
+ background-color: rgb(255, 255, 255);
438
+ flex-wrap: nowrap;
439
+ &.active {
440
+ bottom: 0px;
441
+ }
442
+ &.inactive {
443
+ bottom: -52px;
444
+ }
445
+ }
@@ -84,6 +84,10 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
84
84
  showAlertEmoji: boolean = false
85
85
  showAlertUrl: boolean = false;
86
86
 
87
+ file_size_limit: number = 10;
88
+ attachmentTooltip: string = '';
89
+ isErrorNetwork: boolean = false;
90
+
87
91
  convertColorToRGBA = convertColorToRGBA;
88
92
  private logger: LoggerService = LoggerInstance.getInstance()
89
93
  constructor(private chatManager: ChatManager,
@@ -91,8 +95,10 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
91
95
  private uploadService: UploadService) { }
92
96
 
93
97
  ngOnInit() {
98
+ this.updateAttachmentTooltip();
94
99
  }
95
100
 
101
+
96
102
  ngOnChanges(changes: SimpleChanges){
97
103
  if(changes['conversationWith'] && changes['conversationWith'].currentValue !== undefined){
98
104
  this.conversationHandlerService = this.chatManager.getConversationHandlerByConversationId(this.conversationWith);
@@ -105,6 +111,10 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
105
111
  this.onDrop(this.dropEvent)
106
112
  }
107
113
 
114
+ if(changes['translationMap'] && changes['translationMap'].currentValue !== undefined){
115
+ this.updateAttachmentTooltip();
116
+ }
117
+
108
118
  }
109
119
 
110
120
  ngAfterViewInit() {
@@ -112,6 +122,23 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
112
122
  // setTimeout(() => {
113
123
  this.showEmojiPicker = true
114
124
  // }, 500);
125
+ this.updateAttachmentTooltip();
126
+ }
127
+
128
+
129
+ updateAttachmentTooltip() {
130
+ // Use setTimeout to wait for the async translation map to be populated
131
+ setTimeout(() => {
132
+ this.logger.log('[CONV-FOOTER] updateAttachmentTooltip - translationMap:', this.translationMap);
133
+ if (this.translationMap && this.translationMap.has('MAX_ATTACHMENT')) {
134
+ const template = this.translationMap.get('MAX_ATTACHMENT');
135
+ this.logger.log('[CONV-FOOTER] MAX_ATTACHMENT template:', template);
136
+ this.attachmentTooltip = template.replace('{{file_size_limit}}', this.file_size_limit.toString());
137
+ this.logger.log('[CONV-FOOTER] attachmentTooltip:', this.attachmentTooltip);
138
+ } else {
139
+ this.logger.log('[CONV-FOOTER] MAX_ATTACHMENT not found in translationMap');
140
+ }
141
+ }, 0);
115
142
  }
116
143
 
117
144
  // ========= begin:: functions send image ======= //
@@ -202,7 +229,12 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
202
229
  const fileXLoad = this.arrayFilesLoad[0].file;
203
230
  const uid = this.arrayFilesLoad[0].uid;
204
231
  const type = this.arrayFilesLoad[0].type;
205
- const size = this.arrayFilesLoad[0].size
232
+ const size = this.arrayFilesLoad[0].size;
233
+ if(size > this.file_size_limit * 1024 * 1024){
234
+ this.logger.error('[CONV-FOOTER] file size is greater than the limit: ', size, this.file_size_limit * 1024 * 1024);
235
+ this.showErrorNetwork();
236
+ return;
237
+ }
206
238
  this.logger.log('[CONV-FOOTER] that.fileXLoad: ', type);
207
239
  let metadata;
208
240
  if (type.startsWith('image') && !type.includes('svg')) {
@@ -239,6 +271,15 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
239
271
  }
240
272
 
241
273
 
274
+ private showErrorNetwork() {
275
+ this.isErrorNetwork = true;
276
+ setTimeout(() => {
277
+ this.isErrorNetwork = false;
278
+ this.isFilePendingToUpload = false;
279
+ this.hideTextReply = false;
280
+ }, 5000);
281
+ }
282
+
242
283
  uploadSingle(metadata, file, messageText?: string) {
243
284
  const that = this;
244
285
  try {
@@ -319,6 +360,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
319
360
  * @param additional_attributes
320
361
  */
321
362
  sendMessage(msg: string, type: string, metadata?: any, additional_attributes?: any) { // sponziello
363
+
322
364
  (metadata) ? metadata = metadata : metadata = '';
323
365
  this.onEmojiiPickerShow.emit(false)
324
366
  this.logger.log('[CONV-FOOTER] SEND MESSAGE: ', msg, type, metadata, additional_attributes);
@@ -1,15 +1,15 @@
1
1
  :host {
2
2
  --backgroundColor: #{var(--blue)};
3
- --textColor: #{var(--bck-msg-sent)};
3
+ --buttonTextColor: #{var(--bck-msg-sent)};
4
4
  --hoverBackgroundColor: #{var(--bck-msg-sent)};
5
5
  --hoverTextColor: #{var(--blue)};
6
- --buttonFontSize2: #{var(--button-font-size)};
6
+ --buttonFontSize: #{var(--button-font-size)};
7
7
  --max-width: #{var(--button-in-msg-max-width)};
8
8
  --padding: #{var(--button-in-msg-padding)};
9
9
  --font-family: #{var(--button-in-msg-font-family)};
10
10
  --buttonBorderColor: #{var(--button-border-color)};
11
11
  --buttonColor: #{var(--button-color)};
12
- --buttonBackgroundColor: #ffffff; //#{var(--button-background-color)};
12
+ --buttonBackgroundColor: #{var(--button-background-color)};
13
13
  }
14
14
 
15
15
  .button-in-msg {
@@ -20,8 +20,8 @@
20
20
  border: 1px solid var(--buttonBorderColor);
21
21
  background: var(--buttonBackgroundColor);
22
22
  font-family: var(--font-family);
23
- font-size: var(--buttonFontSize2);
24
- color: var(--textColor);
23
+ font-size: var(--buttonFontSize);
24
+ color: var(--buttonTextColor);
25
25
  overflow: hidden;
26
26
  -o-text-overflow: ellipsis;
27
27
  text-overflow: ellipsis;
@@ -38,7 +38,7 @@
38
38
  }
39
39
 
40
40
  .action {
41
- background: var(--backgroundColor);
41
+ // background: var(--backgroundColor);
42
42
  transition: background-color .6s ease;
43
43
  &:focus,
44
44
  &:hover {
@@ -25,7 +25,7 @@ export class ActionButtonComponent implements OnInit {
25
25
  ngOnChanges(changes: SimpleChanges){
26
26
  //decomment if element should have same color of themeColor and fregroundColor
27
27
  if(this.fontSize) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonFontSize', this.fontSize);
28
- if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--backgroundColor', this.backgroundColor);
28
+ if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
29
29
  if(this.textColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--textColor', this.textColor);
30
30
  if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
31
31
  if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverTextColor', this.hoverTextColor);
@@ -1,15 +1,15 @@
1
1
  :host {
2
2
  --backgroundColor: #{var(--blue)};
3
- --textColor: #{var(--bck-msg-sent)};
3
+ --buttonTextColor: #{var(--bck-msg-sent)};
4
4
  --hoverBackgroundColor: #{var(--bck-msg-sent)};
5
5
  --hoverTextColor: #{var(--blue)};
6
- --buttonFontSize2: #{var(--button-font-size)};
6
+ --buttonFontSize: #{var(--button-font-size)};
7
7
  --max-width: #{var(--button-in-msg-max-width)};
8
8
  --padding: #{var(--button-in-msg-padding)};
9
9
  --font-family: #{var(--button-in-msg-font-family)};
10
10
  --buttonBorderColor: #{var(--button-border-color)};
11
11
  --buttonColor: #{var(--button-color)};
12
- --buttonBackgroundColor: #ffffff; //#{var(--button-background-color)};
12
+ --buttonBackgroundColor: #{var(--button-background-color)};
13
13
  }
14
14
 
15
15
 
@@ -21,8 +21,8 @@
21
21
  border: 1px solid var(--buttonBorderColor);
22
22
  background: var(--buttonBackgroundColor);
23
23
  font-family: var(--font-family);
24
- font-size: var(--buttonFontSize2);
25
- color: var(--textColor);
24
+ font-size: var(--buttonFontSize);
25
+ color: var(--buttonTextColor);
26
26
  overflow: hidden;
27
27
  -o-text-overflow: ellipsis;
28
28
  text-overflow: ellipsis;
@@ -23,8 +23,8 @@ export class LinkButtonComponent implements OnInit {
23
23
  ngOnChanges(changes: SimpleChanges){
24
24
  //decomment if element should have same color of themeColor and fregroundColor
25
25
  if(this.fontSize) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonFontSize', this.fontSize);
26
- if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--backgroundColor', this.backgroundColor);
27
- if(this.textColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--textColor', this.textColor);
26
+ if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
27
+ if(this.textColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonTextColor', this.textColor);
28
28
  if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
29
29
  if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--hoverTextColor', this.hoverTextColor);
30
30
  }
@@ -1,15 +1,14 @@
1
1
  :host {
2
2
  --backgroundColor: #{var(--blue)};
3
- --textColor: #{var(--bck-msg-sent)};
4
- --hoverBackgroundColor: #{var(--bck-msg-sent)};
5
- --hoverTextColor: #{var(--blue)};
6
- --buttonFontSize2: #{var(--button-font-size)};
3
+ --buttonTextColor: #{var(--bck-msg-sent)};
4
+ --buttonHoverBackgroundColor: #{var(--bck-msg-sent)};
5
+ --buttonHoverTextColor: #{var(--blue)};
6
+ --buttonFontSize: #{var(--button-font-size)};
7
7
  --max-width: #{var(--button-in-msg-max-width)};
8
8
  --padding: #{var(--button-in-msg-padding)};
9
9
  --font-family: #{var(--button-in-msg-font-family)};
10
10
  --buttonBorderColor: #{var(--button-border-color)};
11
- // --buttonColor: #{var(--buttonColor)};
12
- --buttonBackgroundColor: #ffffff; //#{var(--button-background-color)};
11
+ --buttonBackgroundColor: #{var(--button-background-color)};
13
12
  --buttonColor: #{var(--button-color)};
14
13
  }
15
14
 
@@ -21,11 +20,9 @@
21
20
  cursor: pointer;
22
21
  border: 1px solid var(--buttonBorderColor);
23
22
  background: var(--buttonBackgroundColor);
24
- // background: var(--backgroundColor);
25
23
  font-family: var(--font-family);
26
- font-size: var(--buttonFontSize2);
27
- // color: var(--buttonColor);
28
- color: var(--textColor);
24
+ font-size: var(--buttonFontSize);
25
+ color: var(--buttonTextColor);
29
26
  overflow: hidden;
30
27
  -o-text-overflow: ellipsis;
31
28
  text-overflow: ellipsis;
@@ -47,8 +44,8 @@
47
44
  transition: background-color .6s ease;
48
45
  &:focus,
49
46
  &:hover {
50
- color: var(--hoverTextColor);
51
- background: var(--hoverBackgroundColor);
47
+ color: var(--buttonHoverTextColor);
48
+ background: var(--buttonHoverBackgroundColor);
52
49
  // transform: scale(1.05);
53
50
  .icon-button-action {
54
51
  svg {
@@ -26,10 +26,10 @@ export class TextButtonComponent implements OnInit {
26
26
  ngOnChanges(changes: SimpleChanges){
27
27
  //decomment if element should have same color of themeColor and fregroundColor
28
28
  if(this.fontSize) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonFontSize', this.fontSize);
29
- if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--backgroundColor', this.backgroundColor);
30
- if(this.textColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--textColor', this.textColor);
31
- if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
32
- if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--hoverTextColor', this.hoverTextColor);
29
+ if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
30
+ if(this.textColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonTextColor', this.textColor);
31
+ if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonHoverBackgroundColor', this.hoverBackgroundColor);
32
+ if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonHoverTextColor', this.hoverTextColor);
33
33
  }
34
34
 
35
35
  onMouseOver(event){
@@ -3,15 +3,11 @@
3
3
 
4
4
  <span *ngFor="let button of buttons | slice:0:limit" class="div-button">
5
5
 
6
- <!--
7
- // bubbleReceivedBackground
8
- // buttonBackgroundColor
9
- -->
10
6
  <chat-text-button-attachment *ngIf="button.type === 'text' && isLastMessage === true" class="div-button"
11
7
  [button]="button"
12
8
  [isConversationArchived]="isConversationArchived"
13
9
  [fontSize]="stylesMap.get('buttonFontSize')"
14
- [backgroundColor]="stylesMap.get('bubbleReceivedBackground')"
10
+ [backgroundColor]="stylesMap.get('buttonBackgroundColor')"
15
11
  [textColor]="stylesMap.get('buttonTextColor')"
16
12
  [hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
17
13
  [hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
@@ -21,7 +17,7 @@
21
17
  <chat-link-button-attachment *ngIf="button.type === 'url'" class="div-button"
22
18
  [button]="button"
23
19
  [fontSize]="stylesMap.get('buttonFontSize')"
24
- [backgroundColor]="stylesMap.get('bubbleReceivedBackground')"
20
+ [backgroundColor]="stylesMap.get('buttonBackgroundColor')"
25
21
  [textColor]="stylesMap.get('buttonTextColor')"
26
22
  [hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
27
23
  [hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
@@ -32,7 +28,7 @@
32
28
  [button]="button"
33
29
  [isConversationArchived]="isConversationArchived"
34
30
  [fontSize]="stylesMap.get('buttonFontSize')"
35
- [backgroundColor]="stylesMap.get('bubbleReceivedBackground')"
31
+ [backgroundColor]="stylesMap.get('buttonBackgroundColor')"
36
32
  [textColor]="stylesMap.get('buttonTextColor')"
37
33
  [hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
38
34
  [hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
@@ -3,6 +3,6 @@
3
3
  <path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
4
4
  </svg>
5
5
  <div class="alert-content">
6
- {{ translationMap.get('CONNECTION_NETWORK_ERROR')}}
6
+ {{ translationMap.get(keyErrorMessage)}}
7
7
  </div>
8
8
  </div>
@@ -1,4 +1,4 @@
1
- import { Component, OnInit } from '@angular/core';
1
+ import { Component, Input, OnInit } from '@angular/core';
2
2
  import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
3
3
 
4
4
  @Component({
@@ -8,6 +8,7 @@ import { CustomTranslateService } from 'src/chat21-core/providers/custom-transla
8
8
  })
9
9
  export class NetworkOfflineComponent implements OnInit {
10
10
 
11
+ @Input() keyErrorMessage: string = 'CONNECTION_NETWORK_ERROR';
11
12
  translationMap: Map< string, string>;
12
13
 
13
14
  constructor(
@@ -16,7 +17,7 @@ export class NetworkOfflineComponent implements OnInit {
16
17
 
17
18
  ngOnInit(): void {
18
19
  let keys = [
19
- 'CONNECTION_NETWORK_ERROR'
20
+ this.keyErrorMessage
20
21
  ]
21
22
  this.translationMap = this.customTranslateService.translateLanguage(keys)
22
23
  }
@@ -99,7 +99,7 @@ export class TranslatorService {
99
99
 
100
100
  // https://github.com/ngx-translate/core/issues/282
101
101
  initI18n(): Promise<any> {
102
- this._translate.addLangs(['en', 'it']);
102
+ this._translate.addLangs(['en', 'it', 'es', 'fr']);
103
103
  this.logger.debug('[TRANSLATOR-SERV]»»»» initI18n getLangs ', this._translate.getLangs());
104
104
 
105
105
  // Set the default language for translation strings.
@@ -261,7 +261,10 @@ export class TranslatorService {
261
261
  'WAITING_TIME_FOUND',
262
262
  'WAITING_TIME_NOT_FOUND',
263
263
  'CLOSED',
264
- 'LABEL_PREVIEW'
264
+ 'LABEL_PREVIEW',
265
+ 'MAX_ATTACHMENT',
266
+ 'MAX_ATTACHMENT_ERROR',
267
+ 'EMOJI'
265
268
  ];
266
269
 
267
270
 
@@ -316,6 +319,9 @@ export class TranslatorService {
316
319
  globals.CLOSED = res['CLOSED'];
317
320
  globals.LABEL_PREVIEW = res['LABEL_PREVIEW']
318
321
  globals.LABEL_ERROR_FIELD_REQUIRED= res['LABEL_ERROR_FIELD_REQUIRED']
322
+ globals.MAX_ATTACHMENT = res['MAX_ATTACHMENT']
323
+ globals.MAX_ATTACHMENT_ERROR = res['MAX_ATTACHMENT_ERROR']
324
+ globals.EMOJI = res['EMOJI']
319
325
 
320
326
 
321
327
  if(globals.WELCOME_TITLE === 'WELLCOME_TITLE') globals.WELCOME_TITLE = res['WELCOME_TITLE']
@@ -24,7 +24,7 @@
24
24
  --button-in-msg-max-width: 280px;
25
25
  --button-in-msg-padding: 8px 16px;
26
26
  --button-color: #5c6c73;
27
- --button-background-color: #f5f5f5; // #f9fcff;
27
+ --button-background-color: #ffffff;//#f5f5f5; // #f9fcff;
28
28
  --button-border-color: #0000000f; //#e4ebf2;
29
29
  --button-font-size: 13px;
30
30
 
@@ -396,7 +396,7 @@ export function checkAcceptedFile(nameFile, fileType, fileUploadAccept): boolean
396
396
  return acceptedTypes.some((accept) => {
397
397
  accept = accept.trim();
398
398
 
399
- // Controlla per i tipi MIME con wildcard, come image/*
399
+ // Controlla wildcard MIME type (es. "image/*")
400
400
  if (accept.endsWith('/*')) {
401
401
  const baseMimeType = fileType.split('/')[0]; // Ottieni la parte principale del MIME type
402
402
  return accept.replace('/*', '') === baseMimeType;
@@ -413,19 +413,17 @@ export function checkAcceptedFile(nameFile, fileType, fileUploadAccept): boolean
413
413
  return true;
414
414
  }
415
415
 
416
- // // Controlla se l'estensione del file corrisponde direttamente
417
- // if (accept.startsWith('.') && fileExtension === accept.substring(1)) {
418
- // return true;
419
- // }
416
+ // Controlla estensione con punto (es. ".pdf")
417
+ if (accept.startsWith('.')) {
418
+ return fileExtension === accept.slice(1);
419
+ }
420
420
 
421
- // Controlla se l'estensione del file corrisponde direttamente
422
- // Dividi la stringa fileUploadAccept in un array di tipi accettati
423
- const acceptedTypes = fileUploadAccept.split(',');
424
- //verifica se l'estensione del file è accettata
425
- if (acceptedTypes.includes(fileExtension)) {
421
+ // Controlla se accept è un'estensione senza punto (es. "pdf")
422
+ if (!accept.includes('/') && fileExtension === accept) {
426
423
  return true;
427
424
  }
428
425
 
426
+
429
427
  return false;
430
428
  });
431
429
  }
@@ -94,5 +94,8 @@
94
94
  "SWITCH_TO": "Or switch to:",
95
95
  "CONNECTION_NETWORK_ERROR": "Our apologies. There was some trouble connecting to network",
96
96
  "EMOJI_NOT_ELLOWED":"Emoji not allowed",
97
- "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain"
97
+ "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
98
+ "MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
99
+ "MAX_ATTACHMENT": "Max allowed size {{file_size_limit}}Mb",
100
+ "EMOJI": "Emoji"
98
101
  }
@@ -92,5 +92,10 @@
92
92
 
93
93
  "LABEL_PREVIEW": "Avance",
94
94
  "SWITCH_TO":"O cambiar a:",
95
- "CONNECTION_NETWORK_ERROR": "Nuestras disculpas. Hubo algunos problemas para conectarse a la red"
95
+ "CONNECTION_NETWORK_ERROR": "Nuestras disculpas. Hubo algunos problemas para conectarse a la red",
96
+ "EMOJI_NOT_ELLOWED":"Emoji no permitido",
97
+ "DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
98
+ "MAX_ATTACHMENT_ERROR": "El archivo supera el tamaño máximo permitido",
99
+ "MAX_ATTACHMENT": "Tamaño máximo permitido {{file_size_limit}}Mb",
100
+ "EMOJI": "Emoji"
96
101
  }
@@ -92,5 +92,10 @@
92
92
 
93
93
  "LABEL_PREVIEW": "Aperçu",
94
94
  "SWITCH_TO":"Ou passer à:",
95
- "CONNECTION_NETWORK_ERROR": "Nos excuses. Il y a eu des problèmes de connexion au réseau"
95
+ "CONNECTION_NETWORK_ERROR": "Nos excuses. Il y a eu des problèmes de connexion au réseau",
96
+ "EMOJI_NOT_ELLOWED":"Emoji non autorisé",
97
+ "DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
98
+ "MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
99
+ "MAX_ATTACHMENT": "Taille maximale autorisée {{file_size_limit}}Mo",
100
+ "EMOJI": "Emoji"
96
101
  }
@@ -86,11 +86,14 @@
86
86
  "LABEL_LAST_ACCESS": "ultimo accesso",
87
87
  "LABEL_TO": "a",
88
88
  "ARRAY_DAYS": ["Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"],
89
-
90
89
  "SENT_AN_ATTACHMENT": "ha inviato un allegato",
91
90
  "SENT_AN_IMAGE":"ha inviato un'immagine",
92
-
93
91
  "LABEL_PREVIEW": "Anteprima",
94
92
  "SWITCH_TO":"Oppure passa a:",
95
- "CONNECTION_NETWORK_ERROR": "Ci scusiamo. Si sono verificati problemi di connessione di rete"
93
+ "CONNECTION_NETWORK_ERROR": "Ci scusiamo. Si sono verificati problemi di connessione di rete",
94
+ "EMOJI_NOT_ELLOWED":"Emoji non consentiti",
95
+ "DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
96
+ "MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
97
+ "MAX_ATTACHMENT": "Dimensione massima consentita {{file_size_limit}}Mb",
98
+ "EMOJI": "Emoji"
96
99
  }
@@ -413,8 +413,8 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
413
413
  message.text = INFO_SUPPORT_LEAD_UPDATED;
414
414
  } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_LEFT_GROUP) {
415
415
  let subject: string = '';
416
- if (message.attributes.messagelabel.parameters.fullname) {
417
- subject = message.attributes.messagelabel.parameters.fullname;
416
+ if (message.attributes.messagelabel.parameters.firstname) {
417
+ subject = message.attributes.messagelabel.parameters.firstname;
418
418
  }else{
419
419
  subject = message.attributes.messagelabel.parameters.member_id;
420
420
  }
@@ -410,8 +410,8 @@ export class MQTTConversationHandler extends ConversationHandlerService {
410
410
  message.text = INFO_SUPPORT_LEAD_UPDATED;
411
411
  } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_LEFT_GROUP) {
412
412
  let subject: string;
413
- if (message.attributes.messagelabel.parameters.fullname) {
414
- subject = message.attributes.messagelabel.parameters.fullname;
413
+ if (message.attributes.messagelabel.parameters.firstname) {
414
+ subject = message.attributes.messagelabel.parameters.firstname;
415
415
  }else{
416
416
  subject = message.attributes.messagelabel.parameters.member_id;
417
417
  }
@@ -464,16 +464,17 @@ export class MQTTConversationHandler extends ConversationHandlerService {
464
464
  private async addCommandMessage(msg: MessageModel): Promise<boolean>{
465
465
  const that = this;
466
466
  const commands = msg.attributes.commands;
467
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage: ', commands)
467
468
  let i=0;
468
469
  if(commands.length === 0) return;
469
470
  return new Promise((resolve, reject)=>{
470
471
  function execute(command){
472
+ that.logger.debug('[MQTTConversationHandlerSERVICE] command: ', command, i)
471
473
  if(command.type === "message"){
472
474
  that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
473
475
  if (i >= 2) {
474
-
475
476
  //check if previus wait message type has time value, otherwize set to 1000ms
476
- !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
477
+ !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time;
477
478
  command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
478
479
 
479
480
  /** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
@@ -483,12 +484,14 @@ export class MQTTConversationHandler extends ConversationHandlerService {
483
484
  command.message.timestamp = previewsTimeMsg + 100
484
485
  commands[i+1]? commands[i+1].time = 0 : null
485
486
  }
486
- } else { /**MANAGE FIRST MESSAGE */
487
+ }
488
+ else { /**MANAGE FIRST MESSAGE */
487
489
  command.message.timestamp = msg.timestamp;
488
490
  if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
489
491
  commands[i+1]? commands[i+1].time = 0 : null
490
492
  }
491
493
  }
494
+
492
495
  that.generateMessageObject(msg, command.message, i, function () {
493
496
  i += 1
494
497
  if (i < commands.length) {
@@ -499,28 +502,36 @@ export class MQTTConversationHandler extends ConversationHandlerService {
499
502
  resolve(true)
500
503
  }
501
504
  })
502
- }else if(command.type === "wait"){
503
- that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
505
+ } else if(command.type === "wait"){
504
506
  //publish waiting event to simulate user typing
505
507
  if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
506
508
  // console.log('message just received::', command, i, commands)
507
509
  that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
508
510
  }
509
- setTimeout(function() {
511
+ that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage: --> msg.status: ', msg.status)
512
+
513
+ const executeNext = () => {
510
514
  i += 1
511
515
  if (i < commands.length) {
512
516
  execute(commands[i])
513
- }
514
- else {
517
+ } else {
515
518
  that.logger.debug('[MQTTConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
516
519
  resolve(true)
517
520
  }
518
- },command.time)
521
+ }
522
+
523
+ if(msg.status === MSG_STATUS_RECEIVED){
524
+ executeNext()
525
+ } else {
526
+ setTimeout(executeNext, command.time)
527
+ }
519
528
  }
520
529
  }
521
530
  execute(commands[0]) //START render first message
522
531
  })
523
532
  }
533
+
534
+
524
535
 
525
536
  private generateMessageObject(message, command_message, index, callback) {
526
537
  let parentUid = message.uid
@@ -71,7 +71,7 @@ export class TiledeskRequestsService {
71
71
 
72
72
  public getMyRequests(): Promise<{ requests: Array<any>}> {
73
73
  this.tiledeskToken = this.appStorage.getItem('tiledeskToken')
74
- const url = this.URL_TILEDESK_REQUEST + '/me?preflight=true'
74
+ const url = this.URL_TILEDESK_REQUEST + 'me?preflight=true'
75
75
  this.logger.log('[TILEDESK-SERVICE] - GET REQUEST url ', url);
76
76
  const httpOptions = {
77
77
  headers: new HttpHeaders({
@@ -661,11 +661,22 @@ export function isAllowedUrlInText(text: string, allowedUrls: string[]) {
661
661
  return nonWhitelistedDomains.length === 0;
662
662
  }
663
663
 
664
+ // function extractUrls(text: string): string[] {
665
+ // const urlRegex = /https?:\/\/[^\s]+/g;
666
+ // return text.match(urlRegex) || [];
667
+ // }
668
+
664
669
  function extractUrls(text: string): string[] {
665
- const urlRegex = /https?:\/\/[^\s]+/g;
666
- return text.match(urlRegex) || [];
670
+ // Rileva URL con o senza protocollo (http/https)
671
+ const urlRegex = /\b((https?:\/\/)?(www\.)?[a-z0-9.-]+\.[a-z]{2,})(\/[^\s]*)?/gi;
672
+ const matches = text.match(urlRegex) || [];
673
+ // Normalizza: aggiunge https:// se manca, così il parsing con new URL() funziona
674
+ return matches.map((url) => {
675
+ if (!/^https?:\/\//i.test(url)) {
676
+ return 'https://' + url;
677
+ }
678
+ return url;
679
+ });
667
680
  }
668
681
 
669
682
 
670
-
671
-
@@ -19,7 +19,7 @@
19
19
 
20
20
  #tiledesk-container.open.overlay--popup {
21
21
  background-color: rgba(0, 0, 0, 0.4);
22
- position: absolute;
22
+ position: fixed;
23
23
  width: 100%;
24
24
  height: 100vh;
25
25
  }