codepens/lotsa-notifications/dist/script.js

289 lines
6.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

window.addEventListener("DOMContentLoaded",() => {
const nc = new NotificationCenter();
});
class NotificationCenter {
constructor() {
this.items = [];
this.itemsToKill = [];
this.messages = NotificationMessages();
this.killTimeout = null;
this.spawnNotes(3);
}
spawnNote() {
const id = this.random(0,2**32,true).toString(16);
const draw = this.random(0,this.messages.length - 1,true);
const message = this.messages[draw];
const note = new Notification({
id: `note-${id}`,
icon: message.icon,
title: message.title,
subtitle: message.subtitle,
actions: message.actions
});
const transY = 100 * this.items.length;
note.el.style.transform = `translateY(${transY}%)`;
note.el.addEventListener("click",this.killNote.bind(this,note.id));
this.items.push(note);
}
spawnNotes(amount) {
let count = typeof amount === "number" ? amount : this.random(1,5,true);
while (count--)
this.spawnNote();
}
killNote(id,e) {
const note = this.items.find(item => item.id === id);
const tar = e.target;
if (note && tar.getAttribute("data-dismiss") === id) {
note.el.classList.add("notification--out");
this.itemsToKill.push(note);
clearTimeout(this.killTimeout);
this.killTimeout = setTimeout(() => {
this.itemsToKill.forEach(itemToKill => {
document.body.removeChild(itemToKill.el);
const left = this.items.filter(item => item.id !== itemToKill.id);
this.items = [...left];
});
this.itemsToKill = [];
if (!this.items.length)
this.spawnNotes();
else
this.spawnNotes(this.random(0,1,true));
this.shiftNotes();
},note.killTime);
}
}
shiftNotes() {
this.items.forEach((item,i) => {
const transY = 100 * i;
item.el.style.transform = `translateY(${transY}%)`;
});
}
random(min,max,round = false) {
const percent = crypto.getRandomValues(new Uint32Array(1))[0] / 2**32;
const relativeValue = (max - min) * percent;
return min + (round === true ? Math.round(relativeValue) : +relativeValue.toFixed(2));
}
}
class Notification {
constructor(args) {
this.args = args;
this.el = null;
this.id = null;
this.killTime = 300;
this.init(args);
}
init(args) {
const {id,icon,title,subtitle,actions} = args;
const block = "notification";
const parent = document.body;
const xmlnsSVG = "http://www.w3.org/2000/svg";
const xmlnsUse = "http://www.w3.org/1999/xlink";
const note = this.newEl("div");
note.id = id;
note.className = block;
parent.insertBefore(note,parent.lastElementChild);
const box = this.newEl("div");
box.className = `${block}__box`;
note.appendChild(box);
const content = this.newEl("div");
content.className = `${block}__content`;
box.appendChild(content);
const _icon = this.newEl("div");
_icon.className = `${block}__icon`;
content.appendChild(_icon);
const iconSVG = this.newEl("svg",xmlnsSVG);
iconSVG.setAttribute("class",`${block}__icon-svg`);
iconSVG.setAttribute("role","img");
iconSVG.setAttribute("aria-label",icon);
iconSVG.setAttribute("width","32px");
iconSVG.setAttribute("height","32px");
_icon.appendChild(iconSVG);
const iconUse = this.newEl("use",xmlnsSVG);
iconUse.setAttributeNS(xmlnsUse,"href",`#${icon}`);
iconSVG.appendChild(iconUse);
const text = this.newEl("div");
text.className = `${block}__text`;
content.appendChild(text);
const _title = this.newEl("div");
_title.className = `${block}__text-title`;
_title.textContent = title;
text.appendChild(_title);
if (subtitle) {
const _subtitle = this.newEl("div");
_subtitle.className = `${block}__text-subtitle`;
_subtitle.textContent = subtitle;
text.appendChild(_subtitle);
}
const btns = this.newEl("div");
btns.className = `${block}__btns`;
box.appendChild(btns);
actions.forEach(action => {
const btn = this.newEl("button");
btn.className = `${block}__btn`;
btn.type = "button";
btn.setAttribute("data-dismiss",id);
const btnText = this.newEl("span");
btnText.className = `${block}__btn-text`;
btnText.textContent = action;
btn.appendChild(btnText);
btns.appendChild(btn);
});
this.el = note;
this.id = note.id;
}
newEl(elName,NSValue) {
if (NSValue)
return document.createElementNS(NSValue,elName);
else
return document.createElement(elName);
}
}
function NotificationMessages() {
return [
{
icon: "error",
title: "Oh No",
subtitle: "Something really bad happened.",
actions: ["Close"]
},
{
icon: "error",
title: "Error",
subtitle: "The operation completed successfully.",
actions: ["OK"]
},
{
icon: "error",
title: "Critical Error",
subtitle: "An error has occurred while trying to display an error notification.",
actions: ["OK"]
},
{
icon: "warning",
title: "Reminder",
subtitle: "You will receive more notifications.",
actions: ["Close"]
},
{
icon: "warning",
title: "Failed to Save Changes",
actions: ["Retry","Cancel"]
},
{
icon: "warning",
title: "Download Failed",
actions: ["Retry","Cancel"]
},
{
icon: "warning",
title: "Cannot Send Mail",
subtitle: "The message was rejected by the server because it is too large.",
actions: ["OK"]
},
{
icon: "warning",
title: "Disk Not Ejected Properly",
subtitle: "Eject “CopyThisFloppy” before disconnecting or turning it off.",
actions: ["Close"]
},
{
icon: "warning",
title: "Notifications",
subtitle: "Notifications may include alerts, sounds, and icon badges.",
actions: ["Dont Allow","Allow"]
},
{
icon: "success",
title: "Changes Saved",
actions: ["OK"]
},
{
icon: "success",
title: "Download Complete",
actions: ["OK"]
},
{
icon: "success",
title: "Yippee",
subtitle: "Nothing bad happened.",
actions: ["OK"]
},
{
icon: "message",
title: "Mail Password Required",
subtitle: "Enter your password for user@domain.com.",
actions: ["Close","Continue"]
},
{
icon: "message",
title: "Mail",
subtitle: "You have 10 new messages.",
actions: ["Read","Dismiss"]
},
{
icon: "clock",
title: "Coffee Break",
subtitle: "In 5 minutes",
actions: ["Close","Snooze"]
},
{
icon: "clock",
title: "Muffin Time",
subtitle: "12:30 PM",
actions: ["Close","Snooze"]
},
{
icon: "clock",
title: "Hammer Time",
subtitle: "In 2 minutes",
actions: ["Close","Snooze"]
},
{
icon: "up",
title: "Upgrade Available",
subtitle: "Enjoy the latest technologies and refinements to your favorite apps.",
actions: ["Install","Details"]
},
{
icon: "up",
title: "Upgrade Waiting",
subtitle: "Get it now, or it wont be long until you are far behind everyone else.",
actions: ["Install","Details"]
},
{
icon: "up",
title: "Upgrade Now",
subtitle: "The current version will soon be obsolete. What are you waiting for?",
actions: ["Install","Details"]
}
];
}