// Показывает модальное окно со списком задач function showUnreadNotification(tasks) { const modalHtml = ` `; let modal = document.getElementById('unread-notification-modal'); if (modal) modal.remove(); const container = document.createElement('div'); container.innerHTML = modalHtml; document.body.appendChild(container); modal = document.getElementById('unread-notification-modal'); modal.style.display = 'block'; // Добавляем стили (если ещё не добавлены) if (!document.getElementById('unread-notification-styles')) { const style = document.createElement('style'); style.id = 'unread-notification-styles'; style.textContent = ` #unread-notification-modal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); animation: fadeIn 0.3s; } #unread-notification-modal .modal-content { animation: slideIn 0.3s ease-out; background-color: #fefefe; margin: 5% auto; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.2); overflow: hidden; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideIn { from { transform: translateY(-50px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } `; document.head.appendChild(style); } } function closeUnreadNotification() { const modal = document.getElementById('unread-notification-modal'); if (modal) { modal.style.display = 'none'; setTimeout(() => modal.remove(), 300); } } // Вспомогательная функция для склонения function pluralize(count, words) { const cases = [2, 0, 1, 1, 1, 2]; return words[(count % 100 > 4 && count % 100 < 20) ? 2 : cases[Math.min(count % 10, 5)]]; } // Экранирование HTML в заголовке задачи (защита от XSS) function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // Открывает чат задачи и помечает все сообщения как прочитанные function openTaskAndMarkRead(taskId) { closeUnreadNotification(); // Опционально: сразу отмечаем все сообщения прочитанными fetch(`/api/chat/tasks/${taskId}/mark-read`, { method: 'POST' }) .catch(err => console.warn('Не удалось отметить сообщения как прочитанные', err)) .finally(() => openTaskChat(taskId)); } // Проверка наличия непрочитанных сообщений function checkUnreadMessages() { // Не беспокоим пользователя, если страница не активна if (document.hidden) return; fetch('/api/chat/unread-summary') .then(response => { if (response.status === 401) return null; // пользователь не авторизован return response.json(); }) .then(data => { if (data && data.totalUnread > 0) { showUnreadNotification(data.tasks); } }) .catch(err => console.error('Ошибка проверки новых сообщений:', err)); } // Запуск периодической проверки (раз в 5 минут) setInterval(checkUnreadMessages, 5 * 60 * 1000); // Проверка при загрузке страницы document.addEventListener('DOMContentLoaded', checkUnreadMessages);