@chat21/chat21-web-widget 5.1.27-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 (30) 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 +28 -82
  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/badge_Bot_Umano.md +85 -0
  9. package/docs/changelog/this-branch.md +35 -24
  10. package/package.json +1 -1
  11. package/src/app/app.component.ts +17 -6
  12. package/src/app/component/conversation-detail/conversation/conversation.component.html +1 -3
  13. package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -2
  14. package/src/app/component/conversation-detail/conversation/conversation.component.ts +27 -153
  15. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -1
  16. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +80 -103
  17. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +13 -40
  18. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +0 -7
  19. package/src/app/component/conversation-detail/conversation-header/conversation-header.component.html +1 -1
  20. package/src/app/providers/global-settings.service.ts +2 -25
  21. package/src/app/providers/translator.service.ts +0 -2
  22. package/src/app/sass/_variables.scss +0 -1
  23. package/src/app/utils/conversation-sender-classifier.ts +116 -0
  24. package/src/app/utils/globals.ts +26 -7
  25. package/src/assets/i18n/en.json +0 -1
  26. package/src/assets/i18n/es.json +0 -1
  27. package/src/assets/i18n/fr.json +0 -1
  28. package/src/assets/i18n/it.json +0 -1
  29. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  30. 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,54 +6,50 @@
6
6
  ### **Copyrigth**:
7
7
  *Tiledesk SRL*
8
8
 
9
- # 5.1.27-rc1
10
- - **added**: closeChatInConversation parameters
11
- - **added**: close chat button under textarea footer component
9
+ # 5.1.30
10
+ - **bug fixed**: startHidden is not working properly
12
11
 
13
- # 5.1.26-rc6
12
+ # 5.1.28
13
+ - **bug fixed**: header option menu is deactivated on mobile
14
+
15
+ # 5.1.28
16
+ - **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
17
+
18
+ # 5.1.27
19
+ - **bug fixed**: centralized fullscreen management on mobile and handled the case of the closed widget that remained fullscreen
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
14
25
  - **changed**: mobile always opens fullscreen and ignores legacy stored size”.
15
26
  - **changed**: changed user-typing
16
-
17
- # 5.1.26-rc5
18
27
  - **changed**: Hide the resize-widget button when on mobile
19
28
  - **added**: added "I'm thinking" when the bot responds
20
29
 
21
- # 5.1.26-rc4
22
- - **changed**: decoupled callout from signin
23
-
24
- # 5.1.26-rc3
25
- - **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
26
-
27
- # 5.1.26-rc2
28
- - **changed**: start with authentication if hasCalloutInWidgetConfig is true
29
-
30
- # 5.1.26-rc1
31
- - **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
32
-
30
+ # 5.1.26
31
+ - **bug fixed**: attachment buttons text alignment
33
32
 
34
- # 5.1.25-rc1
33
+ # 5.1.25
35
34
  - **bug fixed**: attachment buttons in messages now respect the container max width and wrap/break long labels instead of being clipped
36
35
 
37
- # 5.1.24-rc2
38
- - **bug fixed**: minor fix in marked pipe to avoid rendering html tags
39
-
40
- # 5.1.24-rc1
36
+ # 5.1.24
41
37
  - **security**: hardened Markdown link rendering by blocking dangerous protocols (e.g. `javascript:`, `data:`, `vbscript:`) and preventing unsafe links from being rendered as anchors
42
38
  - **changed**: refactored `MarkedPipe` to simplify Markdown parsing, improve link rendering via a custom `marked` renderer, and streamline newline handling (`\\n` → `\n`)
43
39
 
44
- # 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
45
47
  - **bug fixed**: saved the widget's size state to local storage (in HP conversations)
46
48
 
47
- # 5.1.20-rc2
48
- - **changed**: API for upload a file/iamges
49
+ # 5.1.20
49
50
  - **changed**: marked pipe do not render /n
50
51
 
51
- # 5.1.20-rc1
52
- - **changed**: API for upload a file/iamges
53
-
54
52
  # 5.1.19
55
-
56
- # 5.1.19-rc1
57
53
  - **bug fixed**: show bottom scroll button and unread message badge only when I'm not at the bottom of the page
58
54
  - **changed**: allow HTML code to be inserted into messages, but do not parse the code. Ensure coexistence with Markdown.
59
55
  - **bug fixed**: after sending a multi-line message, the text area remains open on multiple lines.
@@ -63,7 +59,6 @@
63
59
  - **changed**: saved the widget's size state to local storage. The parameter flow is (default → storage → settings → URL)
64
60
 
65
61
  # 5.1.18
66
- # 5.1.15-rc3
67
62
  - **added**: Implemented Shadow DOM in the text component to isolate HTML and Markdown rendering in a safe and protected context
68
63
  - **changed**: Adapted text component styles to support Shadow DOM (removed ::ng-deep, added styles for common markdown elements)
69
64
  - **security**: HTML/Markdown content is now rendered in an isolated Shadow DOM, improving security and preventing interference with the rest of the application
@@ -74,12 +69,6 @@
74
69
  # 5.1.16
75
70
  - **changed**: "close chat" header conversation menu button enabled in chatbot-panel.html
76
71
 
77
- # 5.1.15-rc2
78
- - **bug-fixed**: Bug fix for ifame message width
79
-
80
- # 5.1.15-rc1
81
- - **changed**: Load local translations before remote ones
82
-
83
72
  # 5.1.15
84
73
  - **changed**: Load local translations before remote ones
85
74
 
@@ -88,57 +77,14 @@
88
77
 
89
78
  # 5.1.13
90
79
  - **bug-fixed**: set default widget size
91
-
92
- # 5.1.7-rc16
93
- - **bug-fixed**: set default widget size
94
-
95
- # 5.1.7-rc15
96
- - **bug-fixed**: set the color of the buttons with visibility control to the font color
97
-
98
- # 5.1.7-rc14
99
- - **bug-fixed**: departmentId and departmentName is incorrect in attributes
100
-
101
- # 5.1.7-rc13
102
- - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
103
-
104
- # 5.1.7-rc12
105
- - **changed**: Force authentication if ageChangeVisibilityDesktop or PageChangeVisibilityMobile is OPEN
106
- - **changed**: Set the default autoStart value to false
107
- - **added**: Added the open widget loading spinner
108
- - **changed**: Load the widget without authentication and display the speech bubble
109
-
110
- # 5.1.7-rc11
111
- - **changed**: set default value autoStart false
112
- - **added**:added loading spinner
113
-
114
- # 5.1.7-rc10
115
- - **changed**: load widget without authentication and display the balloon
116
-
117
- # 5.1.7-rc9
118
- - **removed**: 'DOMAIN_NOT_ALLOWED' in textarea footer component
119
-
120
- # 5.1.7-rc8
121
- # changes in the branch
122
- - **changed**: Load local translations before remote ones
123
- - **bug-fixed**: set default widget size
124
80
  - **changed**: Updated the translations of the tooltips in the footer-component
125
81
  - **changed**: Refactored the network-offline component and made it generic for displaying errors (now error-alert.component)
126
-
127
- # 5.1.7-rc7
128
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
129
-
130
- # 5.1.7-rc6
131
- - **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)
132
83
 
133
84
  # 5.1.12
134
85
  - **bug-fixed**: check showEmojiFooterButton to enable/disable emojii
135
86
  - **bug-fixed**: markdown is fired as an emojii and blocked by isEmojii check fn
136
87
 
137
- # 5.1.7-rc7
138
- - **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
139
-
140
- # 5.1.7-rc6
141
- - **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
142
88
 
143
89
  # 5.1.7-rc5
144
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
@@ -0,0 +1,85 @@
1
+ # Questo branch: UX bot/umano + disaccoppiamento callout
2
+
3
+ ## Contesto
4
+
5
+ Questo branch migliora il feedback in conversazione e rende il comportamento del callout indipendente dal sign-in del widget.
6
+
7
+ ## Modifiche incluse
8
+
9
+ - Aggiunto un **badge Bot/Umano** nella vista conversazione.
10
+ - All'apertura della conversazione (e ad ogni nuovo messaggio) analizza i messaggi e determina il tipo conversazione.
11
+
12
+ ## Come viene identificato Bot/Umano
13
+
14
+ La logica vive in `ConversationComponent` e in un modulo pure di supporto (`src/app/utils/conversation-sender-classifier.ts`).
15
+
16
+ ### Regole (in ordine)
17
+
18
+ 1) **Selezione del messaggio “server” più recente**
19
+ - Si considerano solo i messaggi **non inviati dal client corrente** (si scartano quelli con `sender === senderId`).
20
+ - L’“ultimo” messaggio server viene determinato in modo robusto usando `timestamp` (equivalente a ordinare per timestamp decrescente).
21
+
22
+ 2) **Regola speciale: handoff a operatore (Umano)**
23
+ - Se l’ultimo messaggio server è `system` e rappresenta un handoff verso umano:
24
+ - `attributes.subtype === "info"`
25
+ - `attributes.updateconversation === true`
26
+ - `attributes.messagelabel.key === "MEMBER_JOINED_GROUP"`
27
+ - `attributes.messagelabel.parameters.member_id` **non** è `system`, **non** inizia con `bot_`, e **non** coincide con il `senderId` del client
28
+ - allora la conversazione viene forzata a **Umano**.
29
+
30
+ 3) **Se l’ultimo messaggio server non è system**
31
+ - viene classificato come **Bot** se:
32
+ - è presente `attributes.flowAttributes.chatbot_id` (segnale forte, anche se diverso da `sender`), oppure
33
+ - euristiche legacy: `sender` contiene `bot_` oppure `sender_fullname` contiene “bot”
34
+ - altrimenti come **Umano**.
35
+
36
+ 4) **Se l’ultimo messaggio server è system (ma non handoff umano)**
37
+ - si cerca il messaggio server **precedente non-system** e si applica la classificazione Bot/Umano su quello.
38
+
39
+ ### Risultato in UI
40
+ - Il badge mostra **Bot** o **Umano** in base all’ultimo responder server **non-system**, con precedenza della regola handoff.
41
+
42
+ - Aggiunto il feedback temporaneo **"sto pensando..."** dopo l'invio del messaggio da parte del client.
43
+ - Mostrato solo quando la conversazione e' classificata come **Bot**.
44
+ - Nascosto alla prima risposta server (nessuna durata minima).
45
+
46
+ - Rimossa l'implementazione temporanea del toast "ciao" nel footer e relativo wiring.
47
+
48
+ - Abilitato il percorso di avvio widget per i casi guidati da bot quando sono presenti `botsRules`.
49
+
50
+ ## Disaccoppiamento callout (step completati)
51
+
52
+ - **Step 1**: rimossa la dipendenza da `g.senderId` nel rendering del componente callout in `app.component.html`.
53
+ - Prima: render solo con `g.senderId && !g.isOpenNewMessage`
54
+ - Dopo: render con `!g.isOpenNewMessage`
55
+
56
+ - **Step 2**: scheduling del callout al caricamento delle impostazioni widget in `AppComponent`.
57
+ - Aggiunto `scheduleCalloutFromSettings()` basato su `g.calloutTimer`.
58
+ - Invocato subito dopo la disponibilita' delle settings (non legato al login).
59
+ - Aggiunta la pulizia del timeout in `ngOnDestroy()`.
60
+
61
+ - **Step 3**: introdotte precedenze UI e rimossa la duplicazione dello scheduling callout.
62
+ - Aggiunta guardia `canShowCalloutNow()` in `AppComponent`:
63
+ - widget chiuso
64
+ - nessuna preview nuovo messaggio attiva
65
+ - stato callout abilitato
66
+ - callout presente nella configurazione widget
67
+ - Aggiornato `showCallout()` per aprire il callout solo quando le guardie passano e il componente esiste.
68
+ - Rimosso il timer interno (`openIfCallOutTimer`) da `EyeeyeCatcherCardComponent` per evitare doppi trigger.
69
+
70
+ ## Comportamento atteso dopo questo branch
71
+
72
+ - Il callout puo' essere innescato da configurazione anche senza sign-in.
73
+ - Il callout non compare quando il widget e' aperto o quando la preview nuovo messaggio e' attiva.
74
+ - La UI della conversazione indica chiaramente se l'ultimo responder e' bot o umano.
75
+ - "Sto pensando..." compare solo nelle conversazioni bot e ha un comportamento prevedibile.
76
+
77
+ ## Checklist regressioni (bot/umano)
78
+ - **Bot con `flowAttributes.chatbot_id` diverso da `sender`** (caso reale):
79
+ - Atteso: classificazione **Bot** (non Human).
80
+ - **System → bot joined** (`MEMBER_JOINED_GROUP` con `member_id` che inizia per `bot_`):
81
+ - Atteso: non forzare Umano (non è handoff verso operatore).
82
+ - **System → handoff umano** (`MEMBER_JOINED_GROUP` con `member_id` umano):
83
+ - Atteso: forzare **Umano** anche se messaggi precedenti indicavano bot.
84
+ - **Conversazione con soli messaggi system** (dopo aver escluso quelli del client):
85
+ - Atteso: nessun crash; badge Bot/Umano può essere nascosto, ma la classificazione dell’ultimo messaggio server deve restare coerente.
@@ -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.27-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,
@@ -452,6 +453,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
452
453
  }
453
454
 
454
455
  const autoStart = this.g.autoStart;
456
+ const startHidden = this.g.startHidden;
455
457
  that.stateLoggedUser = state;
456
458
  if (state && state === AUTH_STATE_ONLINE) {
457
459
  /** sono loggato */
@@ -526,6 +528,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
526
528
  // || this.g.hasCalloutInWidgetConfig;
527
529
  if (shouldAutoAuthenticate) {
528
530
  that.authenticate();
531
+ if(startHidden){ that.hideWidget(); }
529
532
  } else {
530
533
  that.logger.debug('[APP-COMP] Skip auto-auth: startup conditions not met, show launcher only');
531
534
  }
@@ -1253,6 +1256,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1253
1256
  const senderId = this.g.senderId;
1254
1257
  this.logger.debug('[APP-COMP] f21_open senderId: ', senderId);
1255
1258
  if (senderId) {
1259
+ this.enforceMobileFullscreenOnOpen();
1256
1260
  // chiudo callout
1257
1261
  this.g.setParameter('displayEyeCatcherCard', 'none');
1258
1262
  // this.g.isOpen = true; // !this.isOpen;
@@ -1708,6 +1712,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
1708
1712
  this.logger.debug('[APP-COMP] openCloseWidget', recipientId, this.g.isOpen, this.g.startFromHome);
1709
1713
 
1710
1714
  if (this.g.isOpen === false) {
1715
+ this.enforceMobileFullscreenOnOpen();
1711
1716
  if(this.forceDisconnect){
1712
1717
  this.logger.log('[FORCE] onOpenCloseWidget --> reconnect', this.forceDisconnect)
1713
1718
  this.messagingAuthService.createCustomToken(this.g.tiledeskToken)
@@ -2174,6 +2179,13 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
2174
2179
  }
2175
2180
  }
2176
2181
 
2182
+ private enforceMobileFullscreenOnOpen() {
2183
+ if (this.g?.isMobile) {
2184
+ this.g.fullscreenMode = true;
2185
+ this.g.size = 'max';
2186
+ }
2187
+ }
2188
+
2177
2189
  /**
2178
2190
  * MODAL RATING WIDGET:
2179
2191
  * close modal page
@@ -2307,7 +2319,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
2307
2319
  this.el.nativeElement.style.setProperty('--chat-header-height', this.g.hideHeaderConversation? '0px': null)
2308
2320
  this.el.nativeElement.style.setProperty('--font-size-bubble-message', this.g.fontSize)
2309
2321
  this.el.nativeElement.style.setProperty('--font-family-bubble-message', this.g.fontFamily)
2310
- this.el.nativeElement.style.setProperty('--chat-footer-close-button-height', this.g.closeChatInConversation? '30px': '0px')
2311
2322
 
2312
2323
  }
2313
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>