@chat21/chat21-web-widget 5.1.20-rc1 → 5.1.20

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 +13 -23
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +12 -22
  3. package/CHANGELOG.md +3 -54
  4. package/Dockerfile +5 -4
  5. package/angular.json +1 -2
  6. package/deploy_amazon_beta.sh +7 -17
  7. package/deploy_amazon_prod.sh +4 -4
  8. package/package.json +1 -1
  9. package/src/app/app.component.html +1 -8
  10. package/src/app/app.component.scss +0 -59
  11. package/src/app/app.component.ts +28 -63
  12. package/src/app/component/conversation-detail/conversation/conversation.component.ts +4 -18
  13. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +0 -25
  14. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +0 -1
  15. package/src/app/component/home-conversations/home-conversations.component.html +6 -16
  16. package/src/app/component/home-conversations/home-conversations.component.ts +0 -29
  17. package/src/app/component/launcher-button/launcher-button.component.html +1 -1
  18. package/src/app/component/launcher-button/launcher-button.component.ts +2 -3
  19. package/src/app/component/list-conversations/list-conversations.component.html +3 -8
  20. package/src/app/component/list-conversations/list-conversations.component.ts +0 -29
  21. package/src/app/pipe/marked.pipe.ts +17 -1
  22. package/src/app/providers/translator.service.ts +0 -2
  23. package/src/app/utils/globals.ts +1 -1
  24. package/src/assets/i18n/en.json +0 -1
  25. package/src/assets/i18n/es.json +0 -1
  26. package/src/assets/i18n/fr.json +0 -1
  27. package/src/assets/i18n/it.json +0 -1
  28. package/src/chat21-core/providers/abstract/upload.service.ts +1 -1
  29. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +1 -1
  30. package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
  31. package/src/chat21-core/providers/native/native-upload-service.ts +54 -76
  32. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  33. package/src/chat21-core/utils/utils.ts +2 -5
  34. package/src/iframe-style.css +5 -5
@@ -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,22 +12,12 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
 
14
14
  steps:
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
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
@@ -3,30 +3,20 @@ name: Publish Docker Community image tags
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - '**' # Trigger su qualsiasi tag
7
-
6
+ - '**' # Push events to every tag including hierarchical tags like
8
7
  jobs:
8
+
9
9
  push_to_registry:
10
10
  name: Push Docker image to Docker Hub
11
11
  runs-on: ubuntu-latest
12
-
13
12
  steps:
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 }}
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
package/CHANGELOG.md CHANGED
@@ -6,12 +6,10 @@
6
6
  ### **Copyrigth**:
7
7
  *Tiledesk SRL*
8
8
 
9
- # 5.1.20-rc1
10
- - **changed**: API for upload a file/iamges
9
+ # 5.1.20
10
+ - **changed**: marked pipe do not render /n
11
11
 
12
12
  # 5.1.19
13
-
14
- # 5.1.19-rc1
15
13
  - **bug fixed**: show bottom scroll button and unread message badge only when I'm not at the bottom of the page
16
14
  - **changed**: allow HTML code to be inserted into messages, but do not parse the code. Ensure coexistence with Markdown.
17
15
  - **bug fixed**: after sending a multi-line message, the text area remains open on multiple lines.
@@ -21,7 +19,6 @@
21
19
  - **changed**: saved the widget's size state to local storage. The parameter flow is (default → storage → settings → URL)
22
20
 
23
21
  # 5.1.18
24
- # 5.1.15-rc3
25
22
  - **added**: Implemented Shadow DOM in the text component to isolate HTML and Markdown rendering in a safe and protected context
26
23
  - **changed**: Adapted text component styles to support Shadow DOM (removed ::ng-deep, added styles for common markdown elements)
27
24
  - **security**: HTML/Markdown content is now rendered in an isolated Shadow DOM, improving security and preventing interference with the rest of the application
@@ -32,12 +29,6 @@
32
29
  # 5.1.16
33
30
  - **changed**: "close chat" header conversation menu button enabled in chatbot-panel.html
34
31
 
35
- # 5.1.15-rc2
36
- - **bug-fixed**: Bug fix for ifame message width
37
-
38
- # 5.1.15-rc1
39
- - **changed**: Load local translations before remote ones
40
-
41
32
  # 5.1.15
42
33
  - **changed**: Load local translations before remote ones
43
34
 
@@ -46,56 +37,14 @@
46
37
 
47
38
  # 5.1.13
48
39
  - **bug-fixed**: set default widget size
49
-
50
- # 5.1.7-rc16
51
- - **bug-fixed**: set default widget size
52
-
53
- # 5.1.7-rc15
54
- - **bug-fixed**: set the color of the buttons with visibility control to the font color
55
-
56
- # 5.1.7-rc14
57
- - **bug-fixed**: departmentId and departmentName is incorrect in attributes
58
-
59
- # 5.1.7-rc13
60
- - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
61
-
62
- # 5.1.7-rc12
63
- - **changed**: Set the default autoStart value to false
64
- - **added**: Added the open widget loading spinner
65
- - **changed**: Load the widget without authentication and display the speech bubble
66
-
67
- # 5.1.7-rc11
68
- - **changed**: set default value autoStart false
69
- - **added**:added loading spinner
70
-
71
- # 5.1.7-rc10
72
- - **changed**: load widget without authentication and display the balloon
73
-
74
- # 5.1.7-rc9
75
- - **removed**: 'DOMAIN_NOT_ALLOWED' in textarea footer component
76
-
77
- # 5.1.7-rc8
78
- # changes in the branch
79
- - **changed**: Load local translations before remote ones
80
- - **bug-fixed**: set default widget size
81
40
  - **changed**: Updated the translations of the tooltips in the footer-component
82
41
  - **changed**: Refactored the network-offline component and made it generic for displaying errors (now error-alert.component)
83
-
84
- # 5.1.7-rc7
85
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
86
-
87
- # 5.1.7-rc6
88
- - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
42
+ - **bug-fixed**: set the color of the buttons with visibility control to the font color (setButtonColors function)
89
43
 
90
44
  # 5.1.12
91
45
  - **bug-fixed**: check showEmojiFooterButton to enable/disable emojii
92
46
  - **bug-fixed**: markdown is fired as an emojii and blocked by isEmojii check fn
93
47
 
94
- # 5.1.7-rc7
95
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
96
-
97
- # 5.1.7-rc6
98
- - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
99
48
 
100
49
  # 5.1.7-rc5
101
50
  - **bug-fixed**: bug fixed BUTTON STYLES
package/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ### STAGE 1: Build ###
2
2
 
3
3
  # We label our stage as ‘builder’
4
- FROM --platform=$BUILDPLATFORM node:20.12.2-alpine3.19 as builder
4
+ FROM node:20.12.2-alpine3.19 as builder
5
5
 
6
6
  COPY package.json package-lock.json ./
7
7
 
@@ -15,11 +15,12 @@ COPY . .
15
15
 
16
16
  ## Build the angular app in production mode and store the artifacts in dist folder
17
17
 
18
-
19
18
  RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
20
19
 
20
+
21
21
  ### STAGE 2: Setup ###
22
- FROM --platform=$BUILDPLATFORM nginx:1.14.1-alpine
22
+
23
+ FROM nginx:1.14.1-alpine
23
24
 
24
25
  ## Copy our default nginx config
25
26
  COPY nginx.conf /etc/nginx/nginx.conf
@@ -32,4 +33,4 @@ COPY --from=builder /ng-app/dist/browser /usr/share/nginx/html
32
33
 
33
34
  RUN echo "Chat21 Web Widget Started!!"
34
35
 
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;'"]
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;'"]
package/angular.json CHANGED
@@ -44,8 +44,7 @@
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",
48
- "src/environments/real_data/widget-config-aws-aruba.json"
47
+ "src/environments/real_data/widget-config-aws-stage.json"
49
48
  ],
50
49
  "styles": [
51
50
  "src/app/sass/styles.scss"
@@ -2,16 +2,8 @@
2
2
  version=`node -e 'console.log(require("./package.json").version)'`
3
3
  echo "version $version"
4
4
 
5
- npm i
6
-
7
- cp src/environments/real_data/environment.pre.ts src/environments/environment.pre.ts
8
-
9
5
  ng build --configuration="pre" --aot=true --base-href
10
6
 
11
- ### SET HASHING : START ###
12
- cp ./src/launch_template.js ./dist/browser/launch.js
13
- node ./src/build_launch.js
14
- ### SET HASHING : END ###
15
7
 
16
8
  # ########## --->>>> NATIVE-MQTT folder START <<<<<------ ########## #
17
9
 
@@ -31,17 +23,15 @@ node ./src/build_launch.js
31
23
 
32
24
 
33
25
  # ########## --->>>> FIREBASE folder START <<<<<------ ########## #
34
- cd dist/browser
35
- aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300 --exclude='launch.js' #7days
36
- aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
37
- aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control max-age=300 --exclude='launch.js' #7days
38
- aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
39
- cd ../..
26
+ cd dist
27
+ aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300
28
+ aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control max-age=300
29
+ cd ..
40
30
 
41
- aws cloudfront create-invalidation --distribution-id E2V5O0YPR61V8P --paths "/*"
42
-
43
- git restore src/environments/environment.pre.ts
31
+ #aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*"
32
+ cd ..
44
33
 
34
+ aws cloudfront create-invalidation --distribution-id E2V5O0YPR61V8P --paths "/*"
45
35
  # echo new version deployed $NEW_VER/$NEW_BUILD/ on s3://tiledesk-widget-pre/v2
46
36
  echo new version deployed $version/ on s3://tiledesk-widget-pre/v5 and s3://tiledesk-widget-pre/v5/$version/
47
37
  echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget-pre/v5/index.html
@@ -35,7 +35,7 @@ aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*
35
35
 
36
36
  git restore src/environments/environment.prod.ts
37
37
 
38
- echo new version deployed $version on s3://tiledesk-widget/v5
39
- echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget/v5/index.html
40
- echo https://widget.tiledesk.com/v5/index.html
41
- echo https://widget.tiledesk.com/v5/$version/index.html
38
+ echo new version deployed $version on s3://tiledesk-widget/v6
39
+ echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget/v6/index.html
40
+ echo https://widget.tiledesk.com/v6/index.html
41
+ echo https://widget.tiledesk.com/v6/$version/index.html
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.20-rc1",
4
+ "version": "5.1.20",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -145,12 +145,5 @@
145
145
  <chat-launcher-button *ngIf="isInitialized"
146
146
  (onButtonClicked)="onOpenCloseWidget($event)">
147
147
  </chat-launcher-button>
148
-
149
- <!-- Loading Spinner -->
150
- <div *ngIf="loading" class="tiledesk-loading-overlay">
151
- <div class="tiledesk-loading-spinner">
152
- <div class="spinner-circle"></div>
153
- <div class="loading-text">{{ translationMap.get('LABEL_LOADING') }}</div>
154
- </div>
155
- </div>
148
+
156
149
  </div>
@@ -761,63 +761,4 @@ chat-root {
761
761
  }
762
762
  }
763
763
 
764
- // ========= BEGIN: LOADING SPINNER ========= //
765
- .tiledesk-loading-overlay {
766
- position: absolute;
767
- top: 0;
768
- left: 0;
769
- width: 100%;
770
- height: 100%;
771
- background-color: rgba(248, 249, 250, 0.95);
772
- display: flex;
773
- justify-content: center;
774
- align-items: center;
775
- z-index: 9999;
776
- backdrop-filter: blur(2px);
777
- }
778
-
779
- .tiledesk-loading-spinner {
780
- display: flex;
781
- flex-direction: column;
782
- align-items: center;
783
- gap: 16px;
784
- }
785
-
786
- .spinner-circle {
787
- width: 50px;
788
- height: 50px;
789
- border: 4px solid rgba(59, 130, 246, 0.2);
790
- border-top-color: #3b82f6;
791
- border-radius: 50%;
792
- animation: spin 0.8s linear infinite;
793
- }
794
-
795
- @keyframes spin {
796
- 0% {
797
- transform: rotate(0deg);
798
- }
799
- 100% {
800
- transform: rotate(360deg);
801
- }
802
- }
803
-
804
- .loading-text {
805
- font-family: var(--font-family-bubble-message, 'Roboto', 'Google Sans', Helvetica, Arial, sans-serif);
806
- font-size: 14px;
807
- font-weight: 500;
808
- color: #3b82f6;
809
- letter-spacing: 0.5px;
810
- animation: pulse 1.5s ease-in-out infinite;
811
- }
812
-
813
- @keyframes pulse {
814
- 0%, 100% {
815
- opacity: 1;
816
- }
817
- 50% {
818
- opacity: 0.5;
819
- }
820
- }
821
- // ========= END: LOADING SPINNER ========= //
822
-
823
764
  }
@@ -106,10 +106,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
106
106
 
107
107
  forceDisconnect: boolean = false;
108
108
 
109
- //network status
110
- isOnline: boolean = true;
111
- loading: boolean = false;
112
-
113
109
  // alert error message
114
110
  isShowErrorMessage: boolean = false;
115
111
  errorMessage: string = '';
@@ -153,7 +149,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
153
149
  this.logger.info('[APP-CONF]---------------- ngAfterViewInit: APP.COMPONENT ---------------- ')
154
150
 
155
151
  // Initialize translation map and enable buttons
156
- const keys = ['MAXIMIZE', 'MINIMIZE', 'CENTER', 'BUTTON_CLOSE_TO_ICON', 'LABEL_LOADING'];
152
+ const keys = ['MAXIMIZE', 'MINIMIZE', 'CENTER', 'BUTTON_CLOSE_TO_ICON'];
157
153
  this.translationMap = this.translateService.translateLanguage(keys);
158
154
  this.isButtonsDisabled = false;
159
155
 
@@ -266,7 +262,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
266
262
  this.tiledeskRequestsService.initialize(this.appConfigService.getConfig().apiUrl, this.g.projectid)
267
263
  this.messagingAuthService.initialize();
268
264
  this.chatManager.initialize();
269
- this.uploadService.initialize(this.g.projectid);
265
+ this.uploadService.initialize();
270
266
  }
271
267
 
272
268
 
@@ -320,15 +316,8 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
320
316
  this.g.setIsOpen(isOpen)
321
317
  this.appStorageService.setItem('isOpen', isOpen)
322
318
  }
323
-
324
- if(this.g.onPageChangeVisibilityDesktop === 'last'){
325
- this.logger.debug('[APP-COMP2] ------this.g.isOpen: ', this.g.isOpen)
326
- if(this.g.isOpen){
327
- this.g.autoStart = true;
328
- }
329
- }
330
-
331
-
319
+
320
+
332
321
  /**CHECK IF JWT IS IN URL PARAMETERS */
333
322
  this.logger.debug('[APP-COMP] check if token is passed throw url: ', this.g.jwt);
334
323
  if (this.g.jwt) {
@@ -365,6 +354,10 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
365
354
  this.subscriptions.push(obsSettingsService);
366
355
  this.globalSettingsService.initWidgetParamiters(this.g, this.el);
367
356
 
357
+ // SET AUDIO
358
+ this.audio = new Audio();
359
+ this.audio.src = this.g.baseLocation + URL_SOUND_LIST_CONVERSATION;
360
+ this.audio.load();
368
361
  }
369
362
 
370
363
  private initAll() {
@@ -455,7 +448,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
455
448
  that.triggerOnAuthStateChanged(that.stateLoggedUser);
456
449
  that.logger.debug('[APP-COMP] 1 - IMPOSTO STATO CONNESSO UTENTE ', autoStart);
457
450
 
458
- this.initAudioNotification()
451
+
459
452
 
460
453
  new Promise(async (resolve, reject)=> {
461
454
  that.typingService.initialize(this.g.tenant);
@@ -481,30 +474,26 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
481
474
  that.listenToWidgetClick()
482
475
  }
483
476
 
484
- /** DDP IF AUTOSTART IS FALSE, SHOW WIDGET */
485
- if(!autoStart){
486
- that.logger.info('[APP-COMP] AUTOSTART IS FALSE AND LOGGED SUCCESSFULLY ');
487
- this.g.setParameter('isShown', true, true);
488
- }
489
477
 
490
478
 
491
479
  } else if (state && state === AUTH_STATE_OFFLINE && !this.forceDisconnect) {
492
480
  /** non sono loggato */
493
481
  that.logger.info('[APP-COMP] OFFLINE - NO CURRENT USER AUTENTICATE: ');
494
482
  that.g.setParameter('isLogged', false);
495
- // that.hideWidget();
483
+ that.hideWidget();
496
484
  // that.g.setParameter('isShown', false, true);
497
485
  that.triggerOnAuthStateChanged(that.stateLoggedUser);
498
- if (autoStart || this.g.onPageChangeVisibilityDesktop === 'open' || this.g.onPageChangeVisibilityMobile === 'open') {
486
+ if (autoStart) {
499
487
  that.authenticate();
500
488
  }
501
- } else if(state && state === AUTH_STATE_CLOSE ){
489
+ }else if(state && state === AUTH_STATE_CLOSE ){
502
490
  that.logger.info('[APP-COMP] CLOSE - CHANNEL CLOSED: ', this.chatManager);
503
491
  if(this.g.recipientId){
504
492
  this.chatManager.removeConversationHandler(this.g.recipientId)
505
493
  this.g.recipientId = null;
506
494
  }
507
- }
495
+ }
496
+
508
497
 
509
498
  });
510
499
  this.subscriptions.push(subAuthStateChanged);
@@ -749,8 +738,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
749
738
  // divWidgetContainer.style.display = 'block';
750
739
  // }
751
740
  // }, 500);
752
-
753
- this.loading = false;
754
741
  }
755
742
  // ========= end:: START UI ============//
756
743
 
@@ -859,13 +846,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
859
846
  this.appStorageService.setItem('attributes', JSON.stringify(attributes));
860
847
  return attributes;
861
848
  }
862
-
863
- // SET AUDIO
864
- private initAudioNotification(){
865
- this.audio = new Audio();
866
- this.audio.src = this.g.baseLocation + URL_SOUND_LIST_CONVERSATION;
867
- this.audio.load();
868
- }
849
+
869
850
 
870
851
  private async initConversationsHandler(tenant: string, senderId: string) {
871
852
  this.logger.debug('[APP-COMP] initialize: ListConversationsComponent');
@@ -1624,46 +1605,23 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1624
1605
  this.f21_close();
1625
1606
  }
1626
1607
 
1627
-
1628
- /** DDP reload widget */
1629
- async reloadWidget() {
1630
- this.openCloseWidget();
1631
- this.logger.debug('[APP-COMP-1] AAA - hideWidget');
1632
- await Promise.all([
1633
- this.authenticate(),
1634
- // this.initAll()
1635
- ]);
1636
- this.logger.debug('[APP-COMP-1] CCC - showWidget');
1637
- }
1638
-
1639
-
1640
1608
  /**
1641
1609
  * LAUNCHER BUTTON:
1642
1610
  * onClick button open/close widget
1643
1611
  */
1644
1612
  onOpenCloseWidget($event) {
1645
- this.logger.debug('[APP-COMP] onOpenCloseWidget', $event, this.g.isLogged);
1646
- if(!this.g.isLogged){
1647
- this.reloadWidget();
1648
- } else {
1649
- this.openCloseWidget();
1650
- }
1651
- }
1652
-
1653
- /** DDP show widget */
1654
- openCloseWidget() {
1655
1613
  this.g.setParameter('displayEyeCatcherCard', 'none');
1656
1614
  // const conversationActive: ConversationModel = JSON.parse(this.appStorageService.getItem('activeConversation'));
1657
1615
  const recipientId : string = this.appStorageService.getItem('recipientId')
1658
1616
  this.g.setParameter('recipientId', recipientId);
1659
1617
  this.logger.debug('[APP-COMP] openCloseWidget', recipientId, this.g.isOpen, this.g.startFromHome);
1660
-
1661
1618
  if (this.g.isOpen === false) {
1662
1619
  if(this.forceDisconnect){
1663
1620
  this.logger.log('[FORCE] onOpenCloseWidget --> reconnect', this.forceDisconnect)
1664
1621
  this.messagingAuthService.createCustomToken(this.g.tiledeskToken)
1665
1622
  this.forceDisconnect = false;
1666
1623
  }
1624
+
1667
1625
  if (!recipientId) {
1668
1626
  if(this.g.singleConversation){
1669
1627
  this.isOpenHome = false;
@@ -1683,22 +1641,29 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1683
1641
  this.isOpenHome = false;
1684
1642
  this.isOpenConversation = true;
1685
1643
  this.startUI()
1644
+ // this.isOpenSelectionDepartment = false;
1686
1645
  }
1646
+ // if (!conversationActive && !this.g.startFromHome) {
1647
+ // this.isOpenHome = false;
1648
+ // this.isOpenConversation = true;
1649
+ // this.startNwConversation();
1650
+ // } else if (conversationActive) {
1651
+ // this.isOpenHome = false;
1652
+ // this.isOpenConversation = true;
1653
+ // }
1654
+ // this.g.startFromHome = true;
1687
1655
  this.triggerOnOpenEvent();
1656
+
1688
1657
  } else {
1689
1658
  this.triggerOnCloseEvent();
1690
1659
  }
1691
1660
  //change status to the widget
1692
1661
  this.g.setIsOpen(!this.g.isOpen);
1693
1662
  this.appStorageService.setItem('isOpen', this.g.isOpen);
1694
- //show loading if widget is open and user is not logged
1695
- if(this.g.isOpen === true && !this.g.isLogged){
1696
- this.loading = true;
1697
- }
1663
+
1698
1664
  // this.saveBadgeNewConverstionNumber();
1699
1665
  }
1700
1666
 
1701
-
1702
1667
  /**
1703
1668
  * MODAL SELECTION DEPARTMENT:
1704
1669
  * selected department
@@ -470,7 +470,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
470
470
  return this.isConversationArchived;
471
471
  }
472
472
 
473
- // //FALLBACK TO TILEDESK
473
+ //FALLBACK TO TILEDESK
474
474
  const requests_list = await this.tiledeskRequestService.getMyRequests().catch(err => {
475
475
  this.logger.error('[CONV-COMP] getConversationDetail: error getting request from Tiledesk', err);
476
476
  this.isConversationArchived=true
@@ -488,9 +488,9 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
488
488
  return this.isConversationArchived
489
489
  }
490
490
 
491
- this.isConversationArchived = false;
492
- return null;
493
- }
491
+ this.isConversationArchived = true;
492
+ return null;
493
+ }
494
494
 
495
495
  /**
496
496
  * this.g.recipientId:
@@ -840,20 +840,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
840
840
  this.subscriptions.push(subscribe);
841
841
  }
842
842
 
843
- subscribtionKey = 'conversationsAdded';
844
- subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
845
- if(!subscribtion){
846
-
847
- subscribtion = this.chatManager.conversationsHandlerService.conversationChanged.pipe(takeUntil(this.unsubscribe$)).subscribe((conversation) => {
848
- this.logger.debug('[CONV-COMP] ***** DATAIL conversationsChanged *****', conversation, this.conversationWith, this.isConversationArchived);
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
-
857
843
  subscribtionKey = 'messageWait';
858
844
  subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
859
845
  if (!subscribtion) {
@@ -419,28 +419,3 @@ textarea:active{
419
419
  border: none;
420
420
  // margin: -2px -2px 0px;
421
421
  }
422
-
423
-
424
- // aggiungi un'animazione di fade in e fade out quando .star-rating-widget è visibile con transition
425
- .star-rating-widget {
426
- transition: all 0.5s ease-in-out;
427
- }
428
-
429
- .star-rating-widget {
430
- position: absolute;
431
- left: 0;
432
- right: 0;
433
- bottom: -52px;
434
- height: 100%;
435
- width: 100%;
436
- flex-direction: row;
437
- justify-content: center;
438
- background-color: rgb(255, 255, 255);
439
- flex-wrap: nowrap;
440
- &.active {
441
- bottom: 0px;
442
- }
443
- &.inactive {
444
- bottom: -52px;
445
- }
446
- }
@@ -87,7 +87,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
87
87
 
88
88
  file_size_limit = FILE_SIZE_LIMIT;
89
89
  attachmentTooltip: string = '';
90
- isErrorNetwork: boolean = false;
91
90
 
92
91
 
93
92
  convertColorToRGBA = convertColorToRGBA;
@@ -38,14 +38,9 @@
38
38
  <!--CASE: no conversations EXIST - >1 agents is available -->
39
39
  <div *ngIf="(!listConversations || listConversations.length == 0) && availableAgents && availableAgents.length > 1 && g.showAvailableAgents === true" style="display: flex; margin: 20px 30px;">
40
40
  <div *ngFor="let agent of availableAgents" class="c21-pallozzo">
41
- <div class="c21-ball" [ngStyle] = "{ 'background-color': isImageLoaded(agent) ? 'transparent' : setColorFromString(agent.firstname) }" >
42
- <span *ngIf="!isImageLoaded(agent)" class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
43
- <img *ngIf="agent.imageurl"
44
- [src]="agent.imageurl"
45
- style="display: none;"
46
- (load)="onImageLoad(agent)"
47
- (error)="onImageError(agent)">
48
- <div *ngIf="isImageLoaded(agent)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
41
+ <div class="c21-ball" [ngStyle] = "{ 'background-color':setColorFromString(agent.firstname) }" >
42
+ <span class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
43
+ <div *ngIf="agent.imageurl" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
49
44
  </div>
50
45
  </div>
51
46
  </div>
@@ -53,14 +48,9 @@
53
48
  <!--CASE: no conversations EXIST - 1 agents is available -->
54
49
  <div class="flex-container" *ngIf="(!listConversations || listConversations.length == 0) && availableAgents && availableAgents.length === 1 && g.showAvailableAgents === true">
55
50
  <div *ngFor="let agent of availableAgents" class="c21-pallozzo flex-inline-agent ">
56
- <div class="c21-ball" [ngStyle] = "{ 'background-color': isImageLoaded(agent) ? 'transparent' : setColorFromString(agent.firstname) }" >
57
- <span *ngIf="!isImageLoaded(agent)" class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
58
- <img *ngIf="agent.imageurl"
59
- [src]="agent.imageurl"
60
- style="display: none;"
61
- (load)="onImageLoad(agent)"
62
- (error)="onImageError(agent)">
63
- <div *ngIf="isImageLoaded(agent)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
51
+ <div class="c21-ball" [ngStyle] = "{ 'background-color':setColorFromString(agent.firstname) }" >
52
+ <span class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
53
+ <div *ngIf="agent.imageurl" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
64
54
  </div>
65
55
  </div>
66
56
  <button tabindex="1040" aflistconv #aflistconv class="c21-button-primary" (click)="openNewConversation()" [ngStyle]="{'background-color': g.themeColor, 'border-color': g.themeColor, 'color': g.themeForegroundColor }">
@@ -65,7 +65,6 @@ export class HomeConversationsComponent implements OnInit, OnDestroy {
65
65
  themeForegroundColor = '';
66
66
  LABEL_START_NW_CONV: string;
67
67
  availableAgents: Array<UserAgent> = [];
68
- imageLoadedMap: Map<string, boolean> = new Map<string, boolean>();
69
68
  // ========= end:: variabili del componente ======== //
70
69
 
71
70
  waitingTime: number;
@@ -204,34 +203,6 @@ export class HomeConversationsComponent implements OnInit, OnDestroy {
204
203
  this.onConversationLoaded.emit(conversation)
205
204
  }
206
205
 
207
- /**
208
- * Verifica se l'immagine dell'agente esiste e si carica correttamente
209
- */
210
- isImageLoaded(agent: UserAgent): boolean {
211
- if (!agent?.imageurl) {
212
- return false;
213
- }
214
- return this.imageLoadedMap.get(agent.id) === true;
215
- }
216
-
217
- /**
218
- * Gestisce il caricamento riuscito dell'immagine
219
- */
220
- onImageLoad(agent: UserAgent) {
221
- if (agent?.id && agent?.imageurl) {
222
- this.imageLoadedMap.set(agent.id, true);
223
- }
224
- }
225
-
226
- /**
227
- * Gestisce l'errore di caricamento dell'immagine
228
- */
229
- onImageError(agent: UserAgent) {
230
- if (agent?.id) {
231
- this.imageLoadedMap.set(agent.id, false);
232
- }
233
- }
234
-
235
206
  private openConversationByID(conversation) {
236
207
  this.logger.debug('[HOMECONVERSATIONS] openConversationByID: ', conversation);
237
208
  if ( conversation ) {
@@ -1,7 +1,7 @@
1
1
  <!-- tabindex="000"-->
2
2
 
3
3
  <button aflauncherbutton #aflauncherbutton id="c21-launcher-button" class="c21-button-clean scale-in-center"
4
- *ngIf="g.isOpen == false"
4
+ *ngIf="g.isLogged == true && g.isOpen == false"
5
5
  [ngClass]="{'c21-align-left' : g.align === 'left', 'c21-align-right' : g.align !== 'left'}"
6
6
  [ngStyle]="{ 'background-color': g.baloonImage? null: g.themeColor, 'bottom': g.marginY+'px!important', 'left':(g.align==='left')?g.marginX+'px!important':'', 'right':(g.align==='right')?g.marginX+'px!important':'', 'width': g.launcherWidth, 'height': g.launcherHeight, 'border-radius': g.baloonShape}"
7
7
  (click)="openCloseWidget()"
@@ -67,9 +67,8 @@ export class LauncherButtonComponent implements OnInit, AfterViewInit {
67
67
  // this.g.isOpen = !this.g.isOpen;
68
68
  // this.g.setIsOpen(!this.g.isOpen);
69
69
  // this.appStorageService.setItem('isOpen', this.g.isOpen);
70
-
71
- }
72
- this.onButtonClicked.emit( this.g.isOpen );
70
+ this.onButtonClicked.emit( this.g.isOpen );
71
+ }
73
72
  }
74
73
 
75
74
  }
@@ -3,14 +3,9 @@
3
3
  <button tabindex="1103" class="c21-item-conversation" (click)="openConversationByID(conversation)">
4
4
  <div class="c21-body-conv">
5
5
  <div class="c21-left-conv">
6
- <div class="c21-ball" [ngStyle]="{'background': isImageLoaded(conversation) ? 'transparent' : 'linear-gradient(rgb(255,255,255) -125%, ' + conversation.color + ')'}">
7
- <span *ngIf="!isImageLoaded(conversation)" class="c21-ball-label">{{conversation?.avatar}}</span>
8
- <img *ngIf="conversation?.image"
9
- [src]="conversation.image"
10
- style="display: none;"
11
- (load)="onImageLoad(conversation)"
12
- (error)="onImageError(conversation)">
13
- <div *ngIf="isImageLoaded(conversation)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + conversation.image + ')'"></div>
6
+ <div class="c21-ball" [ngStyle]="{'background': 'linear-gradient(rgb(255,255,255) -125%, ' + conversation.color + ')'}">
7
+ <span class="c21-ball-label">{{conversation?.avatar}}</span>
8
+ <div *ngIf="conversation?.image" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + conversation.image + ')'"></div>
14
9
  </div>
15
10
  </div>
16
11
  <div class="c21-right-conv">
@@ -35,7 +35,6 @@ export class ListConversationsComponent implements OnInit {
35
35
  arrayDiffer: any;
36
36
 
37
37
  uidConvSelected: string;
38
- imageLoadedMap: Map<string, boolean> = new Map<string, boolean>();
39
38
  constructor(private iterableDiffers: IterableDiffers) {
40
39
  this.iterableDifferListConv = this.iterableDiffers.find([]).create(null);
41
40
 
@@ -68,33 +67,5 @@ export class ListConversationsComponent implements OnInit {
68
67
 
69
68
  }
70
69
 
71
- /**
72
- * Verifica se l'immagine esiste e si carica correttamente
73
- */
74
- isImageLoaded(conversation: ConversationModel): boolean {
75
- if (!conversation?.image) {
76
- return false;
77
- }
78
- return this.imageLoadedMap.get(conversation.uid) === true;
79
- }
80
-
81
- /**
82
- * Gestisce il caricamento riuscito dell'immagine
83
- */
84
- onImageLoad(conversation: ConversationModel) {
85
- if (conversation?.uid && conversation?.image) {
86
- this.imageLoadedMap.set(conversation.uid, true);
87
- }
88
- }
89
-
90
- /**
91
- * Gestisce l'errore di caricamento dell'immagine
92
- */
93
- onImageError(conversation: ConversationModel) {
94
- if (conversation?.uid) {
95
- this.imageLoadedMap.set(conversation.uid, false);
96
- }
97
- }
98
-
99
70
 
100
71
  }
@@ -18,7 +18,23 @@ export class MarkedPipe implements PipeTransform {
18
18
  typeof value === 'string'
19
19
  ? value
20
20
  : (value === null || value === undefined) ? '' : String(value);
21
- const safeInput = htmlEntities(input);
21
+
22
+ // Converti i \n letterali in newline reali prima di htmlEntities
23
+ // così il markdown con breaks: true li renderizzerà correttamente
24
+ const inputWithNewlines = input.replace(/\\n/g, '\n');
25
+
26
+ // Proteggi i > usati per i blockquote markdown (all'inizio di riga)
27
+ // sostituendoli temporaneamente con un placeholder
28
+ const BLOCKQUOTE_PLACEHOLDER = '___MARKDOWN_BLOCKQUOTE___';
29
+ const protectedInput = inputWithNewlines.replace(/^(\s*)>/gm, (match, spaces) => {
30
+ return spaces + BLOCKQUOTE_PLACEHOLDER;
31
+ });
32
+
33
+ // Applica htmlEntities (che codificherà tutti gli altri >)
34
+ let safeInput = htmlEntities(protectedInput);
35
+
36
+ // Ripristina i > dei blockquote
37
+ safeInput = safeInput.replace(new RegExp(BLOCKQUOTE_PLACEHOLDER, 'g'), '>');
22
38
 
23
39
  const renderer = new marked.Renderer();
24
40
  renderer.link = function({ href, title, tokens }) {
@@ -302,7 +302,6 @@ export class TranslatorService {
302
302
  'CLOSED',
303
303
  'LABEL_PREVIEW',
304
304
  'MAX_ATTACHMENT',
305
- 'MAX_ATTACHMENT_ERROR',
306
305
  'EMOJI'
307
306
  ];
308
307
 
@@ -359,7 +358,6 @@ export class TranslatorService {
359
358
  globals.LABEL_PREVIEW = res['LABEL_PREVIEW']
360
359
  globals.LABEL_ERROR_FIELD_REQUIRED= res['LABEL_ERROR_FIELD_REQUIRED']
361
360
  globals.MAX_ATTACHMENT = res['MAX_ATTACHMENT']
362
- globals.MAX_ATTACHMENT_ERROR = res['MAX_ATTACHMENT_ERROR']
363
361
  globals.EMOJI = res['EMOJI']
364
362
 
365
363
 
@@ -247,7 +247,7 @@ export class Globals {
247
247
 
248
248
  // ============ BEGIN: SET EXTERNAL PARAMETERS ==============//
249
249
  this.baseLocation = 'https://widget.tiledesk.com/v2';
250
- this.autoStart = false;
250
+ this.autoStart = true;
251
251
  /** start Authentication and startUI */
252
252
  this.startHidden = false;
253
253
  /** show/hide all widget -> js call: showAllWidget */
@@ -96,6 +96,5 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji not allowed",
97
97
  "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
98
98
  "MAX_ATTACHMENT": "Max allowed size {{FILE_SIZE_LIMIT}}Mb",
99
- "MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
100
99
  "EMOJI": "Emoji"
101
100
  }
@@ -96,6 +96,5 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji no permitido",
97
97
  "DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
98
98
  "MAX_ATTACHMENT": "Tamaño máximo permitido {{FILE_SIZE_LIMIT}}Mb",
99
- "MAX_ATTACHMENT_ERROR": "El archivo supera el tamaño máximo permitido",
100
99
  "EMOJI": "Emoji"
101
100
  }
@@ -96,6 +96,5 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji non autorisé",
97
97
  "DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
98
98
  "MAX_ATTACHMENT": "Taille maximale autorisée {{FILE_SIZE_LIMIT}}Mo",
99
- "MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
100
99
  "EMOJI": "Emoji"
101
100
  }
@@ -94,6 +94,5 @@
94
94
  "EMOJI_NOT_ELLOWED":"Emoji non consentiti",
95
95
  "DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
96
96
  "MAX_ATTACHMENT": "Dimensione massima consentita {{FILE_SIZE_LIMIT}}Mb",
97
- "MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
98
97
  "EMOJI": "Emoji"
99
98
  }
@@ -27,7 +27,7 @@ export abstract class UploadService {
27
27
  abstract BSStateUpload: BehaviorSubject<any>;
28
28
 
29
29
  // functions
30
- abstract initialize(projectId: string): void;
30
+ abstract initialize(): void;
31
31
  abstract upload(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}>;
32
32
  abstract uploadProfile(userId: string, upload: UploadModel): Promise<any>;
33
33
  abstract delete(userId: string, path: string): Promise<any>;
@@ -31,7 +31,7 @@ export class FirebaseUploadService extends UploadService {
31
31
  super();
32
32
  }
33
33
 
34
- public async initialize(projectId: string) {
34
+ public async initialize() {
35
35
  this.logger.debug('[FIREBASEUploadSERVICE] initialize');
36
36
 
37
37
  const { default: firebase} = await import("firebase/app");
@@ -16,7 +16,7 @@ export class NativeImageRepoService extends ImageRepoService {
16
16
  * @param uid
17
17
  */
18
18
  getImagePhotoUrl(uid: string): string {
19
- this.baseImageURL = this.getImageBaseUrl() + 'files'
19
+ this.baseImageURL = this.getImageBaseUrl() + 'images'
20
20
  let sender_id = '';
21
21
  if (uid.includes('bot_')) {
22
22
  sender_id = uid.slice(4)
@@ -1,7 +1,7 @@
1
1
  import { UploadService } from '../abstract/upload.service';
2
2
  import { HttpClient, HttpHeaders } from '@angular/common/http';
3
3
  import { Injectable } from '@angular/core';
4
- import { BehaviorSubject, first } from 'rxjs';
4
+ import { BehaviorSubject } from 'rxjs';
5
5
  import { UploadModel } from '../../models/upload';
6
6
  import { AppStorageService } from '../abstract/app-storage.service';
7
7
  import { LoggerService } from '../abstract/logger.service';
@@ -14,6 +14,7 @@ export class NativeUploadService extends UploadService {
14
14
  BSStateUpload: BehaviorSubject<any> = new BehaviorSubject<any>(null)
15
15
 
16
16
  private tiledeskToken: string;
17
+ private URL_TILEDESK_IMAGES: string;
17
18
  private URL_TILEDESK_FILE: string;
18
19
  private logger: LoggerService = LoggerInstance.getInstance()
19
20
 
@@ -24,15 +25,16 @@ export class NativeUploadService extends UploadService {
24
25
  super();
25
26
  }
26
27
 
27
- initialize(projectId: string): void {
28
- this.logger.info('[NATIVE UPLOAD] initialize', this.getBaseUrl())
29
- this.URL_TILEDESK_FILE = this.getBaseUrl() + projectId + '/files'
28
+ initialize(): void {
29
+ this.logger.debug('[NATIVE UPLOAD] initialize')
30
+ this.URL_TILEDESK_FILE = this.getBaseUrl() + 'files'
31
+ this.URL_TILEDESK_IMAGES = this.getBaseUrl() + 'images'
30
32
  this.tiledeskToken = this.appStorage.getItem('tiledeskToken')
31
33
  }
32
34
 
33
35
 
34
36
  upload(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}> {
35
- this.logger.log('[NATIVE UPLOAD] - upload new image/file ... upload', upload)
37
+ this.logger.debug('[NATIVE UPLOAD] - upload new image/file ... upload', upload)
36
38
  const headers = new HttpHeaders({
37
39
  Authorization: this.tiledeskToken,
38
40
  //'Content-Type': 'multipart/form-data',
@@ -42,49 +44,35 @@ export class NativeUploadService extends UploadService {
42
44
  formData.append('file', upload.file);
43
45
 
44
46
  const that = this;
45
- const url = this.URL_TILEDESK_FILE + '/chat'
46
- return new Promise((resolve, reject) => {
47
- that.http.post(url, formData, requestOptions).pipe(first()).subscribe({
48
- next: (data) => {
49
- const downloadURL = this.getBaseUrl() + 'files' + '?path=' + data['filename'];
47
+ if ((upload.file.type.startsWith('image') && (!upload.file.type.includes('svg')))) {
48
+ this.logger.debug('[NATIVE UPLOAD] - upload new image')
49
+ //USE IMAGE API
50
+ const url = this.URL_TILEDESK_IMAGES + '/users'
51
+ return new Promise((resolve, reject) => {
52
+ that.http.post(url, formData, requestOptions).subscribe(data => {
53
+ const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
50
54
  resolve({downloadURL : downloadURL, src: downloadURL})
51
- },
52
- error: (error) => {
55
+ // that.BSStateUpload.next({upload: upload});
56
+ }, (error) => {
53
57
  reject(error)
54
- }
58
+ });
55
59
  });
56
- });
57
-
58
- //old_implemenation
59
- // if ((upload.file.type.startsWith('image') && (!upload.file.type.includes('svg')))) {
60
- // this.logger.log('[NATIVE UPLOAD] - upload new image', this.URL_TILEDESK_IMAGES)
61
- // //USE IMAGE API
62
- // const url = this.URL_TILEDESK_IMAGES + '/users'
63
- // return new Promise((resolve, reject) => {
64
- // that.http.post(url, formData, requestOptions).subscribe(data => {
65
- // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
66
- // resolve({downloadURL : downloadURL, src: downloadURL})
67
- // // that.BSStateUpload.next({upload: upload});
68
- // }, (error) => {
69
- // reject(error)
70
- // });
71
- // });
72
- // } else {
73
- // this.logger.log('[NATIVE UPLOAD] - upload new file', this.URL_TILEDESK_FILE)
74
- // //USE FILE API
75
- // const url = this.URL_TILEDESK_FILE + '/users'
76
- // return new Promise((resolve, reject) => {
77
- // that.http.post(url, formData, requestOptions).subscribe(data => {
78
- // const src = this.URL_TILEDESK_FILE + '?path=' + encodeURI(data['filename']);
79
- // const downloadURL = this.URL_TILEDESK_FILE + '/download' + '?path=' + encodeURI(data['filename']);
80
- // resolve({downloadURL : downloadURL, src: src})
81
- // // that.BSStateUpload.next({upload: upload});
82
- // }, (error) => {
83
- // this.logger.error('[NATIVE UPLOAD] - ERROR upload new file ', error)
84
- // reject(error)
85
- // });
86
- // });
87
- // }
60
+ } else {
61
+ this.logger.debug('[NATIVE UPLOAD] - upload new file')
62
+ //USE FILE API
63
+ const url = this.URL_TILEDESK_FILE + '/users'
64
+ return new Promise((resolve, reject) => {
65
+ that.http.post(url, formData, requestOptions).subscribe(data => {
66
+ const src = this.URL_TILEDESK_FILE + '?path=' + encodeURI(data['filename']);
67
+ const downloadURL = this.URL_TILEDESK_FILE + '/download' + '?path=' + encodeURI(data['filename']);
68
+ resolve({downloadURL : downloadURL, src: src})
69
+ // that.BSStateUpload.next({upload: upload});
70
+ }, (error) => {
71
+ this.logger.error('[NATIVE UPLOAD] - ERROR upload new file ', error)
72
+ reject(error)
73
+ });
74
+ });
75
+ }
88
76
 
89
77
  }
90
78
 
@@ -100,18 +88,14 @@ export class NativeUploadService extends UploadService {
100
88
 
101
89
  // USE IMAGE API
102
90
  const that = this;
103
- const botId = userId?.startsWith('bot_') ? userId.substring('bot_'.length) : userId
104
- const url = this.URL_TILEDESK_FILE + `/users/photo?bot_id=${botId}`
91
+ const url = this.URL_TILEDESK_IMAGES + `/users/photo?force=true&user_id=${userId}`
105
92
  return new Promise((resolve, reject) => {
106
- that.http.put(url, formData, requestOptions).pipe(first()).subscribe({
107
- next: (data) => {
108
- const downloadURL = this.getBaseUrl() + 'files?path=' + data['thumbnail'];
109
- resolve(downloadURL)
110
- // that.BSStateUpload.next({upload: upload});
111
- },
112
- error: (error) => {
113
- reject(error)
114
- }
93
+ that.http.put(url, formData, requestOptions).subscribe(data => {
94
+ const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['thumbnail'];
95
+ resolve(downloadURL)
96
+ // that.BSStateUpload.next({upload: upload});
97
+ }, (error) => {
98
+ reject(error)
115
99
  });
116
100
  });
117
101
  }
@@ -126,17 +110,14 @@ export class NativeUploadService extends UploadService {
126
110
 
127
111
  //USE IMAGE API
128
112
  const that = this;
129
- const url = this.URL_TILEDESK_FILE + '?path=' + path.split('path=')[1]
113
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + path.split('path=')[1]
130
114
  return new Promise((resolve, reject) => {
131
- that.http.delete(url, requestOptions).pipe(first()).subscribe({
132
- next: (data) => {
133
- // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
134
- resolve(true)
135
- // that.BSStateUpload.next({upload: upload});
136
- },
137
- error: (error) => {
138
- reject(error)
139
- }
115
+ that.http.delete(url, requestOptions).subscribe(data => {
116
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
117
+ resolve(true)
118
+ // that.BSStateUpload.next({upload: upload});
119
+ }, (error) => {
120
+ reject(error)
140
121
  });
141
122
  });
142
123
  }
@@ -151,17 +132,14 @@ export class NativeUploadService extends UploadService {
151
132
 
152
133
  //USE IMAGE API
153
134
  const that = this;
154
- const url = this.URL_TILEDESK_FILE + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
135
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
155
136
  return new Promise((resolve, reject) => {
156
- that.http.delete(url, requestOptions).pipe(first()).subscribe({
157
- next: (data) => {
158
- // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
159
- resolve(true)
160
- // that.BSStateUpload.next({upload: upload});
161
- },
162
- error: (error) => {
163
- reject(error)
164
- }
137
+ that.http.delete(url, requestOptions).subscribe(data => {
138
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
139
+ resolve(true)
140
+ // that.BSStateUpload.next({upload: upload});
141
+ }, (error) => {
142
+ reject(error)
165
143
  });
166
144
  });
167
145
  }
@@ -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({
@@ -773,11 +773,6 @@ export function isAllowedUrlInText(text: string, allowedUrls: string[]) {
773
773
  return nonWhitelistedDomains.length === 0;
774
774
  }
775
775
 
776
- // function extractUrls(text: string): string[] {
777
- // const urlRegex = /https?:\/\/[^\s]+/g;
778
- // return text.match(urlRegex) || [];
779
- // }
780
-
781
776
  function extractUrls(text: string): string[] {
782
777
  // Rileva URL con o senza protocollo (http/https)
783
778
  const urlRegex = /\b((https?:\/\/)?(www\.)?[a-z0-9.-]+\.[a-z]{2,})(\/[^\s]*)?/gi;
@@ -792,3 +787,5 @@ function extractUrls(text: string): string[] {
792
787
  }
793
788
 
794
789
 
790
+
791
+
@@ -13,7 +13,7 @@
13
13
  bottom: 0px;
14
14
  width: auto;
15
15
  height: auto;
16
- display: block;
16
+ display: none;
17
17
  z-index: 3000000000; /*999999*/;
18
18
  }
19
19
 
@@ -84,12 +84,12 @@
84
84
  max-width: 1024px;
85
85
  max-height: 100%;
86
86
 
87
- /* transition:
87
+ transition:
88
88
  width 300ms,
89
89
  height 300ms,
90
90
  max-height 300ms,
91
91
  transform 300ms cubic-bezier(0, 1.2, 1, 1),
92
- opacity 300ms ease-out; */
92
+ opacity 300ms ease-out;
93
93
  /* per migliorare le prestazioni quando si usa transform */
94
94
  will-change: transform, opacity, width, height;
95
95
  }
@@ -175,14 +175,14 @@
175
175
  }
176
176
 
177
177
  #tiledesk-container.open #tiledeskdiv.min-size {
178
- /* transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out; */
178
+ transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out;
179
179
  width: var(--iframeMinWidth);
180
180
  height: var(--iframeMinHeight);
181
181
  }
182
182
 
183
183
  #tiledesk-container.open #tiledeskdiv.max-size {
184
184
  /* transition: width 1s, height 1s; */
185
- /* transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out; */
185
+ transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out;
186
186
  width: var(--iframeMaxWidth);
187
187
  height: var(--iframeMaxHeight);
188
188
  }