diff --git a/README.md b/README.md
index ebdf5e5..6fefed9 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[![npm](https://img.shields.io/npm/v/ng-chat.svg)](https://www.npmjs.com/package/ng-chat)
[![npm downloads](https://img.shields.io/npm/dm/ng-chat.svg)](https://npmjs.org/ng-chat)
-[![Build Status](https://travis-ci.org/rpaschoal/ng-chat.svg?branch=master)](https://travis-ci.org/rpaschoal/ng-chat)
+[![Build Status](https://travis-ci.org/rpaschoal/ng-chat.svg?branch=development)](https://travis-ci.org/rpaschoal/ng-chat)
[![codecov](https://codecov.io/gh/rpaschoal/ng-chat/branch/master/graph/badge.svg)](https://codecov.io/gh/rpaschoal/ng-chat)
A simple facebook/linkedin lookalike chat module for Angular applications.
@@ -76,6 +76,7 @@ __Additional Settings__
* [pollingInterval]{number}: Configures the long poll interval in milliseconds. Default is 5000.
* [historyEnabled]{boolean}: Defines whether the component should call the "getMessageHistory" from the chat-adapter. Default is true.
* [emojisEnabled]{boolean}: Enables emoji parsing on the messages. Default is true.
+* [linkfyEnabled]{boolean}: Transforms links within the messages to valid HTML links. Default is true.
#### Implement your ChatAdapter:
diff --git a/demo/aspnetcore_signalr/package.json b/demo/aspnetcore_signalr/package.json
index 832145f..242ee5a 100644
--- a/demo/aspnetcore_signalr/package.json
+++ b/demo/aspnetcore_signalr/package.json
@@ -29,7 +29,7 @@
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"jquery": "3.2.1",
- "ng-chat": "1.0.0",
+ "ng-chat": "1.0.1",
"ng2-loading-bar": "0.0.6",
"reflect-metadata": "^0.1.10",
"rxjs": "5.4.2",
diff --git a/demo/offline_bot/package.json b/demo/offline_bot/package.json
index 099b267..4e940c5 100644
--- a/demo/offline_bot/package.json
+++ b/demo/offline_bot/package.json
@@ -24,7 +24,7 @@
"core-js": "^2.4.1",
"rxjs": "^5.4.2",
"zone.js": "^0.8.14",
- "ng-chat": "1.0.0"
+ "ng-chat": "1.0.1"
},
"devDependencies": {
"@angular/cli": "1.3.2",
diff --git a/src/ng-chat/ng-chat.component.html b/src/ng-chat/ng-chat.component.html
index 286cfc5..ba20119 100644
--- a/src/ng-chat/ng-chat.component.html
+++ b/src/ng-chat/ng-chat.component.html
@@ -45,12 +45,10 @@
-
- {{emojisEnabled ? (message.message | emojify) : message.message}}
-
+
-
+
diff --git a/src/ng-chat/ng-chat.component.ts b/src/ng-chat/ng-chat.component.ts
index 17a64f0..887a137 100644
--- a/src/ng-chat/ng-chat.component.ts
+++ b/src/ng-chat/ng-chat.component.ts
@@ -49,6 +49,9 @@ export class NgChat implements OnInit {
@Input()
public emojisEnabled: boolean = true;
+ @Input()
+ public linkfyEnabled: boolean = true;
+
public searchInput: string = "";
private users: User[];
diff --git a/src/ng-chat/ng-chat.module.ts b/src/ng-chat/ng-chat.module.ts
index e727e80..40574ba 100644
--- a/src/ng-chat/ng-chat.module.ts
+++ b/src/ng-chat/ng-chat.module.ts
@@ -4,10 +4,11 @@ import { FormsModule } from '@angular/forms';
import { NgChat } from './ng-chat.component';
import { EmojifyPipe } from './pipes/emojify.pipe';
+import { LinkfyPipe } from './pipes/linkfy.pipe';
@NgModule({
imports: [CommonModule, FormsModule],
- declarations: [NgChat, EmojifyPipe],
+ declarations: [NgChat, EmojifyPipe, LinkfyPipe],
exports: [NgChat]
})
export class NgChatModule {
diff --git a/src/ng-chat/pipes/emojify.pipe.ts b/src/ng-chat/pipes/emojify.pipe.ts
index f1d0409..9b1105d 100644
--- a/src/ng-chat/pipes/emojify.pipe.ts
+++ b/src/ng-chat/pipes/emojify.pipe.ts
@@ -23,14 +23,14 @@ let emojiDictionary = [
*/
@Pipe({name: 'emojify'})
export class EmojifyPipe implements PipeTransform {
- transform(message: string): string {
- if (message && message.length > 1) {
- emojiDictionary.forEach(emoji => {
- emoji.patterns.forEach(pattern => {
- message = message.replace(pattern, emoji.unicode);
- })
- });
- }
+ transform(message: string, pipeEnabled: boolean): string {
+ if (pipeEnabled && message && message.length > 1) {
+ emojiDictionary.forEach(emoji => {
+ emoji.patterns.forEach(pattern => {
+ message = message.replace(pattern, emoji.unicode);
+ })
+ });
+ }
return message;
}
diff --git a/src/ng-chat/pipes/linkfy.pipe.ts b/src/ng-chat/pipes/linkfy.pipe.ts
new file mode 100644
index 0000000..5fabc06
--- /dev/null
+++ b/src/ng-chat/pipes/linkfy.pipe.ts
@@ -0,0 +1,33 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+/*
+ * Transforms text containing URLs or E-mails to valid links/mailtos
+*/
+@Pipe({name: 'linkfy'})
+export class LinkfyPipe implements PipeTransform {
+ transform(message: string, pipeEnabled: boolean): string {
+ if (pipeEnabled && message && message.length > 1)
+ {
+ let replacedText;
+ let replacePatternProtocol;
+ let replacePatternWWW;
+ let replacePatternMailTo;
+
+ // URLs starting with http://, https://, or ftp://
+ replacePatternProtocol = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
+ replacedText = message.replace(replacePatternProtocol, '$1');
+
+ // URLs starting with "www." (ignoring // before it).
+ replacePatternWWW = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
+ replacedText = replacedText.replace(replacePatternWWW, '$1$2');
+
+ // Change email addresses to mailto:: links.
+ replacePatternMailTo = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
+ replacedText = replacedText.replace(replacePatternMailTo, '$1');
+
+ return replacedText;
+ }
+ else
+ return message;
+ }
+}
diff --git a/src/package.json b/src/package.json
index c0567df..cf92f97 100644
--- a/src/package.json
+++ b/src/package.json
@@ -1,6 +1,6 @@
{
"name": "ng-chat",
- "version": "1.0.0",
+ "version": "1.0.1",
"peerDependencies": {
"@angular/common": "*",
"@angular/core": "*",
diff --git a/src/spec/emojify.pipe.spec.ts b/src/spec/emojify.pipe.spec.ts
index 33bd9f6..03193d8 100644
--- a/src/spec/emojify.pipe.spec.ts
+++ b/src/spec/emojify.pipe.spec.ts
@@ -6,27 +6,33 @@ describe('EmojifyPipe', () => {
});
it('Must work on empty messages', () => {
- let result = this.subject.transform('');
+ let result = this.subject.transform('', true);
expect(result).toBe('');
});
+ it('Must not replace with emoji when piple is disabled', () => {
+ let result = this.subject.transform(':)', false);
+
+ expect(result).toBe(':)');
+ });
+
it('Must not replace the message text when no emoji is found', () => {
let message = 'Test message';
- let result = this.subject.transform(message);
+ let result = this.subject.transform(message, true);
expect(result).toBe(message);
});
it('Must replace message text with emoji unicode 😃', () => {
- let result = this.subject.transform(':)');
+ let result = this.subject.transform(':)', true);
expect(result).toBe('😃');
});
it('Must replace message text with emoji unicode 👍', () => {
- let result = this.subject.transform(':+1');
+ let result = this.subject.transform(':+1', true);
expect(result).toBe('👍');
});
diff --git a/src/spec/linkfy.pipe.spec.ts b/src/spec/linkfy.pipe.spec.ts
new file mode 100644
index 0000000..1e517c7
--- /dev/null
+++ b/src/spec/linkfy.pipe.spec.ts
@@ -0,0 +1,73 @@
+import { LinkfyPipe } from '../ng-chat/pipes/linkfy.pipe';
+
+describe('LinkfyPipe', () => {
+ beforeEach(() => {
+ this.subject = new LinkfyPipe();
+ });
+
+ it('Must work on empty messages', () => {
+ let result = this.subject.transform('', true);
+
+ expect(result).toBe('');
+ });
+
+ it('Must not replace with link when piple is disabled', () => {
+ let result = this.subject.transform('www.github.com/rpaschoal/ng-chat', false);
+
+ expect(result).toBe('www.github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must not replace with HTTP link when piple is disabled', () => {
+ let result = this.subject.transform('http://github.com/rpaschoal/ng-chat', false);
+
+ expect(result).toBe('http://github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must not replace with HTTPs link when piple is disabled', () => {
+ let result = this.subject.transform('https://github.com/rpaschoal/ng-chat', false);
+
+ expect(result).toBe('https://github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must not replace with FTP link when piple is disabled', () => {
+ let result = this.subject.transform('ftp://127.0.0.1', false);
+
+ expect(result).toBe('ftp://127.0.0.1');
+ });
+
+ it('Must not replace e-mail with mailto link when piple is disabled', () => {
+ let result = this.subject.transform('test@email.com', false);
+
+ expect(result).toBe('test@email.com');
+ });
+
+ it('Must replace www.{0} text with link', () => {
+ let result = this.subject.transform('www.github.com/rpaschoal/ng-chat', true);
+
+ expect(result).toBe('www.github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must replace http://{0} text with link', () => {
+ let result = this.subject.transform('http://github.com/rpaschoal/ng-chat', true);
+
+ expect(result).toBe('http://github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must replace https://{0} text with link', () => {
+ let result = this.subject.transform('https://github.com/rpaschoal/ng-chat', true);
+
+ expect(result).toBe('https://github.com/rpaschoal/ng-chat');
+ });
+
+ it('Must replace ftp://{0} text with link', () => {
+ let result = this.subject.transform('ftp://127.0.0.1', true);
+
+ expect(result).toBe('ftp://127.0.0.1');
+ });
+
+ it('Must replace e-mail with mailto link', () => {
+ let result = this.subject.transform('test@email.com', true);
+
+ expect(result).toBe('test@email.com');
+ });
+});