js/controllers/NotificationBubbleViewController.js
import ViewController from '~/controllers/ViewController';
import NotificationData from '~/models/Request/NotificationData';
import PopoverViewController from '~/controllers/PopoverViewController';
import NotificationListTemplate from '~/template/NotificationListTemplate';
import { HandleUnhandledPromise } from '~/helpers/ErrorManager';
import Template, { TemplateType } from '~/template/Template';
/**
* Notification bubble to click on
*/
export default class NotificationBubbleViewController extends ViewController {
/**
* @param {Element} bubble The wrapper bubble
* @param {Element} dropdownContainer - relative point to add dropdown
*/
constructor(bubble, dropdownContainer) {
super(bubble);
this._overlay = <div class="notification-button__overlay notification-button__overlay--indicator-count"/>;
this._countText = document.createTextNode('');
this._overlayText = <div class="notification-button__overlay notification-button__overlay--text"><span>{ this._countText }</span></div>;
this._showingCount = false;
bubble.appendChild(this._overlay);
bubble.appendChild(this._overlayText);
const notificationList = new NotificationListTemplate();
dropdownContainer.appendChild(notificationList.unique());
const popover = new PopoverViewController(
null,
bubble,
notificationList
);
popover.delegate.didSetStateTo = (_, state) => {
if (state) {
this.hideCount()
.catch(HandleUnhandledPromise);
}
};
return (async () => {
const notificationData = await new NotificationData().run();
if (notificationData.unseenCount > 0) {
await this.showCount(notificationData.unseenCount);
}
return this;
})();
}
/**
* Displays the count of unseen
* @param {number} count
*/
async showCount(count) {
this._countText.data = String(count);
if (this._showingCount) return;
this._showingCount = true;
const anime = await import('animejs');
anime.timeline()
.add({
targets: this._overlay,
width: ['0%', '100%'],
height: ['0%', '100%'],
easing: 'easeOutElastic',
elasticity: 300,
duration: 700
})
.add({
targets: this._overlayText,
fontSize: ['0em', '1em'],
easing: 'easeOutElastic',
elasticity: 600,
duration: 1200,
offset: 100
});
}
/**
* Hides the count of unseen notifs
*/
async hideCount() {
this._showingCount = false;
const anime = await import('animejs');
anime.timeline()
.add({
targets: this._overlayText,
fontSize: 0,
easing: 'easeInElastic',
elasticity: 300,
duration: 700
})
.add({
targets: this._overlay,
width: 0,
height: 0,
easing: 'easeInElastic',
elasticity: 600,
duration: 900,
offset: 0
});
}
}