106 lines
4.7 KiB
JavaScript
106 lines
4.7 KiB
JavaScript
import { resolveToolbarActive } from '../router.js';
|
|
import { state } from '../state.js';
|
|
import { openAuthRequiredModal } from '../services/auth-required-modal.js';
|
|
|
|
// iconImg — путь к неоновой PNG (если есть, рисуем картинку вместо эмодзи); glow — цвет доп.свечения
|
|
// активной/нажатой вкладки (var --tab-glow); hero — «герой»-вкладка (крупнее/ярче, всегда светится).
|
|
// Пока подключена только «Связи»; остальные 4 — эмодзи до подготовки ассетов (имена подставлю).
|
|
const ITEMS = [
|
|
{ pageId: 'messages-list', label: 'Личные', icon: '💬', iconImg: '/assets/icon_lichnye.png', glow: 'rgba(0, 229, 255, .6)' },
|
|
{ pageId: 'channels-list', label: 'Каналы', icon: '📢', iconImg: '/assets/icon_kanaly.png', glow: 'rgba(0, 229, 255, .6)' },
|
|
{ pageId: 'network-view', label: 'Связи', icon: '🕸', iconImg: '/assets/icon_svyazi.png', glow: 'rgba(0, 229, 255, .6)', hero: true },
|
|
{ pageId: 'notifications-view', label: 'Уведомления', icon: '🔔', iconImg: '/assets/icon_uvedomleniya.png', glow: 'rgba(0, 229, 255, .6)' },
|
|
{ pageId: 'profile-view', label: 'Профиль', icon: '👤', iconImg: '/assets/icon_profil.png', glow: 'rgba(0, 229, 255, .6)' },
|
|
];
|
|
|
|
function iconHtml(item) {
|
|
return item.iconImg
|
|
? `<img class="toolbar-icon-img" src="${item.iconImg}" alt="" aria-hidden="true" style="--tab-glow:${item.glow}" />`
|
|
: `<span>${item.icon}</span>`;
|
|
}
|
|
|
|
function getTotalUnreadMessages() {
|
|
const chats = Object.values(state.chats || {});
|
|
let total = 0;
|
|
chats.forEach((messages) => {
|
|
if (!Array.isArray(messages)) return;
|
|
messages.forEach((msg) => {
|
|
if (msg?.from === 'in' && msg?.unread) total += 1;
|
|
});
|
|
});
|
|
return total;
|
|
}
|
|
|
|
function navigateWithGuestRules(pageId, navigate) {
|
|
if (state.session.isAuthorized) {
|
|
navigate(pageId);
|
|
return;
|
|
}
|
|
if (pageId === 'messages-list') {
|
|
openAuthRequiredModal({
|
|
title: 'Личные сообщения недоступны',
|
|
text: 'Вы не авторизованы. Для личных сообщений сначала войдите в систему.',
|
|
});
|
|
return;
|
|
}
|
|
if (pageId === 'profile-view') {
|
|
openAuthRequiredModal({
|
|
title: 'Профиль недоступен',
|
|
text: 'Вы не авторизованы. Для профиля сначала войдите в систему.',
|
|
});
|
|
return;
|
|
}
|
|
if (pageId === 'notifications-view') {
|
|
openAuthRequiredModal({
|
|
title: 'Уведомления недоступны',
|
|
text: 'Вы не авторизованы. Для уведомлений сначала войдите в систему.',
|
|
});
|
|
return;
|
|
}
|
|
navigate(pageId);
|
|
}
|
|
|
|
export function renderToolbar(currentPageId, navigate) {
|
|
const root = document.createElement('nav');
|
|
root.className = 'toolbar';
|
|
const active = resolveToolbarActive(currentPageId);
|
|
const unreadTotal = getTotalUnreadMessages();
|
|
|
|
ITEMS.forEach((item) => {
|
|
const btn = document.createElement('button');
|
|
const isProfile = item.pageId === 'profile-view';
|
|
const isMessages = item.pageId === 'messages-list';
|
|
const isNetwork = item.pageId === 'network-view';
|
|
btn.className = `toolbar-btn${item.pageId === active ? ' active' : ''}${isProfile ? ' toolbar-btn-profile' : ''}${isMessages ? ' toolbar-btn-messages' : ''}${isNetwork ? ' toolbar-btn-network' : ''}${item.hero ? ' toolbar-btn-hero' : ''}`;
|
|
if (isProfile) {
|
|
btn.innerHTML = `
|
|
${iconHtml(item)}
|
|
<span class="toolbar-label-wrap">
|
|
<span>${item.label}</span>
|
|
<span id="toolbar-connection-indicator" class="toolbar-connection-indicator is-unknown">
|
|
<span class="toolbar-connection-text">connected</span>
|
|
<span class="toolbar-connection-dot" aria-hidden="true"></span>
|
|
</span>
|
|
</span>
|
|
`;
|
|
} else {
|
|
btn.innerHTML = `${iconHtml(item)}<span>${item.label}</span>`;
|
|
}
|
|
if (isMessages && unreadTotal > 0) {
|
|
const badge = document.createElement('span');
|
|
badge.className = 'toolbar-unread-badge';
|
|
badge.textContent = unreadTotal > 99 ? '99+' : String(unreadTotal);
|
|
badge.setAttribute('aria-label', `Непрочитанных сообщений: ${badge.textContent}`);
|
|
btn.append(badge);
|
|
}
|
|
if (item.pageId === 'channels-list') {
|
|
btn.addEventListener('click', () => navigate('channels-list/feed'));
|
|
} else {
|
|
btn.addEventListener('click', () => navigateWithGuestRules(item.pageId, navigate));
|
|
}
|
|
root.append(btn);
|
|
});
|
|
|
|
return root;
|
|
}
|