3
3
class =" vac-format-message-wrapper"
4
4
:class =" { 'vac-text-ellipsis': singleLine }"
5
5
>
6
- <div
7
- v-if =" !textFormatting.disabled"
8
- :class =" { 'vac-text-ellipsis': singleLine }"
9
- >
6
+ <template v-for =" (message , i ) in parsedMessage " :key =" i " >
10
7
<div
11
- v-for =" (message, i) in linkifiedMessage"
12
- :key =" i"
8
+ v-if =" message.markdown"
9
+ class =" markdown"
10
+ @click =" openTag"
11
+ v-html =" message.value"
12
+ />
13
+ <div
14
+ v-else
13
15
class =" vac-format-container"
16
+ :class =" { 'vac-text-ellipsis': singleLine }"
14
17
>
15
18
<component
16
19
:is =" message.url ? 'a' : 'span'"
17
20
:class =" {
18
21
'vac-text-ellipsis': singleLine,
19
- 'vac-text-bold': message.bold,
20
- 'vac-text-italic': deleted || message.italic,
21
- 'vac-text-strike': message.strike,
22
- 'vac-text-underline': message.underline,
23
- 'vac-text-inline-code': !singleLine && message.inline,
24
- 'vac-text-multiline-code': !singleLine && message.multiline,
25
22
'vac-text-tag': !singleLine && !reply && message.tag
26
23
}"
27
24
:href =" message.href"
28
25
:target =" message.href ? linkOptions.target : null"
29
26
:rel =" message.href ? linkOptions.rel : null"
30
- @click =" openTag(message)"
31
27
>
32
28
<template v-if =" deleted " >
33
29
<slot
56
52
/>
57
53
</div >
58
54
<div class =" vac-image-link-message" >
59
- < span > {{ message.value }}</ span >
55
+ {{ message.value }}
60
56
</div >
61
57
</template >
62
58
<template v-else >
63
- < span v-html = " message.value" />
59
+ {{ message.value }}
64
60
</template >
65
61
</component >
66
62
</div >
67
- </div >
68
- <div v-else v-html =" formattedContent" />
63
+ </template >
69
64
</div >
70
65
</template >
71
66
72
67
<script >
73
68
import SvgIcon from ' ../SvgIcon/SvgIcon'
74
69
75
- import formatString from ' ../../utils/format-string '
70
+ import markdown from ' ../../utils/markdown '
76
71
import { IMAGE_TYPES } from ' ../../utils/constants'
77
72
78
73
export default {
@@ -97,38 +92,36 @@ export default {
97
92
emits: [' open-user-tag' ],
98
93
99
94
computed: {
100
- linkifiedMessage () {
95
+ parsedMessage () {
101
96
if (this .deleted ) {
102
97
return [{ value: this .textMessages .MESSAGE_DELETED }]
103
98
}
104
99
105
- const message = formatString (
106
- this .formatTags (this .content ),
107
- this .linkify && ! this .linkOptions .disabled ,
108
- this .textFormatting
109
- )
100
+ let options
101
+ if (! this .textFormatting .disabled ) {
102
+ options = {
103
+ textFormatting: {
104
+ linkify: this .linkify ,
105
+ linkOptions: this .linkOptions ,
106
+ singleLine: this .singleLine ,
107
+ reply: this .reply ,
108
+ users: this .users ,
109
+ ... this .textFormatting
110
+ }
111
+ }
112
+ } else {
113
+ options = {}
114
+ }
115
+
116
+ const message = markdown (this .content , options)
110
117
111
118
message .forEach (m => {
112
- m .url = this .checkType (m, ' url' )
113
- m .bold = this .checkType (m, ' bold' )
114
- m .italic = this .checkType (m, ' italic' )
115
- m .strike = this .checkType (m, ' strike' )
116
- m .underline = this .checkType (m, ' underline' )
117
- m .inline = this .checkType (m, ' inline-code' )
118
- m .multiline = this .checkType (m, ' multiline-code' )
119
+ m .markdown = this .checkType (m, ' markdown' )
119
120
m .tag = this .checkType (m, ' tag' )
120
121
m .image = this .checkImageType (m)
121
- m .value = this .replaceEmojiByElement (m .value )
122
122
})
123
123
124
124
return message
125
- },
126
- formattedContent () {
127
- if (this .deleted ) {
128
- return this .textMessages .MESSAGE_DELETED
129
- } else {
130
- return this .formatTags (this .content )
131
- }
132
125
}
133
126
},
134
127
@@ -162,63 +155,12 @@ export default {
162
155
image .removeEventListener (' load' , onLoad)
163
156
}
164
157
},
165
- formatTags (content ) {
166
- const firstTag = ' <usertag>'
167
- const secondTag = ' </usertag>'
168
-
169
- const usertags = [... content .matchAll (new RegExp (firstTag, ' gi' ))].map (
170
- a => a .index
171
- )
172
-
173
- const initialContent = content
174
-
175
- usertags .forEach (index => {
176
- const userId = initialContent .substring (
177
- index + firstTag .length ,
178
- initialContent .indexOf (secondTag, index)
179
- )
180
-
181
- const user = this .users .find (user => user ._id === userId)
182
-
183
- content = content .replaceAll (userId, ` @${ user? .username || ' unknown' }` )
184
- })
185
-
186
- return content
187
- },
188
- openTag(message) {
189
- if (!this.singleLine && this.checkType(message, 'tag')) {
190
- const user = this.users.find(
191
- u => message.value.indexOf(u.username) !== -1
192
- )
158
+ openTag (event ) {
159
+ const userId = event .target .getAttribute (' data-user-id' )
160
+ if (! this .singleLine && userId) {
161
+ const user = this .users .find (u => String (u ._id ) === userId)
193
162
this .$emit (' open-user-tag' , user)
194
163
}
195
- },
196
- replaceEmojiByElement(value) {
197
- let emojiSize
198
- if (this.singleLine) {
199
- emojiSize = 16
200
- } else {
201
- const onlyEmojis = this.containsOnlyEmojis()
202
- emojiSize = onlyEmojis ? 28 : 20
203
- }
204
-
205
- return value.replaceAll(
206
- /[\p {Extended_Pictographic}\u{1F3FB} -\u{1F3FF}\u{1F9B0} -\u{1F9B3} ]/gu,
207
- v => {
208
- return ` < span style= " font-size: ${emojiSize}px" > ${v}< / span> `
209
- }
210
- )
211
- },
212
- containsOnlyEmojis() {
213
- const onlyEmojis = this.content.replace(
214
- new RegExp('[\u0000 -\u1eef f]', 'g'),
215
- ''
216
- )
217
- const visibleChars = this.content.replace(
218
- new RegExp('[\n\r s]+|( )+', 'g'),
219
- ''
220
- )
221
- return onlyEmojis.length === visibleChars.length
222
164
}
223
165
}
224
166
}
0 commit comments