/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';
import { convertToBoolProperty, NbBooleanInput } from '../helpers';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { NbChatMessageFile } from './chat-message-file.component';
/**
* Chat message component.
*
* Multiple message types are available through a `type` property, such as
* - text - simple text message
* - file - could be a file preview or a file icon
* if multiple files are provided grouped files are shown
* - quote - quotes a message with specific quote styles
* - map - shows a google map picture by provided [latitude] and [longitude] properties
*
* @stacked-example(Available Types, chat/chat-message-types-showcase.component)
*
* Message with attached files:
* ```html
*
*
* ```
*
* Map message:
* ```html
*
*
* ```
*
* @styles
*
* chat-message-background:
* chat-message-text-color:
* chat-message-reply-background-color:
* chat-message-reply-text-color:
* chat-message-avatar-background-color:
* chat-message-sender-text-color:
* chat-message-quote-background-color:
* chat-message-quote-text-color:
* chat-message-file-text-color:
* chat-message-file-background-color:
*/
@Component({
selector: 'nb-chat-message',
template: `
`,
animations: [
trigger('flyInOut', [
state('in', style({ transform: 'translateX(0)' })),
transition('void => *', [
style({ transform: 'translateX(-100%)' }),
animate(80),
]),
transition('* => void', [
animate(80, style({ transform: 'translateX(100%)' })),
]),
]),
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NbChatMessageComponent {
@HostBinding('@flyInOut')
get flyInOut() {
return true;
}
@HostBinding('class.not-reply')
get notReply() {
return !this.reply;
}
avatarStyle: SafeStyle;
/**
* Determines if a message is a reply
*/
@Input()
@HostBinding('class.reply')
get reply(): boolean {
return this._reply;
}
set reply(value: boolean) {
this._reply = convertToBoolProperty(value);
}
protected _reply: boolean = false;
static ngAcceptInputType_reply: NbBooleanInput;
@HostBinding('class.not-last-of-a-group')
get notLastOfAGroup() {
return !this.lastOfAGroup;
}
/**
* Determines if a message is a the last of a group
*/
@Input()
@HostBinding('class.last-of-a-group')
get lastOfAGroup(): boolean {
return this._lastOfAGroup;
}
set lastOfAGroup(value: boolean) {
this._lastOfAGroup = convertToBoolProperty(value);
}
protected _lastOfAGroup: boolean = false;
static ngAcceptInputType_lastOfAGroup: NbBooleanInput;
/**
* Determines if a message is a the first of the day
*/
@Input() firstOfTheDay: boolean;
/**
* Message sender
* @type {string}
*/
@Input() message: string;
/**
* Message sender
* @type {string}
*/
@Input() sender: string;
/**
* Message send date
* @type {Date}
*/
@Input() date: Date;
/**
* Message send date format, default 'shortTime'
* @type {string}
*/
@Input() dateFormat: string;
/**
* Array of files `{ url: 'file url', icon: 'file icon class' }`
*/
@Input() files: NbChatMessageFile[];
/**
* Quoted message text
* @type {string}
*/
@Input() quote: string;
/**
* Map latitude
* @type {number}
*/
@Input() latitude: number;
/**
* Map longitude
* @type {number}
*/
@Input() longitude: number;
/**
* Message send avatar
* @type {string}
*/
@Input()
set avatar(value: string) {
this.avatarStyle = value ? this.domSanitizer.bypassSecurityTrustStyle(`url(${value})`) : null;
}
/**
* Message type, available options `text|file|map|quote`
* @type {string}
*/
@Input() type: string;
constructor(protected domSanitizer: DomSanitizer) { }
getInitials(): string {
if (this.sender) {
const names = this.sender.split(' ');
return names.map(n => n.charAt(0)).splice(0, 2).join('').toUpperCase();
}
return '';
}
}