157 lines
4.7 KiB
JavaScript
157 lines
4.7 KiB
JavaScript
class NotifyBubble {
|
|
constructor(trayButton, bubbleSelector) {
|
|
this.button = trayButton;
|
|
this.bubble = document.querySelector(bubbleSelector);
|
|
this.hideTimeout = null;
|
|
this.initEvents();
|
|
this.initExistingItems();
|
|
this.updateCounter(); // 🔥 initialer Counter
|
|
}
|
|
|
|
/* =========================
|
|
SHOW / HIDE
|
|
========================== */
|
|
show() {
|
|
clearTimeout(this.hideTimeout);
|
|
this.button.classList.add("active");
|
|
|
|
// Tooltip entfernen beim Öffnen
|
|
this.button.removeAttribute('data-tooltip');
|
|
}
|
|
|
|
hide(delay = 1000) {
|
|
clearTimeout(this.hideTimeout);
|
|
|
|
this.hideTimeout = setTimeout(() => {
|
|
this.button.classList.remove("active");
|
|
|
|
// 🔥 Counter nach Schließen anzeigen
|
|
this.updateCounter();
|
|
|
|
}, delay);
|
|
}
|
|
|
|
/* =========================
|
|
COUNTER / TOOLTIP
|
|
========================== */
|
|
updateCounter() {
|
|
const items = this.bubble.querySelectorAll(".bubble-item");
|
|
const count = items.length;
|
|
|
|
if (!this.button.classList.contains("active") && count > 0) {
|
|
this.button.setAttribute('data-tooltip', `${count} neue Benachrichtigung${count > 1 ? 'en' : ''}`);
|
|
} else {
|
|
this.button.setAttribute('data-tooltip', "Keine Benachrichtigungen");
|
|
}
|
|
}
|
|
|
|
/* =========================
|
|
EVENTS
|
|
========================== */
|
|
initEvents() {
|
|
// Toggle bei Klick auf Button
|
|
this.button.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
|
|
if (this.button.classList.contains("active")) {
|
|
this.hide(0);
|
|
} else {
|
|
this.show();
|
|
}
|
|
});
|
|
|
|
// Klick innerhalb der Bubble soll NICHT schließen
|
|
this.bubble.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Klick irgendwo anders → schließen
|
|
document.addEventListener("click", () => {
|
|
if (this.button.classList.contains("active")) {
|
|
this.hide(0);
|
|
}
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
INIT EXISTING ITEMS
|
|
========================== */
|
|
initExistingItems() {
|
|
this.bubble.querySelectorAll(".bubble-item").forEach(item => {
|
|
this.attachItemEvents(item);
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
ITEM EVENTS
|
|
========================== */
|
|
attachItemEvents(item) {
|
|
item.addEventListener("click", () => {
|
|
const checkbox = item.querySelector("input[type='checkbox']");
|
|
if (checkbox) {
|
|
checkbox.checked = !checkbox.checked;
|
|
|
|
fetch('/api/NotifyTray/markAsSeen', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
id: item.dataset.id,
|
|
value: checkbox.checked
|
|
})
|
|
});
|
|
|
|
// 🔥 Counter ggf. aktualisieren
|
|
this.updateCounter();
|
|
}
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
ADD SINGLE ITEM
|
|
========================== */
|
|
addItem(notification) {
|
|
const item = document.createElement("label");
|
|
item.className = "bubble-item";
|
|
item.dataset.id = notification.ID;
|
|
|
|
item.innerHTML = `
|
|
<div>${notification.Message}</div>
|
|
|
|
<div style="display:flex;flex-direction:row;flex-wrap:no-wrap;justify-content:flex-end;gap:10px;align-items:center;">
|
|
<div>
|
|
<div>${dateFormat(notification.CreatedAt, 'dd.mm.yyyy HH:MM:SS')}</div>
|
|
<div>${notification.PluginName}</div>
|
|
</div>
|
|
<div>
|
|
<label class="cb cb-modern">
|
|
<input id="notification_${notification.ID}" type="checkbox">
|
|
<span class="cb-box"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
this.attachItemEvents(item);
|
|
this.bubble.appendChild(item);
|
|
|
|
// 🔥 Counter aktualisieren
|
|
this.updateCounter();
|
|
}
|
|
|
|
/* =========================
|
|
ADD MULTIPLE ITEMS
|
|
========================== */
|
|
addItems(notifications) {
|
|
notifications.forEach(n => this.addItem(n));
|
|
}
|
|
|
|
/* =========================
|
|
CLEAR
|
|
========================== */
|
|
clear() {
|
|
this.bubble.innerHTML = "";
|
|
this.updateCounter();
|
|
}
|
|
} |