33 class =" vac-format-message-wrapper"
44 :class =" { 'vac-text-ellipsis': singleLine }"
55 >
6- <div
7- v-if =" !textFormatting.disabled"
8- :class =" { 'vac-text-ellipsis': singleLine }"
9- >
6+ <template v-for =" (message , i ) in parsedMessage " :key =" i " >
107 <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
1315 class =" vac-format-container"
16+ :class =" { 'vac-text-ellipsis': singleLine }"
1417 >
1518 <component
1619 :is =" message.url ? 'a' : 'span'"
1720 :class =" {
1821 '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,
2522 'vac-text-tag': !singleLine && !reply && message.tag
2623 }"
2724 :href =" message.href"
2825 :target =" message.href ? linkOptions.target : null"
2926 :rel =" message.href ? linkOptions.rel : null"
30- @click =" openTag(message)"
3127 >
3228 <template v-if =" deleted " >
3329 <slot
5652 />
5753 </div >
5854 <div class =" vac-image-link-message" >
59- < span > {{ message.value }}</ span >
55+ {{ message.value }}
6056 </div >
6157 </template >
6258 <template v-else >
63- < span v-html = " message.value" />
59+ {{ message.value }}
6460 </template >
6561 </component >
6662 </div >
67- </div >
68- <div v-else v-html =" formattedContent" />
63+ </template >
6964 </div >
7065</template >
7166
7267<script >
7368import SvgIcon from ' ../SvgIcon/SvgIcon'
7469
75- import formatString from ' ../../utils/format-string '
70+ import markdown from ' ../../utils/markdown '
7671import { IMAGE_TYPES } from ' ../../utils/constants'
7772
7873export default {
@@ -97,38 +92,36 @@ export default {
9792 emits: [' open-user-tag' ],
9893
9994 computed: {
100- linkifiedMessage () {
95+ parsedMessage () {
10196 if (this .deleted ) {
10297 return [{ value: this .textMessages .MESSAGE_DELETED }]
10398 }
10499
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)
110117
111118 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' )
119120 m .tag = this .checkType (m, ' tag' )
120121 m .image = this .checkImageType (m)
121- m .value = this .replaceEmojiByElement (m .value )
122122 })
123123
124124 return message
125- },
126- formattedContent () {
127- if (this .deleted ) {
128- return this .textMessages .MESSAGE_DELETED
129- } else {
130- return this .formatTags (this .content )
131- }
132125 }
133126 },
134127
@@ -162,63 +155,12 @@ export default {
162155 image .removeEventListener (' load' , onLoad)
163156 }
164157 },
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)
193162 this .$emit (' open-user-tag' , user)
194163 }
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
222164 }
223165 }
224166}
0 commit comments