const FIRST_THRESHOLD = 80; const SECOND_THRESHOLD = 160; const CLOSE_THRESHOLD = 40; const MAX_SWIPE = 200; let dotnetHelper; window.initNotifications = (dotnetRef) => { dotnetHelper = dotnetRef; document.querySelectorAll('.row').forEach(initRow); }; function initRow(row) { const card = row.querySelector('.notification-card'); const btnTrash = row.querySelector('.trash-btn'); const btnRead = row.querySelector('.read-btn'); const behindRight = row.querySelector('.behind-right'); // cestino const behindLeft = row.querySelector('.behind-left'); // mark as read let startX = 0, currentX = 0, dragging = false; let open = null; // "left", "right" oppure null // inizializza nascosti behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; // funzione di utilità → controlla se c'è unread-dot function canMarkAsRead() { return row.querySelector('.unread-dot') !== null; } card.addEventListener('pointerdown', (e) => { if (e.pointerType === 'mouse' && e.button !== 0) return; dragging = true; startX = e.clientX; card.setPointerCapture(e.pointerId); card.style.transition = 'none'; }); card.addEventListener('pointermove', (e) => { if (!dragging) return; const dx = e.clientX - startX; if (dx > 0 && !canMarkAsRead() && !open) { currentX = 0; return; // niente movimento } let translate = dx; if (!open) { translate = Math.max(-MAX_SWIPE, Math.min(MAX_SWIPE, dx)); } else if (open === "left") { translate = Math.min(MAX_SWIPE, FIRST_THRESHOLD + dx); } else if (open === "right") { translate = Math.max(-MAX_SWIPE, -FIRST_THRESHOLD + dx); } currentX = translate; card.style.transform = `translateX(${translate}px)`; // mostra/nascondi i behind in tempo reale if (currentX < 0) { behindRight.style.visibility = "visible"; // cestino behindLeft.style.visibility = "hidden"; } else if (currentX > 0) { behindLeft.style.visibility = "visible"; // mark as read behindRight.style.visibility = "hidden"; } else { behindLeft.style.visibility = "hidden"; behindRight.style.visibility = "hidden"; } }); function endDrag() { if (!dragging) return; dragging = false; card.style.transition = 'transform .2s ease'; // blocca swipe destro se non consentito if (currentX > 0 && !canMarkAsRead() && !open) { card.style.transform = 'translateX(0)'; currentX = 0; open = null; behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; return; } // Swipe a sinistra → elimina if (!open && currentX < 0) { if (currentX < -SECOND_THRESHOLD) { card.style.transform = `translateX(-${MAX_SWIPE}px)`; setTimeout(() => removeRow(row), 200); } else if (currentX < -FIRST_THRESHOLD) { card.style.transform = `translateX(-${FIRST_THRESHOLD}px)`; open = "right"; } else { card.style.transform = 'translateX(0)'; open = null; behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; } } // Swipe a destra → mark as read SOLO se consentito else if (!open && currentX > 0) { if (currentX > SECOND_THRESHOLD) { card.style.transform = `translateX(${MAX_SWIPE}px)`; setTimeout(() => markAsRead(row), 200); } else if (currentX > FIRST_THRESHOLD) { card.style.transform = `translateX(${FIRST_THRESHOLD}px)`; open = "left"; } else { card.style.transform = 'translateX(0)'; open = null; behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; } } // Se già aperta, gestisci chiusura else { if (open === "right" && currentX > -FIRST_THRESHOLD + CLOSE_THRESHOLD) { card.style.transform = 'translateX(0)'; open = null; behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; } else if (open === "left" && currentX < FIRST_THRESHOLD - CLOSE_THRESHOLD) { card.style.transform = 'translateX(0)'; open = null; behindRight.style.visibility = "hidden"; behindLeft.style.visibility = "hidden"; } else if (open) { card.style.transform = `translateX(${open === "right" ? -FIRST_THRESHOLD : FIRST_THRESHOLD}px)`; } } } card.addEventListener('pointerup', endDrag); card.addEventListener('pointercancel', endDrag); btnTrash.addEventListener('click', () => removeRow(row)); btnRead.addEventListener('click', () => markAsRead(row)); } function removeRow(row) { //collapseAndRemove(row); dotnetHelper.invokeMethodAsync('Delete', row.id); } function markAsRead(row) { //collapseAndRemove(row); dotnetHelper.invokeMethodAsync('MarkAsRead', row.id); } function collapseAndRemove(row) { const h = row.getBoundingClientRect().height; row.style.height = h + 'px'; row.classList.add('collapsing'); requestAnimationFrame(() => { row.style.opacity = '0'; row.style.marginTop = '0'; row.style.marginBottom = '0'; row.style.height = '0'; }); setTimeout(() => row.remove(), 220); }