@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.
- package/.github/workflows/docker-community-push-latest.yml +13 -23
- package/.github/workflows/docker-image-tag-community-tag-push.yml +12 -22
- package/CHANGELOG.md +3 -54
- package/Dockerfile +5 -4
- package/angular.json +1 -2
- package/deploy_amazon_beta.sh +7 -17
- package/deploy_amazon_prod.sh +4 -4
- package/package.json +1 -1
- package/src/app/app.component.html +1 -8
- package/src/app/app.component.scss +0 -59
- package/src/app/app.component.ts +28 -63
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +4 -18
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +0 -25
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +0 -1
- package/src/app/component/home-conversations/home-conversations.component.html +6 -16
- package/src/app/component/home-conversations/home-conversations.component.ts +0 -29
- package/src/app/component/launcher-button/launcher-button.component.html +1 -1
- package/src/app/component/launcher-button/launcher-button.component.ts +2 -3
- package/src/app/component/list-conversations/list-conversations.component.html +3 -8
- package/src/app/component/list-conversations/list-conversations.component.ts +0 -29
- package/src/app/pipe/marked.pipe.ts +17 -1
- package/src/app/providers/translator.service.ts +0 -2
- package/src/app/utils/globals.ts +1 -1
- package/src/assets/i18n/en.json +0 -1
- package/src/assets/i18n/es.json +0 -1
- package/src/assets/i18n/fr.json +0 -1
- package/src/assets/i18n/it.json +0 -1
- package/src/chat21-core/providers/abstract/upload.service.ts +1 -1
- package/src/chat21-core/providers/firebase/firebase-upload.service.ts +1 -1
- package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
- package/src/chat21-core/providers/native/native-upload-service.ts +54 -76
- package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
- package/src/chat21-core/utils/utils.ts +2 -5
- 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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
- '**'
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
10
|
-
- **changed**:
|
|
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
|
|
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
|
-
|
|
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",
|
|
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"
|
package/deploy_amazon_beta.sh
CHANGED
|
@@ -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
|
|
35
|
-
aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300
|
|
36
|
-
aws s3 sync . s3://tiledesk-widget-pre/v5
|
|
37
|
-
|
|
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
|
|
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
|
package/deploy_amazon_prod.sh
CHANGED
|
@@ -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/
|
|
39
|
-
echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget/
|
|
40
|
-
echo https://widget.tiledesk.com/
|
|
41
|
-
echo https://widget.tiledesk.com/
|
|
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
|
@@ -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
|
}
|
package/src/app/app.component.ts
CHANGED
|
@@ -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'
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
483
|
+
that.hideWidget();
|
|
496
484
|
// that.g.setParameter('isShown', false, true);
|
|
497
485
|
that.triggerOnAuthStateChanged(that.stateLoggedUser);
|
|
498
|
-
if (autoStart
|
|
486
|
+
if (autoStart) {
|
|
499
487
|
that.authenticate();
|
|
500
488
|
}
|
|
501
|
-
}
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
492
|
-
|
|
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) {
|
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss
CHANGED
|
@@ -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
|
-
}
|
|
@@ -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':
|
|
42
|
-
<span
|
|
43
|
-
<
|
|
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':
|
|
57
|
-
<span
|
|
58
|
-
<
|
|
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':
|
|
7
|
-
<span
|
|
8
|
-
<
|
|
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
|
-
|
|
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
|
|
package/src/app/utils/globals.ts
CHANGED
|
@@ -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 =
|
|
250
|
+
this.autoStart = true;
|
|
251
251
|
/** start Authentication and startUI */
|
|
252
252
|
this.startHidden = false;
|
|
253
253
|
/** show/hide all widget -> js call: showAllWidget */
|
package/src/assets/i18n/en.json
CHANGED
|
@@ -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
|
}
|
package/src/assets/i18n/es.json
CHANGED
|
@@ -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
|
}
|
package/src/assets/i18n/fr.json
CHANGED
|
@@ -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
|
}
|
package/src/assets/i18n/it.json
CHANGED
|
@@ -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(
|
|
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(
|
|
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() + '
|
|
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
|
|
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(
|
|
28
|
-
this.logger.
|
|
29
|
-
this.URL_TILEDESK_FILE = this.getBaseUrl() +
|
|
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.
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
55
|
+
// that.BSStateUpload.next({upload: upload});
|
|
56
|
+
}, (error) => {
|
|
53
57
|
reject(error)
|
|
54
|
-
}
|
|
58
|
+
});
|
|
55
59
|
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
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).
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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.
|
|
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).
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
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).
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
+
|
package/src/iframe-style.css
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
bottom: 0px;
|
|
14
14
|
width: auto;
|
|
15
15
|
height: auto;
|
|
16
|
-
display:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|