Skip to content

Commit 10780d6

Browse files
committed
feat: Wrap links with a tag if message has text content
1 parent 1455740 commit 10780d6

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

projects/stream-chat-angular/src/lib/message/message.component.spec.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,10 @@ describe('MessageComponent', () => {
652652
it('should display HTML content', () => {
653653
const htmlContent =
654654
'<a href="https://getstream.io/">https://getstream.io/</a>';
655-
component.message = { ...component.message!, ...{ html: htmlContent } };
655+
component.message = {
656+
...component.message!,
657+
...{ html: `<p>${htmlContent}</p>\n` },
658+
};
656659
component.ngOnChanges({ message: {} as SimpleChange });
657660
fixture.detectChanges();
658661

@@ -899,6 +902,25 @@ describe('MessageComponent', () => {
899902
(window as typeof window & { chrome: Object }).chrome = chrome;
900903
});
901904

905+
it('should replace URL links inside text content', () => {
906+
component.message = {
907+
html: '<p>This is a message with a link <a href="https://getstream.io/" rel="nofollow">https://getstream.io/</a></p>\n',
908+
text: 'This is a message with a link https://getstream.io/',
909+
} as any as StreamMessage;
910+
component.ngOnChanges({ message: {} as SimpleChange });
911+
912+
expect(component.messageTextParts[0].content).toContain(
913+
' <a href="https://getstream.io/" rel="nofollow">https://getstream.io/</a>'
914+
);
915+
916+
component.message.html = undefined;
917+
component.ngOnChanges({ message: {} as SimpleChange });
918+
919+
expect(component.messageTextParts[0].content).toContain(
920+
'<a href="https://getstream.io/" rel="nofollow">https://getstream.io/</a>'
921+
);
922+
});
923+
902924
it('should display reply count for parent messages', () => {
903925
expect(queryReplyCountButton()).toBeNull();
904926

projects/stream-chat-angular/src/lib/message/message.component.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,18 +295,24 @@ export class MessageComponent implements OnInit, OnChanges, OnDestroy {
295295
if (!content) {
296296
this.messageTextParts = [];
297297
} else {
298+
let isHTML = false;
298299
// Backend will wrap HTML content with <p></p>\n
299300
if (content.startsWith('<p>')) {
300301
content = content.replace('<p>', '');
302+
isHTML = true;
301303
}
302304
if (content.endsWith('</p>\n')) {
303305
content = content.replace('</p>\n', '');
306+
isHTML = true;
304307
}
305308
if (
306309
!this.message!.mentioned_users ||
307310
this.message!.mentioned_users.length === 0
308311
) {
309312
content = this.fixEmojiDisplay(content);
313+
if (!isHTML) {
314+
content = this.wrapLinskWithAnchorTag(content);
315+
}
310316
this.messageTextParts = [{ content, type: 'text' }];
311317
} else {
312318
this.messageTextParts = [];
@@ -315,6 +321,9 @@ export class MessageComponent implements OnInit, OnChanges, OnDestroy {
315321
const mention = `@${user.name || user.id}`;
316322
let precedingText = text.substring(0, text.indexOf(mention));
317323
precedingText = this.fixEmojiDisplay(precedingText);
324+
if (!isHTML) {
325+
precedingText = this.wrapLinskWithAnchorTag(precedingText);
326+
}
318327
this.messageTextParts.push({
319328
content: precedingText,
320329
type: 'text',
@@ -328,6 +337,9 @@ export class MessageComponent implements OnInit, OnChanges, OnDestroy {
328337
});
329338
if (text) {
330339
text = this.fixEmojiDisplay(text);
340+
if (!isHTML) {
341+
text = this.wrapLinskWithAnchorTag(text);
342+
}
331343
this.messageTextParts.push({ content: text, type: 'text' });
332344
}
333345
}
@@ -352,4 +364,15 @@ export class MessageComponent implements OnInit, OnChanges, OnDestroy {
352364

353365
return content;
354366
}
367+
368+
private wrapLinskWithAnchorTag(content: string) {
369+
const urlRegexp =
370+
/(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[A-Z0-9+&@#/%=~_|$])/gim;
371+
content = content.replace(
372+
urlRegexp,
373+
(match) => `<a href="${match}" rel="nofollow">${match}</a>`
374+
);
375+
376+
return content;
377+
}
355378
}

0 commit comments

Comments
 (0)