import { Component, Input, OnInit } from '@angular/core';
import { isFunction } from './toasty.utils';
import { Ng2vToastyService, Ng2vToastData, Ng2vToastyConfig, Ng2vToastyEvent, Ng2vToastyEventType } from './toasty.service';
/**
* Toasty is container for Toast components
*/
@Component({
selector: 'ng2v-toasty',
template: `
`
})
export class Ng2vToastyComponent implements OnInit {
/**
* Set of constants defins position of Toasty on the page.
*/
static POSITIONS: Array = ['bottom-right', 'bottom-left', 'top-right', 'top-left', 'top-center', 'bottom-center', 'center-center'];
private _position: string = '';
// The window position where the toast pops up. Possible values:
// - bottom-right (default value from ToastConfig)
// - bottom-left
// - top-right
// - top-left
// - top-center
// - bottom-center
// - center-center
@Input() set position(value: string) {
if (value) {
let notFound = true;
for (let i = 0; i < Ng2vToastyComponent.POSITIONS.length; i++) {
if (Ng2vToastyComponent.POSITIONS[i] === value) {
notFound = false;
break;
}
}
if (notFound) {
// Position was wrong - clear it here to use the one from config.
value = this.config.position;
}
} else {
value = this.config.position;
}
this._position = 'toasty-position-' + value;
}
get position(): string {
return this._position;
}
// The storage for toasts.
toasts: Array = [];
constructor(private config: Ng2vToastyConfig, private toastyService: Ng2vToastyService) {
// Initialise position
this.position = '';
}
/**
* `ngOnInit` is called right after the directive's data-bound properties have been checked for the
* first time, and before any of its children have been checked. It is invoked only once when the
* directive is instantiated.
*/
ngOnInit(): any {
// We listen events from our service
this.toastyService.events.subscribe((event: Ng2vToastyEvent) => {
if (event.type === Ng2vToastyEventType.ADD) {
// Add the new one
let toast: Ng2vToastData = event.value;
this.add(toast);
} else if (event.type === Ng2vToastyEventType.CLEAR) {
// Clear the one by number
let id: number = event.value;
this.clear(id);
} else if (event.type === Ng2vToastyEventType.CLEAR_ALL) {
// Lets clear all toasts
this.clearAll();
}
});
}
/**
* Event listener of 'closeToast' event comes from ToastyComponent.
* This method removes ToastComponent assosiated with this Toast.
*/
closeToast(toast: Ng2vToastData) {
this.clear(toast.id);
}
/**
* Add new Toast
*/
add(toast: Ng2vToastData) {
// If we've gone over our limit, remove the earliest
// one from the array
if (this.toasts.length >= this.config.limit) {
this.toasts.shift();
}
// Add toasty to array
this.toasts.push(toast);
//
// If there's a timeout individually or globally,
// set the toast to timeout
if (toast.timeout) {
this._setTimeout(toast);
}
}
/**
* Clear individual toast by id
* @param id is unique identifier of Toast
*/
clear(id: number) {
if (id) {
this.toasts.forEach((value: any, key: number) => {
if (value.id === id) {
if (value.onRemove && isFunction(value.onRemove)) {
value.onRemove.call(this, value);
}
this.toasts.splice(key, 1);
}
});
} else {
throw new Error('Please provide id of Toast to close');
}
}
/**
* Clear all toasts
*/
clearAll() {
this.toasts.forEach((value: any, key: number) => {
if (value.onRemove && isFunction(value.onRemove)) {
value.onRemove.call(this, value);
}
});
this.toasts = [];
}
/**
* Custom setTimeout function for specific setTimeouts on individual toasts.
*/
private _setTimeout(toast: Ng2vToastData) {
window.setTimeout(() => {
this.clear(toast.id);
}, toast.timeout);
}
}