136 lines
4.1 KiB
JavaScript
136 lines
4.1 KiB
JavaScript
/**
|
||
* @fileoverview Chat Badge Manager - управление счётчиками непрочитанных сообщений
|
||
* Слушает события `chat:read` и обновляет бейджи для чатов
|
||
* @module components/chatBadgeManager
|
||
*/
|
||
|
||
/**
|
||
* Инициализирует менеджер бейджей непрочитанных сообщений
|
||
* @param {Object} options - Опции инициализации
|
||
* @param {string} [options.chatRowSelector='.chat-row'] - Селектор элементов чата
|
||
* @param {string} [options.badgeSelector='[data-unread]'] - Селектор бейджа
|
||
* @param {string} [options.countSelector='[data-unread-count]'] - Селектор счётчика
|
||
* @returns {Object|null} API менеджера или null
|
||
*/
|
||
export function initChatBadgeManager(options = {}) {
|
||
const {
|
||
chatRowSelector = '.chat-row',
|
||
badgeSelector = '[data-unread]',
|
||
countSelector = '[data-unread-count]'
|
||
} = options;
|
||
|
||
/**
|
||
* Обновляет бейдж для конкретного чата
|
||
* @param {string} chatId - ID чата
|
||
* @param {number} count - Количество непрочитанных (0 = скрыть бейдж)
|
||
*/
|
||
function updateBadge(chatId, count = 0) {
|
||
const row = document.querySelector(`${chatRowSelector}[data-chat-id="${chatId}"]`);
|
||
if (!row) return;
|
||
|
||
const badge = row.querySelector(badgeSelector);
|
||
const cntEl = row.querySelector(countSelector);
|
||
|
||
if (cntEl) {
|
||
cntEl.textContent = String(count);
|
||
}
|
||
|
||
if (badge) {
|
||
if (count > 0) {
|
||
badge.classList.remove('d-none');
|
||
} else {
|
||
badge.classList.add('d-none');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Получает текущее количество непрочитанных для чата
|
||
* @param {string} chatId - ID чата
|
||
* @returns {number} Количество непрочитанных
|
||
*/
|
||
function getBadgeCount(chatId) {
|
||
const row = document.querySelector(`${chatRowSelector}[data-chat-id="${chatId}"]`);
|
||
if (!row) return 0;
|
||
|
||
const cntEl = row.querySelector(countSelector);
|
||
if (!cntEl) return 0;
|
||
|
||
return Number(cntEl.textContent) || 0;
|
||
}
|
||
|
||
/**
|
||
* Увеличивает счётчик непрочитанных для чата
|
||
* @param {string} chatId - ID чата
|
||
* @param {number} delta - На сколько увеличить (по умолчанию 1)
|
||
*/
|
||
function incrementBadge(chatId, delta = 1) {
|
||
const current = getBadgeCount(chatId);
|
||
updateBadge(chatId, current + delta);
|
||
}
|
||
|
||
/**
|
||
* Сбрасывает бейдж (устанавливает 0)
|
||
* @param {string} chatId - ID чата
|
||
*/
|
||
function resetBadge(chatId) {
|
||
updateBadge(chatId, 0);
|
||
}
|
||
|
||
/**
|
||
* Обработчик события chat:read
|
||
* @param {CustomEvent} e - Событие с detail.chatId
|
||
*/
|
||
function handleChatRead(e) {
|
||
const chatId = e.detail?.chatId;
|
||
if (chatId) {
|
||
resetBadge(chatId);
|
||
}
|
||
}
|
||
|
||
// Подключаем обработчик события
|
||
window.addEventListener('chat:read', handleChatRead);
|
||
|
||
// API
|
||
return {
|
||
/**
|
||
* Программное обновление бейджа
|
||
* @param {string} chatId - ID чата
|
||
* @param {number} count - Количество непрочитанных
|
||
*/
|
||
updateBadge,
|
||
|
||
/**
|
||
* Получить количество непрочитанных
|
||
* @param {string} chatId - ID чата
|
||
* @returns {number}
|
||
*/
|
||
getBadgeCount,
|
||
|
||
/**
|
||
* Увеличить счётчик
|
||
* @param {string} chatId - ID чата
|
||
* @param {number} delta - На сколько увеличить
|
||
*/
|
||
incrementBadge,
|
||
|
||
/**
|
||
* Сбросить счётчик в 0
|
||
* @param {string} chatId - ID чата
|
||
*/
|
||
resetBadge,
|
||
|
||
/**
|
||
* Уничтожение обработчиков
|
||
*/
|
||
destroy: () => {
|
||
window.removeEventListener('chat:read', handleChatRead);
|
||
}
|
||
};
|
||
}
|
||
|
||
// Публикуем в window для совместимости
|
||
if (typeof window !== 'undefined') {
|
||
window.initChatBadgeManager = initChatBadgeManager;
|
||
}
|