Files
project-minnesota/resources/js/notification.js
2024-06-12 19:51:59 +02:00

144 lines
4.0 KiB
JavaScript

import {renderToaster, renderToast} from './notification/ui';
import registerSwipe from './notification/touch';
const VISIBLE_TOASTS_AMOUNT = 3;
const TOAST_LIFETIME = 4000;
const GAP = 14;
const TIME_BEFORE_UNMOUNT = 200;
window.ToastinTakin = {
init() {
if (reinitializeToaster()) {
return;
}
renderToaster();
const toaster = document.getElementById("toaster");
registerMouseOver(toaster);
registerKeyboardShortcuts(toaster);
},
success(msg) {
ToastinTakin.show(msg, "success");
},
error(msg) {
ToastinTakin.show(msg, "error");
},
info(msg) {
ToastinTakin.show(msg, "info");
},
warning(msg) {
ToastinTakin.show(msg, "warning");
},
show(msg, type) {
const list = document.getElementById("toaster");
const { toast, id } = renderToast(list, msg, type);
const el = list.children[0];
const height = el.getBoundingClientRect().height;
el.dataset.initialHeight = height;
el.dataset.hidden = false;
list.style.setProperty("--front-toast-height", `${height}px`);
registerSwipe(id);
refreshProperties();
if(list.dataset.expanded === "false") {
registerRemoveTimeout(el);
}
},
remove(id) {
const el = document.querySelector(`[data-toast-id="${id}"]`);
if (!el) {
return;
}
el.dataset.removed = true;
refreshProperties();
const previousTid = el.dataset.unmountTid;
if (previousTid) window.clearTimeout(previousTid);
const tid = window.setTimeout(function () {
el.parentElement?.removeChild(el);
}, TIME_BEFORE_UNMOUNT);
el.dataset.unmountTid = tid;
},
};
function registerRemoveTimeout(el) {
const tid = window.setTimeout(function () {
ToastinTakin.remove(el.dataset.toastId);
}, TOAST_LIFETIME);
el.dataset.removeTid = tid;
}
function reinitializeToaster() {
const ol = document.getElementById("toaster");
if (!ol) {
return;
}
for (let i = 0; i < ol.children.length; i++) {
const el = ol.children[i];
const id = el.dataset.toastId;
registerSwipe(id);
refreshProperties();
registerRemoveTimeout(el);
}
return ol;
}
function registerMouseOver(ol) {
ol.addEventListener("mouseenter", function () {
ol.dataset.expanded = true;
for(let el of ol.children) {
clearRemoveTimeout(el);
}
});
ol.addEventListener("mouseleave", function () {
ol.dataset.expanded = false;
for(let el of ol.children) {
registerRemoveTimeout(el);
}
});
}
function registerKeyboardShortcuts(ol) {
window.addEventListener("keydown", function (e) {
if (e.altKey && e.code === "KeyT") {
if (ol.children.length === 0) {
return;
}
e.preventDefault();
ol.dataset.expanded = ol.dataset.expanded === "true" ? "false" : "true";;
}
});
}
function clearRemoveTimeout(el) {
const tid = el.dataset.removeTid;
if (tid) window.clearTimeout(tid);
}
function refreshProperties() {
const list = document.getElementById("toaster");
let heightsBefore = 0;
let removed = 0;
for (let i = 0; i < list.children.length; i++) {
const el = list.children[i];
if (el.dataset.removed === "true") {
removed++;
continue;
}
const idx = i - removed;
el.dataset.index = idx;
el.dataset.front = (idx === 0).toString();
el.dataset.hidden = (idx > VISIBLE_TOASTS_AMOUNT).toString();
el.style.setProperty("--index", idx);
el.style.setProperty("--offset", `${GAP * idx + heightsBefore}px`);
el.style.setProperty("z-index", list.children.length - i);
heightsBefore += Number(el.dataset.initialHeight);
}
list.style.setProperty('--full-height', `${heightsBefore + GAP * list.children.length}px`);
}