fchat-rising/site/flash_display.ts

93 lines
2.7 KiB
TypeScript

import Vue from 'vue';
export type flashMessageType = 'info' | 'success' | 'warning' | 'danger';
let boundHandler;
interface FlashComponent extends Vue {
lastId: number
floating: boolean
messages: {
id: number
message: string
classes: string
}[]
removeMessage(id: number)
}
export function addFlashMessage(type: flashMessageType, message: string): void {
instance.addMessage(type, message);
}
function bindEventHandler(vm): void {
boundHandler = eventHandler.bind(vm);
document.addEventListener('scroll', boundHandler);
document.addEventListener('resize', boundHandler);
}
function removeHandlers(): void {
document.removeEventListener('scroll', boundHandler);
document.removeEventListener('resize', boundHandler);
boundHandler = undefined;
}
function eventHandler(this: FlashComponent): void {
const isElementVisible = (el: Element): boolean => {
const rect = el.getBoundingClientRect();
const vHeight = window.innerWidth || document.documentElement.clientHeight;
const vWidth = window.innerWidth || document.documentElement.clientWidth;
const efp = (x, y) => document.elementFromPoint(x, y);
if(rect.top > vHeight || rect.bottom < 0 || rect.left > vWidth || rect.right < 0)
return false;
return true;
//return (el.contains(efp(rect.left, rect.top)) || el.contains(efp(rect.right, rect.top)));
};
this.floating = !isElementVisible(this.$refs['detector'] as Element);
}
function addMessage(this: FlashComponent, type: flashMessageType, message: string): void {
if(!boundHandler) {
bindEventHandler(this);
boundHandler();
}
const newId = this.lastId++;
this.messages.push({id: newId, message, classes: `flash-message alert-${type}`});
setTimeout(() => {
this.removeMessage(newId);
}, 15000);
}
function removeMessage(id: number): void {
this.messages = this.messages.filter(function(item) {
return item['id'] !== id;
});
if(this.messages.length === 0)
removeHandlers();
}
interface FlashMessageManager {
addMessage(type: flashMessageType, message: string): void
removeMessage(id: number): void
}
const instance: Vue & FlashMessageManager = new Vue({
template: '#flashMessagesTemplate',
el: '#flashMessages',
data() {
return {
lastId: 1,
messages: [],
floating: false
};
},
computed: {
containerClasses(this: FlashComponent): string {
return this.floating ? 'flash-messages-fixed' : 'flash-messages';
}
},
methods: {
addMessage,
removeMessage
}
}) as Vue & FlashMessageManager;