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

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 (28) 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 +24 -87
  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 +41 -0
  8. package/docs/changelog/this-branch.md +35 -24
  9. package/package.json +1 -1
  10. package/src/app/app.component.ts +9 -11
  11. package/src/app/component/conversation-detail/conversation/conversation.component.html +1 -3
  12. package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -2
  13. package/src/app/component/conversation-detail/conversation/conversation.component.ts +5 -26
  14. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -1
  15. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +80 -103
  16. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +13 -40
  17. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +0 -7
  18. package/src/app/component/last-message/last-message.component.ts +1 -4
  19. package/src/app/providers/global-settings.service.ts +0 -11
  20. package/src/app/providers/translator.service.ts +0 -2
  21. package/src/app/sass/_variables.scss +0 -1
  22. package/src/app/utils/globals.ts +1 -4
  23. package/src/assets/i18n/en.json +0 -1
  24. package/src/assets/i18n/es.json +0 -1
  25. package/src/assets/i18n/fr.json +0 -1
  26. package/src/assets/i18n/it.json +0 -1
  27. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  28. package/src/chat21-core/utils/utils.ts +2 -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,63 +6,50 @@
6
6
  ### **Copyrigth**:
7
7
  *Tiledesk SRL*
8
8
 
9
- # 5.1.30-rc1
9
+ # 5.1.30
10
10
  - **bug fixed**: startHidden is not working properly
11
11
 
12
- # 5.1.27-rc3
12
+ # 5.1.28
13
+ - **bug fixed**: header option menu is deactivated on mobile
14
+
15
+ # 5.1.28
13
16
  - **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
14
17
 
15
- # 5.1.27-rc2
18
+ # 5.1.27
16
19
  - **bug fixed**: centralized fullscreen management on mobile and handled the case of the closed widget that remained fullscreen
17
-
18
- # 5.1.27-rc1
19
- - **added**: closeChatInConversation parameters
20
- - **added**: close chat button under textarea footer component
21
-
22
- # 5.1.26-rc6
20
+ - **changed**: start with authentication if hasCalloutInWidgetConfig is true
21
+ - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
22
+ - **changed**: Set the default autoStart value to false
23
+ - **added**: Added the open widget loading spinner
24
+ - **changed**: Load the widget without authentication and display the speech bubble
23
25
  - **changed**: mobile always opens fullscreen and ignores legacy stored size”.
24
26
  - **changed**: changed user-typing
25
-
26
- # 5.1.26-rc5
27
27
  - **changed**: Hide the resize-widget button when on mobile
28
28
  - **added**: added "I'm thinking" when the bot responds
29
29
 
30
- # 5.1.26-rc4
31
- - **changed**: decoupled callout from signin
32
-
33
- # 5.1.26-rc3
34
- - **changed**: start with authentication if a proactive message has been set, so if a rule has been set on at one chatbot in the project
35
-
36
- # 5.1.26-rc2
37
- - **changed**: start with authentication if hasCalloutInWidgetConfig is true
30
+ # 5.1.26
31
+ - **bug fixed**: attachment buttons text alignment
38
32
 
39
- # 5.1.26-rc1
40
- - **bug fixed**: improved audio recording/upload flow by ignoring empty recorder chunks, preserving the recorder MIME type when creating the audio blob/file, and uploading audio directly without Base64 conversion
41
-
42
-
43
- # 5.1.25-rc1
33
+ # 5.1.25
44
34
  - **bug fixed**: attachment buttons in messages now respect the container max width and wrap/break long labels instead of being clipped
45
35
 
46
- # 5.1.24-rc2
47
- - **bug fixed**: minor fix in marked pipe to avoid rendering html tags
48
-
49
- # 5.1.24-rc1
36
+ # 5.1.24
50
37
  - **security**: hardened Markdown link rendering by blocking dangerous protocols (e.g. `javascript:`, `data:`, `vbscript:`) and preventing unsafe links from being rendered as anchors
51
38
  - **changed**: refactored `MarkedPipe` to simplify Markdown parsing, improve link rendering via a custom `marked` renderer, and streamline newline handling (`\\n` → `\n`)
52
39
 
53
- # 5.1.20-rc3
40
+ # 5.1.23
41
+ - **changed**: API for upload a file/iamges
42
+
43
+ # 5.1.22
44
+ - **changed**: Updated Launch.js for Wix and Shopify by bypassing scrdoc
45
+
46
+ # 5.1.21
54
47
  - **bug fixed**: saved the widget's size state to local storage (in HP conversations)
55
48
 
56
- # 5.1.20-rc2
57
- - **changed**: API for upload a file/iamges
49
+ # 5.1.20
58
50
  - **changed**: marked pipe do not render /n
59
51
 
60
- # 5.1.20-rc1
61
- - **changed**: API for upload a file/iamges
62
-
63
52
  # 5.1.19
64
-
65
- # 5.1.19-rc1
66
53
  - **bug fixed**: show bottom scroll button and unread message badge only when I'm not at the bottom of the page
67
54
  - **changed**: allow HTML code to be inserted into messages, but do not parse the code. Ensure coexistence with Markdown.
68
55
  - **bug fixed**: after sending a multi-line message, the text area remains open on multiple lines.
@@ -72,7 +59,6 @@
72
59
  - **changed**: saved the widget's size state to local storage. The parameter flow is (default → storage → settings → URL)
73
60
 
74
61
  # 5.1.18
75
- # 5.1.15-rc3
76
62
  - **added**: Implemented Shadow DOM in the text component to isolate HTML and Markdown rendering in a safe and protected context
77
63
  - **changed**: Adapted text component styles to support Shadow DOM (removed ::ng-deep, added styles for common markdown elements)
78
64
  - **security**: HTML/Markdown content is now rendered in an isolated Shadow DOM, improving security and preventing interference with the rest of the application
@@ -83,12 +69,6 @@
83
69
  # 5.1.16
84
70
  - **changed**: "close chat" header conversation menu button enabled in chatbot-panel.html
85
71
 
86
- # 5.1.15-rc2
87
- - **bug-fixed**: Bug fix for ifame message width
88
-
89
- # 5.1.15-rc1
90
- - **changed**: Load local translations before remote ones
91
-
92
72
  # 5.1.15
93
73
  - **changed**: Load local translations before remote ones
94
74
 
@@ -97,57 +77,14 @@
97
77
 
98
78
  # 5.1.13
99
79
  - **bug-fixed**: set default widget size
100
-
101
- # 5.1.7-rc16
102
- - **bug-fixed**: set default widget size
103
-
104
- # 5.1.7-rc15
105
- - **bug-fixed**: set the color of the buttons with visibility control to the font color
106
-
107
- # 5.1.7-rc14
108
- - **bug-fixed**: departmentId and departmentName is incorrect in attributes
109
-
110
- # 5.1.7-rc13
111
- - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
112
-
113
- # 5.1.7-rc12
114
- - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
115
- - **changed**: Set the default autoStart value to false
116
- - **added**: Added the open widget loading spinner
117
- - **changed**: Load the widget without authentication and display the speech bubble
118
-
119
- # 5.1.7-rc11
120
- - **changed**: set default value autoStart false
121
- - **added**:added loading spinner
122
-
123
- # 5.1.7-rc10
124
- - **changed**: load widget without authentication and display the balloon
125
-
126
- # 5.1.7-rc9
127
- - **removed**: 'DOMAIN_NOT_ALLOWED' in textarea footer component
128
-
129
- # 5.1.7-rc8
130
- # changes in the branch
131
- - **changed**: Load local translations before remote ones
132
- - **bug-fixed**: set default widget size
133
80
  - **changed**: Updated the translations of the tooltips in the footer-component
134
81
  - **changed**: Refactored the network-offline component and made it generic for displaying errors (now error-alert.component)
135
-
136
- # 5.1.7-rc7
137
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
138
-
139
- # 5.1.7-rc6
140
- - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
82
+ - **bug-fixed**: set the color of the buttons with visibility control to the font color (setButtonColors function)
141
83
 
142
84
  # 5.1.12
143
85
  - **bug-fixed**: check showEmojiFooterButton to enable/disable emojii
144
86
  - **bug-fixed**: markdown is fired as an emojii and blocked by isEmojii check fn
145
87
 
146
- # 5.1.7-rc7
147
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
148
-
149
- # 5.1.7-rc6
150
- - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
151
88
 
152
89
  # 5.1.7-rc5
153
90
  - **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
@@ -0,0 +1,41 @@
1
+ # npm version patch
2
+ version=`node -e 'console.log(require("./package.json").version)'`
3
+ echo "version $version"
4
+
5
+ npm i
6
+
7
+ cp src/environments/real_data/environment.prod.ts src/environments/environment.prod.ts
8
+
9
+ # --build-optimizer=false if localstorage is disabled (webview) appears https://github.com/firebase/angularfire/issues/970
10
+ ng build --configuration="prod" --aot=true
11
+ ##--base-href='./v5/' --output-hashing none
12
+
13
+ ### SET HASHING : START ###
14
+ cp ./src/launch_template.js ./dist/browser/launch.js
15
+ node ./src/build_launch.js
16
+ ### SET HASHING : END ###
17
+
18
+ #### FIREBASE #####
19
+ # cd dist
20
+ # # aws s3 sync . s3://tiledesk-widget/v5/latest/
21
+ # aws s3 sync . s3://tiledesk-widget/v5/$version/ --cache-control max-age=300
22
+ # aws s3 sync . s3://tiledesk-widget/v5/ --cache-control max-age=300
23
+ # cd ..
24
+
25
+ # #### MQTT #####
26
+ cd dist/browser
27
+ # aws s3 sync . s3://tiledesk-widget/v5/latest/
28
+ aws s3 sync . s3://tiledesk-widget/v6/$version/ --cache-control max-age=86400 --exclude='launch.js' #8days
29
+ aws s3 sync . s3://tiledesk-widget/v6/$version/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
30
+ aws s3 sync . s3://tiledesk-widget/v6/ --cache-control max-age=86400 --exclude='launch.js' #8days
31
+ aws s3 sync . s3://tiledesk-widget/v6/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
32
+ cd ../..
33
+
34
+ aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*"
35
+
36
+ git restore src/environments/environment.prod.ts
37
+
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
@@ -1,36 +1,47 @@
1
- # This branch: identificazione bot o umano
1
+ # Questo branch: UX bot/umano + disaccoppiamento callout
2
2
 
3
- ## Obiettivo
3
+ ## Contesto
4
4
 
5
- In questo branch e' stata introdotta una logica esplicita per capire, all'apertura della conversazione, se l'ultimo responder lato server e' un **bot** oppure un **umano**.
5
+ Questo branch migliora il feedback in conversazione e rende il comportamento del callout indipendente dal sign-in del widget.
6
6
 
7
- ## Come viene fatta l'identificazione
7
+ ## Modifiche incluse
8
8
 
9
- - La valutazione parte dai messaggi gia' caricati in conversazione.
10
- - Viene cercato l'**ultimo messaggio ricevuto dal server** (non inviato dal client corrente).
11
- - Quel messaggio viene classificato con una funzione dedicata (`classifyMessageSenderKind`) che usa piu' segnali:
12
- - `attributes.flowAttributes.chatbot_id` (quando presente indica bot)
13
- - pattern del mittente (es. `senderId` con prefisso bot, quando applicabile)
14
- - informazioni del mittente (`sender_fullname` e metadati associati)
9
+ - Aggiunto un **badge Bot/Umano** nella vista conversazione.
10
+ - All'apertura della conversazione analizza **l'ultimo messaggio ricevuto dal server** (escludendo quelli inviati dal client).
11
+ - Classifica il mittente come `Bot` o `Umano`.
12
+ - Regola speciale: se l'ultimo evento di sistema rilevante e' `MEMBER_JOINED_GROUP` (handoff verso operatore), la conversazione viene classificata come **Umano**.
15
13
 
16
- ## Regola speciale per messaggi di sistema
14
+ - Aggiunto il feedback temporaneo **"sto pensando..."** dopo l'invio del messaggio da parte del client.
15
+ - Mostrato solo quando la conversazione e' classificata come **Bot**.
16
+ - Nascosto alla prima risposta server, con durata minima visibile di 5 secondi.
17
17
 
18
- Se l'ultimo messaggio utile e' di tipo `system`, viene fatto un controllo aggiuntivo:
18
+ - Rimossa l'implementazione temporanea del toast "ciao" nel footer e relativo wiring.
19
19
 
20
- - se in `attributes` e' presente un evento con `messagelabel.key = MEMBER_JOINED_GROUP`
21
- - e rappresenta il passaggio della conversazione a un operatore
20
+ - Abilitato il percorso di avvio widget per i casi guidati da bot quando sono presenti `botsRules`.
22
21
 
23
- allora la conversazione viene forzata a **Umano** anche se altri indizi potrebbero suggerire bot.
22
+ ## Disaccoppiamento callout (step completati)
24
23
 
25
- ## Risultato in UI
24
+ - **Step 1**: rimossa la dipendenza da `g.senderId` nel rendering del componente callout in `app.component.html`.
25
+ - Prima: render solo con `g.senderId && !g.isOpenNewMessage`
26
+ - Dopo: render con `!g.isOpenNewMessage`
26
27
 
27
- - In apertura conversazione viene mostrato un badge con stato:
28
- - `Bot`
29
- - `Umano`
30
- - Questo stato viene ricalcolato al variare dei messaggi ricevuti.
28
+ - **Step 2**: scheduling del callout al caricamento delle impostazioni widget in `AppComponent`.
29
+ - Aggiunto `scheduleCalloutFromSettings()` basato su `g.calloutTimer`.
30
+ - Invocato subito dopo la disponibilita' delle settings (non legato al login).
31
+ - Aggiunta la pulizia del timeout in `ngOnDestroy()`.
31
32
 
32
- ## Effetto sui feedback utente
33
+ - **Step 3**: introdotte precedenze UI e rimossa la duplicazione dello scheduling callout.
34
+ - Aggiunta guardia `canShowCalloutNow()` in `AppComponent`:
35
+ - widget chiuso
36
+ - nessuna preview nuovo messaggio attiva
37
+ - stato callout abilitato
38
+ - callout presente nella configurazione widget
39
+ - Aggiornato `showCallout()` per aprire il callout solo quando le guardie passano e il componente esiste.
40
+ - Rimosso il timer interno (`openIfCallOutTimer`) da `EyeeyeCatcherCardComponent` per evitare doppi trigger.
33
41
 
34
- - Il messaggio temporaneo `"sto pensando..."` viene mostrato solo quando la conversazione risulta di tipo **Bot**.
35
- - Alla ricezione della prima risposta dal server, `"sto pensando..."` viene nascosto **immediatamente**.
36
- - Non e' previsto alcun tempo minimo di visualizzazione del messaggio.
42
+ ## Comportamento atteso dopo questo branch
43
+
44
+ - Il callout puo' essere innescato da configurazione anche senza sign-in.
45
+ - Il callout non compare quando il widget e' aperto o quando la preview nuovo messaggio e' attiva.
46
+ - La UI della conversazione indica chiaramente se l'ultimo responder e' bot o umano.
47
+ - "Sto pensando..." compare solo nelle conversazioni bot e ha un comportamento prevedibile.
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.30-rc1",
4
+ "version": "5.1.30",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -106,17 +106,18 @@ 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
- private calloutScheduleTimeout: any = null;
113
-
114
109
  // alert error message
115
110
  isShowErrorMessage: boolean = false;
116
111
  errorMessage: string = '';
117
112
  errorKeyMessage: string = null;
118
113
  errorParams: Record<string, any> = {};
119
114
 
115
+ //network status
116
+ isOnline: boolean = true;
117
+
118
+ loading: boolean = false;
119
+ private calloutScheduleTimeout: any = null;
120
+
120
121
  private logger: LoggerService = LoggerInstance.getInstance();
121
122
  constructor(
122
123
  private el: ElementRef,
@@ -169,13 +170,13 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
169
170
  if (conversation.attributes && conversation.attributes['subtype'] === 'info') {
170
171
  return;
171
172
  }
172
- if (conversation.is_new && that.isInitialized) {
173
+ if (conversation.is_new && this.isInitialized) {
173
174
  that.manageTabNotification(false, 'conv-added')
174
175
  // this.soundMessage();
175
176
  }
176
- if(this.g.isOpen === false && conversation.sender !== this.g.senderId && !isInfo(conversation)){
177
- that.g.isOpenNewMessage = true;
177
+ if(this.g.isOpen === false){
178
178
  that.lastConversation = conversation;
179
+ that.g.isOpenNewMessage = true;
179
180
  }
180
181
  } else {
181
182
  //widget closed
@@ -223,7 +224,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
223
224
  that.lastConversation = conversation;
224
225
  that.g.isOpenNewMessage = true;
225
226
  that.logger.debug('[APP-COMP] lastconversationnn', that.lastConversation)
226
- that.logger.debug('[APP-COMP] lastconversationnn message' + JSON.stringify(that.lastConversation?.attributes?.commands))
227
227
  }
228
228
  let badgeNewConverstionNumber = that.conversationsHandlerService.countIsNew()
229
229
  that.g.setParameter('conversationsBadge', badgeNewConverstionNumber);
@@ -526,7 +526,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
526
526
  this.g.onPageChangeVisibilityMobile === 'open' ||
527
527
  (Array.isArray(this.g.botsRules) && this.g.botsRules.length > 0)
528
528
  // || this.g.hasCalloutInWidgetConfig;
529
- console.log('[APP-COMP] shouldAutoAuthenticate', shouldAutoAuthenticate, startHidden)
530
529
  if (shouldAutoAuthenticate) {
531
530
  that.authenticate();
532
531
  if(startHidden){ that.hideWidget(); }
@@ -2320,7 +2319,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
2320
2319
  this.el.nativeElement.style.setProperty('--chat-header-height', this.g.hideHeaderConversation? '0px': null)
2321
2320
  this.el.nativeElement.style.setProperty('--font-size-bubble-message', this.g.fontSize)
2322
2321
  this.el.nativeElement.style.setProperty('--font-family-bubble-message', this.g.fontFamily)
2323
- this.el.nativeElement.style.setProperty('--chat-footer-close-button-height', this.g.closeChatInConversation? '30px': '0px')
2324
2322
 
2325
2323
  }
2326
2324
 
@@ -137,7 +137,6 @@
137
137
  [isMobile]="g?.isMobile"
138
138
  [isEmojiiPickerShow]="isEmojiiPickerShow"
139
139
  [footerMessagePlaceholder]="footerMessagePlaceholder"
140
- [closeChatInConversation]="g?.closeChatInConversation"
141
140
  [fileUploadAccept]="g?.fileUploadAccept"
142
141
  [dropEvent]="dropEvent"
143
142
  [poweredBy]="g?.poweredBy"
@@ -148,8 +147,7 @@
148
147
  (onAfterSendMessage)="onAfterSendMessageFN($event)"
149
148
  (onChangeTextArea)="onChangeTextArea($event)"
150
149
  (onAttachmentFileButtonClicked)="onAttachmentFileButtonClicked($event)"
151
- (onNewConversationButtonClicked)="onNewConversationButtonClickedFN($event)"
152
- (onCloseChatButtonClicked)="onCloseChatButtonClickedFN($event)">
150
+ (onNewConversationButtonClicked)="onNewConversationButtonClickedFN($event)">
153
151
  </chat-conversation-footer>
154
152
 
155
153
  </div>
@@ -137,7 +137,7 @@
137
137
  #dropZone_container{
138
138
  position: absolute;
139
139
  top: 52px;
140
- bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height));
140
+ bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height));
141
141
  left: 0;
142
142
  right: 0;
143
143
  background-color: rgba(240,248,255,0.6);
@@ -240,7 +240,7 @@ dialog:-internal-dialog-in-top-layer{
240
240
 
241
241
 
242
242
  ::ng-deep .chat21-sheet-content{
243
- bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height) + 34px)!important;
243
+ bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + 34px)!important;
244
244
  }
245
245
 
246
246
  }
@@ -246,8 +246,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
246
246
  'CONTINUE',
247
247
  'EMOJI_NOT_ELLOWED',
248
248
  'ATTACHMENT',
249
- 'EMOJI',
250
- 'CLOSE_CHAT'
249
+ 'EMOJI'
251
250
  ];
252
251
 
253
252
  const keysContent = [
@@ -502,7 +501,7 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
502
501
  return this.isConversationArchived;
503
502
  }
504
503
 
505
- // //FALLBACK TO TILEDESK
504
+ //FALLBACK TO TILEDESK
506
505
  const requests_list = await this.tiledeskRequestService.getMyRequests().catch(err => {
507
506
  this.logger.error('[CONV-COMP] getConversationDetail: error getting request from Tiledesk', err);
508
507
  this.isConversationArchived=true
@@ -520,9 +519,9 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
520
519
  return this.isConversationArchived
521
520
  }
522
521
 
523
- this.isConversationArchived = false;
524
- return null;
525
- }
522
+ this.isConversationArchived = true;
523
+ return null;
524
+ }
526
525
 
527
526
  /**
528
527
  * this.g.recipientId:
@@ -878,20 +877,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
878
877
  this.subscriptions.push(subscribe);
879
878
  }
880
879
 
881
- subscribtionKey = 'conversationsAdded';
882
- subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
883
- if(!subscribtion){
884
-
885
- subscribtion = this.chatManager.conversationsHandlerService.conversationChanged.pipe(takeUntil(this.unsubscribe$)).subscribe((conversation) => {
886
- this.logger.debug('[CONV-COMP] ***** DATAIL conversationsChanged *****', conversation, this.conversationWith, this.isConversationArchived);
887
- if(conversation && conversation.recipient === this.conversationId){
888
- this.isConversationArchived = false
889
- }
890
- });
891
- const subscribe = {key: subscribtionKey, value: subscribtion };
892
- this.subscriptions.push(subscribe);
893
- }
894
-
895
880
  subscribtionKey = 'messageWait';
896
881
  subscribtion = this.subscriptions.find(item => item.key === subscribtionKey);
897
882
  if (!subscribtion) {
@@ -1398,12 +1383,6 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
1398
1383
  this.logger.debug('[CONV-COMP] floating onNewConversationButtonClicked')
1399
1384
  this.onNewConversationButtonClicked.emit()
1400
1385
  }
1401
-
1402
- /** CALLED BY: conv-footer component */
1403
- onCloseChatButtonClickedFN(event){
1404
- this.logger.debug('[CONV-COMP] onCloseChatButtonClicked::::', event)
1405
- this.onCloseChat()
1406
- }
1407
1386
  // =========== END: event emitter function ====== //
1408
1387
 
1409
1388
 
@@ -44,7 +44,7 @@
44
44
  top: 0;
45
45
  right: 0;
46
46
  left: 0;
47
- bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height));
47
+ bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height));
48
48
  overflow: hidden;
49
49
  .time{
50
50
  margin-bottom: 20px;
@@ -14,117 +14,94 @@
14
14
 
15
15
  </div>
16
16
 
17
- <div class="textarea-container-wrapper" *ngIf="!hideTextAreaContent && !hideTextReply">
18
- <!-- TEXTAREA + ICONS: conv active-->
19
- <div class="textarea-container">
20
-
21
- <div *ngIf="!isStopRec" class="icons-container">
22
- <!-- ICON ATTACHMENT -->
23
- <label *ngIf="showAttachmentFooterButton" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
24
- <span class="v-align-center">
25
- <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
26
- <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"/>
27
- <title id="altIconTitle">{{ 'MAX_ATTACHMENT' | translate: { FILE_SIZE_LIMIT: file_size_limit } }}</title>
28
- </svg>
29
-
30
- </span>
31
- <input
32
- [attr.disabled] = "(isFilePendingToUpload || isConversationArchived || hideTextReply)? true : null"
33
- tabindex="1503"
34
- type="file"
35
- aria-label="seleziona allegato"
36
- [accept]="fileUploadAccept"
37
- name="chat21-file"
38
- id="chat21-file"
39
- #chat21_file
40
- class="inputfile"
41
- [ngStyle]="{'display': 'block', height:'1px', width:'1px', overflow: 'hidden' }"
42
- (change)="detectFiles($event)"/>
43
- </label>
44
- <!-- ICON EMOJII -->
45
- <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()">
46
- <span class="v-align-center">
47
- <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
48
- <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"/>
49
- <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"/>
50
- <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"/>
51
- <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"/>
52
- <title id="altIconTitle">{{ translationMap?.get('EMOJI') }}</title>
53
-
54
- <!-- <path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
55
- <circle cx="15.02" cy="9.86" r="1.29"/>
56
- <circle cx="9.02" cy="9.86" r="1.29"/>
57
- <path d="M12.02,15.43c-1.27,0-2.36-.69-2.96-1.71h-1.43c.69,1.76,2.39,3,4.39,3s3.7-1.24,4.39-3h-1.43c-.6,1.02-1.69,1.71-2.96,1.71Zm0-12C7.28,3.43,3.45,7.27,3.45,12s3.83,8.57,8.56,8.57,8.58-3.84,8.58-8.57S16.75,3.43,12.01,3.43Zm0,15.43c-3.79,0-6.86-3.07-6.86-6.86s3.07-6.86,6.86-6.86,6.86,3.07,6.86,6.86-3.07,6.86-6.86,6.86Z"/> -->
58
- </svg>
59
- </span>
60
- </label>
61
- </div>
17
+ <!-- TEXTAREA + ICONS: conv active-->
18
+ <div class="textarea-container" *ngIf="!hideTextAreaContent && !hideTextReply">
19
+
20
+ <div *ngIf="!isStopRec" class="icons-container">
21
+ <!-- ICON ATTACHMENT -->
22
+ <label *ngIf="showAttachmentFooterButton" tabindex="1502" aria-label="allegati" for="chat21-file" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-start-upload-doc">
23
+ <span class="v-align-center">
24
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" width="24px" height="24" viewBox="0 0 24 24" fill="currentColor">
25
+ <path d="M9.9,22.7c0,0-.1,0-.2,0-1.9.3-3.7-.2-5.2-1.4-3-2.3-3.6-6.4-1.4-9.5L9.5,2.5c.4-.5,1.1-.6,1.6-.3.5.4.6,1.1.3,1.6l-6.5,9.4c-1.4,2-1,4.8.9,6.3,1,.8,2.2,1.1,3.5.9,1.3-.2,2.4-.9,3.1-1.9l6-8.7c.9-1.2.6-3-.6-3.9-.6-.5-1.4-.6-2.1-.5-.8.1-1.4.5-1.9,1.1l-5.8,8.2c-.3.5-.2,1.1.2,1.5.2.2.5.3.8.2.3,0,.6-.2.7-.4l4.7-6.2c.4-.5,1.1-.6,1.6-.2.5.4.6,1.1.2,1.6l-4.7,6.2c-.5.7-1.4,1.2-2.3,1.3-.9.1-1.8-.2-2.5-.7-1.4-1.1-1.6-3.1-.6-4.6l5.8-8.2c.8-1.1,2-1.9,3.4-2.1,1.4-.2,2.7.1,3.8,1,2.2,1.7,2.7,4.8,1.1,7.1l-6,8.7c-1.1,1.5-2.6,2.5-4.4,2.8h0Z"/>
26
+ <title id="altIconTitle">{{ 'MAX_ATTACHMENT' | translate: { FILE_SIZE_LIMIT: file_size_limit } }}</title>
27
+ </svg>
28
+
29
+ </span>
30
+ <input
31
+ [attr.disabled] = "(isFilePendingToUpload || isConversationArchived || hideTextReply)? true : null"
32
+ tabindex="1503"
33
+ type="file"
34
+ aria-label="seleziona allegato"
35
+ [accept]="fileUploadAccept"
36
+ name="chat21-file"
37
+ id="chat21-file"
38
+ #chat21_file
39
+ class="inputfile"
40
+ [ngStyle]="{'display': 'block', height:'1px', width:'1px', overflow: 'hidden' }"
41
+ (change)="detectFiles($event)"/>
42
+ </label>
43
+ <!-- ICON EMOJII -->
44
+ <label *ngIf="showEmojiFooterButton" tabindex="1504" aria-label="emojii" for="chat21-emojii" class="chat21-textarea-button" [class.active]="!isFilePendingToUpload && !hideTextReply" id="chat21-emoticon-picker" (click)="onEmojiiPickerClicked()">
45
+ <span class="v-align-center">
46
+ <svg role="img" aria-labelledby="altIconTitle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
47
+ <path stroke-width=".4px" stroke="currentColor" d="M12,20.8c-5.1,0-9.3-4.2-9.3-9.3S6.9,2.2,12,2.2s9.3,4.2,9.3,9.3-4.2,9.3-9.3,9.3ZM12,3.6c-4.4,0-7.9,3.6-7.9,7.9s3.6,7.9,7.9,7.9,7.9-3.6,7.9-7.9-3.6-7.9-7.9-7.9Z"/>
48
+ <path stroke-width=".4px" stroke="currentColor" d="M12,17.2c-2.7,0-4.3-1.9-4.6-2.3-.2-.3-.2-.7.1-1s.7-.2,1,.1c.1.2,1.4,1.8,3.5,1.8s2.2,0,3.5-1.8c.2-.3.7-.4,1-.1s.4.7.1,1c-1.7,2.2-4.1,2.3-4.6,2.3Z"/>
49
+ <path d="M8.7,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
50
+ <path d="M15.5,10.9c-.9,0-1.6-.7-1.6-1.6s.7-1.6,1.6-1.6,1.6.7,1.6,1.6-.7,1.6-1.6,1.6Z"/>
51
+ <title id="altIconTitle">{{ translationMap?.get('EMOJI') }}</title>
62
52
 
53
+ <!-- <path d="M0,0H20.57V20.57H0V0Z" fill="none"/>
54
+ <circle cx="15.02" cy="9.86" r="1.29"/>
55
+ <circle cx="9.02" cy="9.86" r="1.29"/>
56
+ <path d="M12.02,15.43c-1.27,0-2.36-.69-2.96-1.71h-1.43c.69,1.76,2.39,3,4.39,3s3.7-1.24,4.39-3h-1.43c-.6,1.02-1.69,1.71-2.96,1.71Zm0-12C7.28,3.43,3.45,7.27,3.45,12s3.83,8.57,8.56,8.57,8.58-3.84,8.58-8.57S16.75,3.43,12.01,3.43Zm0,15.43c-3.79,0-6.86-3.07-6.86-6.86s3.07-6.86,6.86-6.86,6.86,3.07,6.86,6.86-3.07,6.86-6.86,6.86Z"/> -->
57
+ </svg>
58
+ </span>
59
+ </label>
60
+ </div>
63
61
 
64
62
 
65
63
 
66
- <div *ngIf="!isStopRec" class="visible-text-area" [class.hasError]="showAlertEmoji" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
67
- <!-- isFilePendingToUpload || -->
68
- <textarea
69
- [attr.disabled] = "(hideTextReply)? true : null"
70
- [attr.placeholder] ="(footerMessagePlaceholder)? footerMessagePlaceholder : translationMap?.get('LABEL_PLACEHOLDER')"
71
- start-focus-chat21-conversation-component
72
- inputTextArea
73
- #textbox
74
- tabindex="1501"
75
- aria-labelledby="altTextArea"
76
- rows="1"
77
- id="chat21-main-message-context"
78
- class='f21textarea c21-button-clean'
79
- [(ngModel)]="textInputTextArea"
80
- (ngModelChange)="onTextAreaChange()"
81
- (keypress)="onkeypress($event)"
82
- (keydown)="onkeydown($event)"
83
- (paste)="onPaste($event)">
84
- </textarea>
85
-
86
- </div>
87
64
 
88
- <!-- ICON SEND -->
89
- <div *ngIf="(textInputTextArea !== '' && !isStopRec) || !showAudioRecorderFooterButton" tabindex="-1" class="chat21-textarea-button" [class.disabled]="showAlertEmoji" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
90
- <span class="v-align-center">
91
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="24" width="24" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" fill="currentColor">
92
- <path d="M1.8,20.6V3.4l20.2,8.6L1.8,20.6ZM3.9,17.3l12.6-5.4L3.9,6.6v3.7l6.4,1.6-6.4,1.6v3.8ZM3.9,17.3V6.6v10.7Z"/>
93
- </svg>
94
- </span>
95
- </div>
65
+ <div *ngIf="!isStopRec" class="visible-text-area" [class.hasError]="showAlertEmoji" [class.disabled] = "( isConversationArchived || hideTextReply)? true : null">
66
+ <!-- isFilePendingToUpload || -->
67
+ <textarea
68
+ [attr.disabled] = "(hideTextReply)? true : null"
69
+ [attr.placeholder] ="(footerMessagePlaceholder)? footerMessagePlaceholder : translationMap?.get('LABEL_PLACEHOLDER')"
70
+ start-focus-chat21-conversation-component
71
+ inputTextArea
72
+ #textbox
73
+ tabindex="1501"
74
+ aria-labelledby="altTextArea"
75
+ rows="1"
76
+ id="chat21-main-message-context"
77
+ class='f21textarea c21-button-clean'
78
+ [(ngModel)]="textInputTextArea"
79
+ (ngModelChange)="onTextAreaChange()"
80
+ (keypress)="onkeypress($event)"
81
+ (keydown)="onkeydown($event)"
82
+ (paste)="onPaste($event)">
83
+ </textarea>
84
+
85
+ </div>
96
86
 
97
- <!-- ICON REC -->
98
- <div *ngIf="showAudioRecorderFooterButton && !textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
99
- <chat-audio-recorder
100
- (startRecordingEvent)="onStartRecording()"
101
- (deleteRecordingEvent)="onDeleteRecording()"
102
- (endRecordingEvent)="onEndRecording($event)"
103
- (sendRecordingEvent)="onSendRecording($event)"
104
- [stylesMap]="stylesMap">
105
- </chat-audio-recorder>
106
- </div>
87
+ <!-- ICON SEND -->
88
+ <div *ngIf="(textInputTextArea !== '' && !isStopRec) || !showAudioRecorderFooterButton" tabindex="-1" class="chat21-textarea-button" [class.disabled]="showAlertEmoji" [class.active]="textInputTextArea && !hideTextReply" id="chat21-button-send" (click)="onSendPressed($event)">
89
+ <span class="v-align-center">
90
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="24" width="24" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" fill="currentColor">
91
+ <path d="M1.8,20.6V3.4l20.2,8.6L1.8,20.6ZM3.9,17.3l12.6-5.4L3.9,6.6v3.7l6.4,1.6-6.4,1.6v3.8ZM3.9,17.3V6.6v10.7Z"/>
92
+ </svg>
93
+ </span>
107
94
  </div>
108
95
 
109
- <div class="close-chat-container" *ngIf="closeChatInConversation">
110
- <button tabindex="1040" aflistconv #aflistconv class="c21-button-primary c21-close" (click)="onCloseChat($event)" [ngStyle]="{'background-color': stylesMap.get('themeColor'), 'border-color': stylesMap.get('themeColor'), 'color': stylesMap?.get('foregroundColor')}">
111
- <span class="v-align-center">
112
- <!-- <svg [ngStyle]="{'fill': 'yellow' }" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
113
- <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" [ngStyle]="{'fill': stylesMap?.get('foregroundColor')}"/>
114
- </svg> -->
115
- <svg [ngStyle]="{'stroke': stylesMap?.get('foregroundColor'), 'fill': stylesMap?.get('foregroundColor') }" role="img" id="archive" aria-labelledby="altIconTitle" class="icon-menu" xmlns="http://www.w3.org/2000/svg"
116
- width="15px" height="15px" viewBox="0 0 512 512">
117
- <path d="M80 152v256a40.12 40.12 0 0040 40h272a40.12 40.12 0 0040-40V152" stroke-linecap="round" stroke-linejoin="round" stroke-width="50px" fill="none"></path>
118
- <rect x="48" y="64" width="416" height="80" rx="28" ry="28" stroke-linejoin="round" stroke-width="50px" fill="none" ></rect>
119
- <path stroke-linecap="round" stroke-linejoin="round" d="M320 304l-64 64-64-64M256 345.89V224" stroke-width="50px" fill="none"></path>
120
- <title id="altIconTitle">{{ translationMap?.get('CLOSE_CHAT') }}</title>
121
- </svg>
122
- </span>
123
- <span class="v-align-center c21-label-button">
124
- {{translationMap?.get('CLOSE_CHAT')}}
125
- </span>
126
- <div class="clear"></div>
127
- </button>
96
+ <!-- ICON REC -->
97
+ <div *ngIf="showAudioRecorderFooterButton && !textInputTextArea" tabindex="-1" class="chat21-audio-button" [class.active]="isStopRec" id="chat21-button-rec">
98
+ <chat-audio-recorder
99
+ (startRecordingEvent)="onStartRecording()"
100
+ (deleteRecordingEvent)="onDeleteRecording()"
101
+ (endRecordingEvent)="onEndRecording($event)"
102
+ (sendRecordingEvent)="onSendRecording($event)"
103
+ [stylesMap]="stylesMap">
104
+ </chat-audio-recorder>
128
105
  </div>
129
106
  </div>
130
107
 
@@ -1,25 +1,23 @@
1
- .textarea-container-wrapper{
2
- display: flex;
3
- flex-direction: column;
4
- gap: 8px;
5
- }
1
+
6
2
  .textarea-container{
3
+ // padding: 8px 34px;
4
+ // padding-left: 70px;
5
+ // padding-right: 45px;
7
6
  display: flex;
7
+ // width: 100%;
8
8
  align-items: center;
9
9
  justify-content: space-between;
10
10
  gap: 8px;
11
- }
12
- .close-chat-container{
13
- display: flex;
14
- flex-direction: column;
15
- align-items: center;
16
- justify-content: center;
17
- gap: 8px;
18
11
 
19
- .c21-close{
20
- height: 30px !important;
21
- margin: 0px !important;
12
+ //if attachment icon OR emoji icon is not in DOM -> increment textarea width
13
+ &:has(:not(#chat21-start-upload-doc), :not(#chat21-emoticon-picker)) .visible-text-area {
14
+ width: 80%;
22
15
  }
16
+ //if attachment icon AND emoji icon is not in DOM -> increment textarea width
17
+ &:has(:not(#chat21-start-upload-doc)):has(:not(#chat21-emoticon-picker)) .visible-text-area {
18
+ width: 90%;
19
+ }
20
+
23
21
  }
24
22
 
25
23
  .icons-container{
@@ -421,28 +419,3 @@ textarea:active{
421
419
  border: none;
422
420
  // margin: -2px -2px 0px;
423
421
  }
424
-
425
-
426
- // aggiungi un'animazione di fade in e fade out quando .star-rating-widget è visibile con transition
427
- .star-rating-widget {
428
- transition: all 0.5s ease-in-out;
429
- }
430
-
431
- .star-rating-widget {
432
- position: absolute;
433
- left: 0;
434
- right: 0;
435
- bottom: -52px;
436
- height: 100%;
437
- width: 100%;
438
- flex-direction: row;
439
- justify-content: center;
440
- background-color: rgb(255, 255, 255);
441
- flex-wrap: nowrap;
442
- &.active {
443
- bottom: 0px;
444
- }
445
- &.inactive {
446
- bottom: -52px;
447
- }
448
- }
@@ -42,7 +42,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
42
42
  @Input() isEmojiiPickerShow: boolean;
43
43
  @Input() footerMessagePlaceholder: string;
44
44
  @Input() fileUploadAccept: string;
45
- @Input() closeChatInConversation: boolean;
46
45
  @Input() dropEvent: Event;
47
46
  @Input() poweredBy: string;
48
47
  @Input() stylesMap: Map<string, string>
@@ -53,7 +52,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
53
52
  @Output() onChangeTextArea = new EventEmitter<any>();
54
53
  @Output() onAttachmentFileButtonClicked = new EventEmitter<any>();
55
54
  @Output() onNewConversationButtonClicked = new EventEmitter();
56
- @Output() onCloseChatButtonClicked = new EventEmitter();
57
55
 
58
56
  @ViewChild('chat21_file') public chat21_file: ElementRef;
59
57
  // @ViewChild('emojii_container', {read: ViewContainerRef}) selector;
@@ -89,7 +87,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
89
87
 
90
88
  file_size_limit = FILE_SIZE_LIMIT;
91
89
  attachmentTooltip: string = '';
92
- isErrorNetwork: boolean = false;
93
90
 
94
91
 
95
92
  convertColorToRGBA = convertColorToRGBA;
@@ -712,10 +709,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
712
709
  this.onNewConversationButtonClicked.emit();
713
710
  }
714
711
 
715
- onCloseChat(event){
716
- this.onCloseChatButtonClicked.emit();
717
- }
718
-
719
712
  // onContinueConversation(){
720
713
  // this.hideTextAreaContent = false;
721
714
  // this.onBackButton.emit(false)
@@ -12,7 +12,7 @@ import { MIN_WIDTH_IMAGES } from 'src/app/utils/constants';
12
12
  import { ConversationModel } from 'src/chat21-core/models/conversation';
13
13
  import { LoggerService } from 'src/chat21-core/providers/abstract/logger.service';
14
14
  import { LoggerInstance } from 'src/chat21-core/providers/logger/loggerInstance';
15
- import { commandToMessage, conversationToMessage, isEmojii, isFrame, isImage, isMine, isSameSender, isSender } from 'src/chat21-core/utils/utils-message';
15
+ import { commandToMessage, conversationToMessage, isEmojii, isFrame, isImage, isSameSender } from 'src/chat21-core/utils/utils-message';
16
16
 
17
17
 
18
18
  @Component({
@@ -59,9 +59,6 @@ export class LastMessageComponent implements OnInit, AfterViewInit, OnDestroy {
59
59
  ngOnChanges(changes: SimpleChanges) {
60
60
  this.logger.debug('[LASTMESSAGE] onChanges', changes)
61
61
  if(this.conversation){
62
-
63
- /** if the message is sent by the logged user, do not add it to the messages array */
64
- if(isSender(this.conversation.sender, this.g.senderId)) return;
65
62
 
66
63
  if(this.conversation.attributes && this.conversation.attributes.commands){
67
64
  this.addCommandMessage(this.conversation)
@@ -1130,12 +1130,6 @@ export class GlobalSettingsService {
1130
1130
  if (TEMP !== undefined) {
1131
1131
  globals.size = TEMP;
1132
1132
  }
1133
-
1134
- TEMP = tiledeskSettings['closeChatInConversation'];
1135
- // this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > closeChatInConversation:: ', TEMP]);
1136
- if (TEMP !== undefined) {
1137
- globals.closeChatInConversation = (TEMP === true) ? true : false;
1138
- }
1139
1133
  }
1140
1134
 
1141
1135
  /**
@@ -1882,11 +1876,6 @@ export class GlobalSettingsService {
1882
1876
  if (TEMP) {
1883
1877
  globals.size = TEMP;
1884
1878
  }
1885
-
1886
- TEMP = getParameterByName(windowContext, 'tiledesk_closeChatInConversation');
1887
- if (TEMP) {
1888
- globals.closeChatInConversation = stringToBoolean(TEMP);
1889
- }
1890
1879
 
1891
1880
  }
1892
1881
 
@@ -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
 
@@ -36,7 +36,6 @@
36
36
 
37
37
  --chat-footer-height: 64px;
38
38
  --chat-footer-logo-height: 30px;
39
- --chat-footer-close-button-height: 30px;
40
39
  --chat-footer-border-radius: 16px;
41
40
  --chat-footer-background-color: #f6f7fb;
42
41
  --chat-footer-color: #1a1a1a;
@@ -227,8 +227,6 @@ export class Globals {
227
227
  fontFamilySource: string; // ******* new ********
228
228
 
229
229
  size: 'min' | 'max' | 'top'; // ******* new ********
230
-
231
- closeChatInConversation: boolean; // ******* new ********
232
230
  constructor(
233
231
  ) { }
234
232
 
@@ -445,8 +443,7 @@ export class Globals {
445
443
  this.hasCalloutInWidgetConfig = false;
446
444
  /** set widget size from 3 different positions: min, max, top */
447
445
  this.size = 'min';
448
- /** enable to close the chat in conversation */
449
- this.closeChatInConversation = false;
446
+
450
447
  // ============ END: SET EXTERNAL PARAMETERS ==============//
451
448
 
452
449
 
@@ -97,6 +97,5 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji not allowed",
98
98
  "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
99
99
  "MAX_ATTACHMENT": "Max allowed size {{FILE_SIZE_LIMIT}}Mb",
100
- "MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
101
100
  "EMOJI": "Emoji"
102
101
  }
@@ -97,6 +97,5 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji no permitido",
98
98
  "DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
99
99
  "MAX_ATTACHMENT": "Tamaño máximo permitido {{FILE_SIZE_LIMIT}}Mb",
100
- "MAX_ATTACHMENT_ERROR": "El archivo supera el tamaño máximo permitido",
101
100
  "EMOJI": "Emoji"
102
101
  }
@@ -97,6 +97,5 @@
97
97
  "EMOJI_NOT_ELLOWED":"Emoji non autorisé",
98
98
  "DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
99
99
  "MAX_ATTACHMENT": "Taille maximale autorisée {{FILE_SIZE_LIMIT}}Mo",
100
- "MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
101
100
  "EMOJI": "Emoji"
102
101
  }
@@ -95,6 +95,5 @@
95
95
  "EMOJI_NOT_ELLOWED":"Emoji non consentiti",
96
96
  "DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
97
97
  "MAX_ATTACHMENT": "Dimensione massima consentita {{FILE_SIZE_LIMIT}}Mb",
98
- "MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
99
98
  "EMOJI": "Emoji"
100
99
  }
@@ -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
+