import {
Component, OnInit, OnDestroy, Input, AnimationTransitionEvent, trigger, state,
transition, style, animate
} from '@angular/core';
import { Notice } from "./notifier-notice";
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
import { NotifierService } from "./notifier.service";
@Component({
selector: 'ng2-notifier-message',
template: `<div [@enterLeave]="notice.state" (@enterLeave.done)="animationDone($event)" (click)="onClick()" (mouseenter)="onEnter()" (mouseleave)="onLeave()" class="notifier-message {{notice.type}}"><div class="{{notice.config.titleClass || 'title'}}">{{notice.title}}</div><div class="{{notice.config.messageClass || 'content'}}">{{notice.content}}</div><div [innerHTML]="safeSvg"></div></div>`,
styles: [`.notifier-message,.timer{-moz-border-radius:.3rem}.notifier-message{font-size:12px;font-size:.75rem;line-height:20px;line-height:1.25rem;position:relative;width:272px;width:17rem;min-height:48px;min-height:3rem;border-radius:.3rem;margin-bottom:10px;margin-bottom:.625rem;padding:10px;padding:.625rem;color:#333;background-color:#fff;border-color:#ccc;-moz-box-shadow:0 0 8px 3px rgba(255,254,247,.75);box-shadow:0 0 8px 3px rgba(255,254,247,.75);cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.notifier-message .title{font-size:16px;font-size:1rem;line-height:20px;line-height:1.25rem}.notifier-message .content,.notifier-message .title{padding-right:48px;padding-right:3rem}.notifier-message.primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.notifier-message.success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.notifier-message.danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.notifier-message.warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}:host /deep/ .notifier-message svg{position:absolute;-moz-box-sizing:border-box;box-sizing:border-box;top:0;right:0;width:48px;width:3rem;height:48px;height:3rem;padding:10px;padding:.625rem;fill:#fff}.timer{position:absolute;top:0;left:0;width:100%;height:4px;border-radius:.3rem}.timer .bar{display:block;position:relative;height:100%;-moz-border-radius:.3rem;border-radius:.3rem;background:rgba(0,0,0,.3);-webkit-transition:width .1s ease;-moz-transition:width .1s ease;transition:width .1s ease}`],
animations: [
trigger('enterLeave', [
// Enter from right
state('flyRight', style({opacity: 1, transform: 'translateX(0)'})),
state('flyRightOut', style({opacity: 0, transform: 'translateX(-10%)'})),
transition('void => flyRight', [
style({opacity: 0, transform: 'translateX(10%)'}),
animate('400ms ease-in-out')
]),
transition('flyRight => flyRightOut', [
animate('300ms ease-in-out', style({opacity: 0, transform: 'translateX(-10%)'}))
]),
// Enter from left
state('flyLeft', style({opacity: 1, transform: 'translateX(0)'})),
state('flyLeftOut', style({opacity: 0, transform: 'translateX(10%)'})),
transition('* => flyLeft', [
style({opacity: 0, transform: 'translateX(-10%)'}),
animate('400ms ease-in-out')
]),
transition('flyLeft => flyLeftOut', [
animate('300ms ease-in-out', style({opacity: 0, transform: 'translateX(10%)'}))
]),
// Scale
state('scale', style({opacity: 1, transform: 'scale(1)'})),
state('scaleOut', style({opacity: 0, transform: 'scale(0)'})),
transition('* => scale', [
style({opacity: 0, transform: 'scale(0)'}),
animate('400ms ease-in-out')
]),
transition('scale => scaleOut', [
style({opacity: 1, transform: 'scale(1)'}),
animate('400ms ease-in-out')
]),
// Rotate
state('rotate', style({opacity: 1, transform: 'rotate(0deg)'})),
state('rotateOut', style({opacity: 0, transform: 'rotate(-5deg)'})),
transition('* => rotate', [
style({opacity: 0, transform: 'rotate(5deg)'}),
animate('400ms ease-in-out')
]),
transition('rotate => rotateOut', [
style({opacity: 1, transform: 'rotate(0deg)'}),
animate('400ms ease-in-out')
]),
// Fade
state('fade', style({opacity: 1})),
state('fadeOut', style({opacity: 0})),
transition('* => fade', [
style({opacity: 0}),
animate('400ms ease-in-out')
]),
transition('fade => fadeOut', [
style({opacity: 1}),
animate('400ms ease-in-out')
])
])
]
})
export class NotifierMessageComponent implements OnInit, OnDestroy {
@Input() notice: Notice;
private safeSvg: SafeHtml;
private timerId: number = 0;
private start: any;
private timeLeft: any;
constructor( private domSanitizer: DomSanitizer,
private notifierService: NotifierService ) {
}
ngOnInit() {
this.safeSvg = this.domSanitizer.bypassSecurityTrustHtml(this.notice.icon);
this.notice.state = this.notice.config.animate;
if (this.notice.config.notifierLife > 0) {
this.startTimer();
}
}
ngOnDestroy() {
this.clearTimer();
}
animationDone( event: AnimationTransitionEvent ): void {
if (event.toState == this.notice.config.animate + 'Out') {
this.notifierService.clear(this.notice);
}
}
onEnter(): void {
if (this.notice.config.pauseOnHover) {
this.timeLeft = this.notice.config.notifierLife;
this.timeLeft -= new Date().getTime() - this.start;
this.clearTimer();
}
}
onLeave(): void {
if (this.notice.config.pauseOnHover) {
if (!this.timeLeft) {
this.timeLeft = this.notice.config.notifierLife;
}
this.timerId = window.setTimeout(() => {
this.setStateOut();
}, this.timeLeft);
}
}
onClick(): void {
if (this.notice.config.clickToClose) {
this.setStateOut();
}
}
private startTimer(): void {
this.start = new Date().getTime();
this.timerId = window.setTimeout(() => {
this.setStateOut();
}, this.notice.config.notifierLife);
}
private clearTimer(): void {
clearTimeout(this.timerId);
}
private setStateOut(): void {
this.notice.state = this.notice.config.animate + 'Out';
this.clearTimer();
}
}