codepens/lotsa-notifications/dist/script.js

289 lines
6.8 KiB
JavaScript
Raw Normal View History

2023-10-06 23:12:53 +02:00
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"]
}
];
}