@bcc-code/vue-bcc-chat-ui 3.4.0 → 3.5.0
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/dist/chat/connection.d.ts +4 -4
- package/dist/chat/data.d.ts +4 -3
- package/dist/chat/environment.d.ts +2 -1
- package/dist/chat/index.d.ts +15 -14
- package/dist/chat/login.d.ts +2 -2
- package/dist/chat/theme.d.ts +2 -1
- package/dist/chat/types.d.ts +2 -1
- package/dist/chat/uiKit.d.ts +3 -2
- package/dist/components/BccChatMessageBubble.vue.d.ts +2 -1
- package/dist/components/BccChatMessageList.vue.d.ts +1 -1
- package/dist/components/CometChatMessageListOverride.vue.d.ts +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/offline/cometChatAPIInterceptor.d.ts +1 -0
- package/dist/offline/cometChatWSInterceptor.d.ts +1 -0
- package/dist/offline/connectivity.d.ts +3 -2
- package/dist/offline/offlineStoreLocalStorage.d.ts +2 -1
- package/dist/style.css +1 -1
- package/dist/vue-bcc-chat-ui.js +18470 -17900
- package/package.json +11 -9
- package/src/components/BccChatMessageBubble.vue +46 -53
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@bcc-code/vue-bcc-chat-ui",
|
|
3
3
|
"author": "bcc-code",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.5.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"private": false,
|
|
8
8
|
"files": [
|
|
@@ -22,21 +22,23 @@
|
|
|
22
22
|
"vue": "^3.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"@types/dompurify": "^3.0.5",
|
|
25
26
|
"@types/markdown-it": "^13.0.7",
|
|
26
|
-
"@types/node": "^20.
|
|
27
|
+
"@types/node": "^20.12.4",
|
|
27
28
|
"@vitejs/plugin-vue": "^4.6.2",
|
|
28
29
|
"path": "^0.12.7",
|
|
29
|
-
"sass": "^1.
|
|
30
|
-
"typescript": "^5.4.
|
|
31
|
-
"vite": "^5.2.
|
|
32
|
-
"vite-plugin-dts": "^3.
|
|
30
|
+
"sass": "^1.74.1",
|
|
31
|
+
"typescript": "^5.4.4",
|
|
32
|
+
"vite": "^5.2.8",
|
|
33
|
+
"vite-plugin-dts": "^3.8.1",
|
|
33
34
|
"vue": "^3.4.21"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@cometchat/chat-sdk-javascript": "^4.0.4",
|
|
37
|
-
"@cometchat/chat-uikit-vue": "^4.3.
|
|
38
|
-
"@cometchat/uikit-resources": "^4.3.
|
|
39
|
-
"@cometchat/uikit-shared": "^4.3.
|
|
38
|
+
"@cometchat/chat-uikit-vue": "^4.3.2",
|
|
39
|
+
"@cometchat/uikit-resources": "^4.3.2",
|
|
40
|
+
"@cometchat/uikit-shared": "^4.3.3",
|
|
41
|
+
"dompurify": "^3.0.11",
|
|
40
42
|
"jwt-decode": "^4.0.0",
|
|
41
43
|
"markdown-it": "^14.1.0"
|
|
42
44
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import MarkdownIt from 'markdown-it'
|
|
3
3
|
import { User } from '@cometchat/chat-sdk-javascript'
|
|
4
|
+
import DOMPurify from 'dompurify';
|
|
4
5
|
|
|
5
6
|
const props = defineProps<{
|
|
6
7
|
text: string,
|
|
@@ -9,72 +10,59 @@ const props = defineProps<{
|
|
|
9
10
|
}>()
|
|
10
11
|
|
|
11
12
|
function toMarkdownHtml(str: string) {
|
|
12
|
-
|
|
13
|
-
const urlRegex = /([^\]]\(|[^\(]|^\(?)((?:https?|ftp):\/\/[^\s\]\)]*|www\.[^\s\]\)]+)(?=[\s\]\)](?!\()|$)/g;
|
|
14
|
-
|
|
15
|
-
// Replacing URLs in the string with Markdown links
|
|
16
|
-
let outStr = str.replace(urlRegex, formatUrlToMarkdown);
|
|
17
|
-
|
|
18
|
-
outStr = formatMentionsInText(outStr);
|
|
19
|
-
|
|
20
|
-
outStr = cleanUpHTML(outStr);
|
|
13
|
+
str = formatMentionsInText(str);
|
|
21
14
|
|
|
22
15
|
const md = new MarkdownIt({
|
|
23
16
|
breaks: true,
|
|
24
17
|
typographer: true,
|
|
18
|
+
linkify: true,
|
|
19
|
+
html: true
|
|
25
20
|
});
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
str = md.render(str);
|
|
23
|
+
|
|
24
|
+
str = DOMPurify.sanitize(str, {
|
|
25
|
+
ALLOWED_TAGS: [
|
|
26
|
+
"a", // links
|
|
27
|
+
"ul", "ol", "li", // lists
|
|
28
|
+
"p", // paragraphs
|
|
29
|
+
"b", "strong", // bold
|
|
30
|
+
"i", "em", // italics
|
|
31
|
+
"u", // underline
|
|
32
|
+
"s", // strikethrough
|
|
33
|
+
"img", // images
|
|
34
|
+
"blockquote", // indented text
|
|
35
|
+
"hr", // horizontal line
|
|
36
|
+
"pre", // constant width text
|
|
37
|
+
"br", // newline
|
|
38
|
+
"div" // newline on mobile
|
|
39
|
+
]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return str
|
|
28
43
|
}
|
|
29
44
|
|
|
30
|
-
// Function to format a URL into a Markdown link
|
|
31
|
-
function formatUrlToMarkdown(_match: string, group1: string, group2: string) {
|
|
32
|
-
let url = group2;
|
|
33
|
-
// Prepend "http://" to URLs starting with "www."
|
|
34
|
-
if (url.startsWith('www.')) {
|
|
35
|
-
url = 'http://' + url;
|
|
36
|
-
}
|
|
37
|
-
const hostname = new URL(url).hostname;
|
|
38
|
-
return `${group1}[${hostname}](${url})`;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
45
|
function formatMentionsInText(text: string) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
return text.replace(/<@uid:(.*?)>/g, (_match: string, uid: string) => {
|
|
47
|
+
const user = (props.mentionedUsers || []).find((user) => user.getUid() === uid);
|
|
48
|
+
// Check if a userName exists for the given uid; if not, keep the original match
|
|
49
|
+
if (user) {
|
|
50
|
+
return `**${user.getName()}**`;
|
|
51
|
+
} else {
|
|
52
|
+
return `**@unknown**`;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
// Due to how mobile adds line breaks we need to remove them
|
|
54
|
-
function cleanUpHTML(input: string) {
|
|
55
|
-
// Step 1: Replace <div><br></div> with <br>
|
|
56
|
-
let cleaned = input.replace(/<div><br><\/div>/g, '\n');
|
|
57
|
-
|
|
58
|
-
// Step 2: Replace opening <div> that follows any content or at the start with <br>
|
|
59
|
-
cleaned = cleaned.replace(/(^|<\/div>)(<div>)/g, '$1\n');
|
|
60
|
-
|
|
61
|
-
// Step 3: Remove all remaining <div> and </div> tags
|
|
62
|
-
cleaned = cleaned.replace(/<\/?div>/g, '');
|
|
63
|
-
|
|
64
|
-
return cleaned;
|
|
65
|
-
}
|
|
66
57
|
</script>
|
|
67
58
|
|
|
68
59
|
<template>
|
|
69
|
-
<div
|
|
70
|
-
v-html="toMarkdownHtml(metadata.translated_message)"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class="bcc-chat-msg-bubble"
|
|
76
|
-
:class="{'bcc-chat-msg-bubble--translated': metadata && !!metadata.translated_message}"
|
|
77
|
-
/>
|
|
60
|
+
<div>
|
|
61
|
+
<div v-if="metadata && metadata.translated_message" v-html="toMarkdownHtml(metadata.translated_message)"
|
|
62
|
+
class="bcc-chat-msg-bubble bcc-chat-msg-bubble--translation" />
|
|
63
|
+
<div v-html="toMarkdownHtml(text)" class="bcc-chat-msg-bubble"
|
|
64
|
+
:class="{ 'bcc-chat-msg-bubble--translated': metadata && !!metadata.translated_message }" />
|
|
65
|
+
</div>
|
|
78
66
|
</template>
|
|
79
67
|
|
|
80
68
|
<style lang="scss">
|
|
@@ -88,7 +76,7 @@ function cleanUpHTML(input: string) {
|
|
|
88
76
|
|
|
89
77
|
p {
|
|
90
78
|
color: var(--cc__text-color);
|
|
91
|
-
line-height: 1.2;
|
|
79
|
+
line-height: 1.2;
|
|
92
80
|
word-break: break-word;
|
|
93
81
|
text-align: left;
|
|
94
82
|
white-space: normal;
|
|
@@ -98,6 +86,7 @@ function cleanUpHTML(input: string) {
|
|
|
98
86
|
p:first-child {
|
|
99
87
|
margin-top: 0;
|
|
100
88
|
}
|
|
89
|
+
|
|
101
90
|
p:last-child {
|
|
102
91
|
margin-bottom: 0;
|
|
103
92
|
}
|
|
@@ -106,14 +95,17 @@ function cleanUpHTML(input: string) {
|
|
|
106
95
|
font-size: 1.6em;
|
|
107
96
|
font-weight: 800;
|
|
108
97
|
}
|
|
98
|
+
|
|
109
99
|
h2 {
|
|
110
100
|
font-size: 1.4em;
|
|
111
101
|
font-weight: 700;
|
|
112
102
|
}
|
|
103
|
+
|
|
113
104
|
h3 {
|
|
114
105
|
font-size: 1.2em;
|
|
115
106
|
font-weight: 600;
|
|
116
107
|
}
|
|
108
|
+
|
|
117
109
|
h4 {
|
|
118
110
|
font-size: 1em;
|
|
119
111
|
font-weight: 500;
|
|
@@ -130,6 +122,7 @@ function cleanUpHTML(input: string) {
|
|
|
130
122
|
list-style: disc;
|
|
131
123
|
margin: 8px 0;
|
|
132
124
|
}
|
|
125
|
+
|
|
133
126
|
ol {
|
|
134
127
|
padding-left: 16px;
|
|
135
128
|
list-style: decimal;
|