$(document).ready(function () {
function cleanupStaleModalState() {
if (!document.querySelector('.modal.show')) {
document.querySelectorAll('.modal-backdrop').forEach(function (backdrop) {
backdrop.remove();
});
document.body.classList.remove('modal-open');
document.body.style.removeProperty('padding-right');
document.body.style.removeProperty('overflow');
}
}
function getNotificationBadge() {
return document.getElementById('notification-badge');
}
function updateNotificationBadge(count) {
const badge = getNotificationBadge();
if (!badge) {
return;
}
const safeCount = Math.max(0, parseInt(count || 0, 10));
badge.dataset.count = String(safeCount);
badge.classList.toggle('d-none', safeCount === 0);
}
function incrementNotificationBadge() {
const badge = getNotificationBadge();
if (!badge) {
return;
}
const current = parseInt(badge.dataset.count || '0', 10);
updateNotificationBadge(current + 1);
}
function markNotificationRead(notificationId) {
if (!notificationId || !window.notificationsReadUrlTemplate) {
return;
}
fetch(window.notificationsReadUrlTemplate.replace('__id__', String(notificationId)), {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'Accept': 'application/json',
},
keepalive: true,
})
.then(function (response) {
if (!response.ok) {
return null;
}
return response.json();
})
.then(function (data) {
if (data && typeof data.unread !== 'undefined') {
updateNotificationBadge(data.unread);
}
})
.catch(function () {
// noop
});
}
function appendWsPopup(notification) {
const container = document.getElementById('ws-notification-container');
if (!container || !notification) {
return;
}
const popup = document.createElement('div');
popup.className = 'ws-notification-popup';
popup.dataset.id = String(notification.id || '');
const safeTitle = notification.title || 'Уведомление';
const bodyHtml = notification.message_html || notification.message || '';
popup.innerHTML =
'
' +
'' + bodyHtml + '
';
const closeBtn = popup.querySelector('.ws-notification-close');
if (closeBtn) {
closeBtn.addEventListener('click', function (event) {
event.stopPropagation();
markNotificationRead(notification.id);
popup.remove();
});
}
container.appendChild(popup);
}
cleanupStaleModalState();
window.addEventListener('pageshow', cleanupStaleModalState);
if ($('.main-alert').length) {
setTimeout(function () {
$('.main-alert').fadeTo(2000, 500).slideUp(500, function () {
$('.main-alert').slideUp(500);
});
}, 3000);
}
const user = localStorage.getItem('user');
if (user > 0) {
const socket = new WebSocket(localStorage.getItem('socketAddress'));
socket.onopen = function () {
console.log('[WS] Connected. Listen messages for user ' + user);
};
socket.onmessage = function (event) {
const received = JSON.parse(event.data);
if (parseInt(received.data.user_id, 10) !== parseInt(user, 10)) {
return;
}
const action = received.data.action;
if (action === 'persistent_notification') {
incrementNotificationBadge();
appendWsPopup(received.data.notification);
return;
}
if (action !== 'message') {
return;
}
if (received.data.payload.download) {
document.location.href = '/storage/export/' + received.data.payload.download;
}
if (received.data.payload.link) {
document.location.href = received.data.payload.link;
setTimeout(function () {
document.location.reload();
}, 2000);
}
setTimeout(function () {
if (received.data.payload.error) {
$('.alerts').append('' + received.data.message + '
');
} else {
$('.alerts').append('' + received.data.message + '
');
}
setTimeout(function () {
$('.main-alert2').fadeTo(2000, 500).slideUp(500, function () {
$('.main-alert2').slideUp(500);
});
}, 3000);
}, 1000);
};
socket.onclose = function (event) {
if (event.wasClean) {
console.log('[WS] Closed clear, code=' + event.code + ' reason=' + event.reason);
} else {
console.log('[WS] Connection lost', event);
}
};
socket.onerror = function (error) {
console.log('[error]', error);
};
}
});