import {NgModule,Component,ElementRef,AfterViewInit,DoCheck,OnDestroy,Input,Output,ViewChild,EventEmitter,IterableDiffers,Optional} from '@angular/core'; import {CommonModule} from '@angular/common'; import {Message} from '../common/message'; import {DomHandler} from '../dom/domhandler'; import {MessageService} from '../common/messageservice'; import {Subscription} from 'rxjs/Subscription'; @Component({ selector: 'p-growl', template: `
{{msg.summary}}

`, providers: [DomHandler] }) export class Growl implements AfterViewInit,DoCheck,OnDestroy { @Input() life: number = 3000; @Input() style: any; @Input() styleClass: string; @Input() immutable: boolean = true; @Input() autoZIndex: boolean = true; @Input() baseZIndex: number = 0; @Input() key: string; @Output() onClick: EventEmitter = new EventEmitter(); @Output() onHover: EventEmitter = new EventEmitter(); @Output() onClose: EventEmitter = new EventEmitter(); @Output() valueChange: EventEmitter = new EventEmitter(); @ViewChild('container') containerViewChild: ElementRef; _sticky: boolean; _value: Message[]; timeout: any; preventRerender: boolean; differ: any; subscription: Subscription; closeIconClick: boolean; constructor(public el: ElementRef, public domHandler: DomHandler, public differs: IterableDiffers, @Optional() public messageService: MessageService) { this.differ = differs.find([]).create(null); if(messageService) { this.subscription = messageService.messageObserver.subscribe(messages => { if(messages) { if(messages instanceof Array) { let filteredMessages = messages.filter(m => this.key === m.key); this.value = this.value ? [...this.value, ...filteredMessages] : [...filteredMessages]; } else if (this.key === messages.key) { this.value = this.value ? [...this.value, ...[messages]] : [messages]; } } else { this.value = null; } }); } } ngAfterViewInit() { if(!this.sticky) { this.initTimeout(); } } @Input() get value(): Message[] { return this._value; } set value(val:Message[]) { this._value = val; if(this.containerViewChild && this.containerViewChild.nativeElement && this.immutable) { this.handleValueChange(); } } @Input() get sticky(): boolean { return this._sticky; } set sticky(value: boolean) { if(value && this.timeout) { clearTimeout(this.timeout); } this._sticky = value; } ngDoCheck() { if(!this.immutable && this.containerViewChild && this.containerViewChild.nativeElement) { let changes = this.differ.diff(this.value); if(changes) { this.handleValueChange(); } } } handleValueChange() { if(this.preventRerender) { this.preventRerender = false; return; } if(this.autoZIndex) { this.containerViewChild.nativeElement.style.zIndex = String(this.baseZIndex + (++DomHandler.zindex)); } this.domHandler.fadeIn(this.containerViewChild.nativeElement, 250); if(!this.sticky) { this.initTimeout(); } } initTimeout() { if(this.timeout) { clearTimeout(this.timeout); } this.timeout = setTimeout(() => { this.removeAll(); }, this.life); } remove(index: number, msgel: any) { this.closeIconClick = true; this.domHandler.fadeOut(msgel, 250); setTimeout(() => { this.preventRerender = true; this.onClose.emit({message:this.value[index]}); if(this.immutable) { this._value = this.value.filter((val,i) => i!=index); this.valueChange.emit(this._value); } else { this._value.splice(index, 1); } }, 250); } removeAll() { if(this.value && this.value.length) { this.domHandler.fadeOut(this.containerViewChild.nativeElement, 250); setTimeout(() => { this.value.forEach((msg,index) => this.onClose.emit({message:this.value[index]})); if(this.immutable) { this.value = []; this.valueChange.emit(this.value); } else { this.value.splice(0, this.value.length); } }, 250); } } onMessageClick(i: number) { if(this.closeIconClick) this.closeIconClick = false; else this.onClick.emit({message: this.value[i]}); } onMessageHover(i: number) { this.onHover.emit({message: this.value[i]}); } ngOnDestroy() { if(!this.sticky) { clearTimeout(this.timeout); } if(this.subscription) { this.subscription.unsubscribe(); } } } @NgModule({ imports: [CommonModule], exports: [Growl], declarations: [Growl] }) export class GrowlModule { }