import { renderHeader } from '../components/header.js';
import { directMessages } from '../mock-data.js';
import {
getChatMessages,
isSessionInvalidError,
setContacts,
state,
terminateCurrentSession,
} from '../state.js';
import { loadCurrentRelations } from '../services/user-connections.js';
export const pageMeta = { id: 'messages-list', title: 'Личные сообщения' };
export function render({ navigate }) {
const screen = document.createElement('section');
screen.className = 'stack dm-screen dm-list-screen';
screen.append(
renderHeader({
title: 'Личные сообщения',
leftLabel: String(state.session.login || '').trim(),
rightActions: [{ label: '+', onClick: () => navigate('contact-search-view') }],
}),
);
const list = document.createElement('div');
list.className = 'stack dm-list';
function renderRow(item) {
const row = document.createElement('article');
row.className = 'list-item dm-dialog-card';
row.innerHTML = `
${item.initials}
${item.name}
${item.notInContacts ? 'не в контактах' : ''}
${item.lastMessage}
${item.time}
${item.unread ? `${item.unread}` : ''}
`;
row.addEventListener('click', () => navigate(`chat-view/${encodeURIComponent(item.id)}`));
return row;
}
async function loadList() {
try {
const relations = await loadCurrentRelations();
const contacts = relations.outContacts || [];
setContacts(contacts);
list.innerHTML = '';
const contactRows = contacts.map((login) => {
const preview = directMessages.find((item) => item.id.toLowerCase() === login.toLowerCase());
const chat = getChatMessages(login);
const lastChat = chat[chat.length - 1];
const unread = chat.filter((m) => m?.from === 'in' && m?.unread).length;
return {
id: login,
initials: (login[0] || '?').toUpperCase(),
name: preview?.name || login,
lastMessage: lastChat?.text || preview?.lastMessage || 'Диалог пока пуст.',
time: preview?.time || '—',
unread,
notInContacts: false,
};
});
const allChatIds = Object.keys(state.chats || {})
.filter((id) => id && id.toLowerCase() !== String(state.session.login || '').toLowerCase())
.filter((id) => (getChatMessages(id) || []).length > 0);
const contactKeys = new Set(contacts.map((x) => String(x || '').toLowerCase()));
const extraRows = allChatIds
.filter((login) => !contactKeys.has(String(login || '').toLowerCase()))
.map((login) => {
const chat = getChatMessages(login);
const lastChat = chat[chat.length - 1];
const unread = chat.filter((m) => m?.from === 'in' && m?.unread).length;
return {
id: login,
initials: (login[0] || '?').toUpperCase(),
name: login,
lastMessage: lastChat?.text || 'Диалог пока пуст.',
time: 'сейчас',
unread,
notInContacts: true,
};
});
const rows = [...contactRows, ...extraRows];
if (!rows.length) {
const empty = document.createElement('div');
empty.className = 'card meta-muted';
empty.textContent = 'Пока нет ни контактов, ни сообщений';
list.append(empty);
return;
}
rows.forEach((item) => list.append(renderRow(item)));
} catch (error) {
if (isSessionInvalidError(error)) {
list.innerHTML = '';
const card = document.createElement('div');
card.className = 'card stack';
const title = document.createElement('strong');
title.textContent = 'Сессия устарела';
const details = document.createElement('p');
details.className = 'meta-muted';
details.textContent = 'Ваша сессия больше не действует. Авторизуйтесь заново.';
const okBtn = document.createElement('button');
okBtn.type = 'button';
okBtn.className = 'primary-btn';
okBtn.textContent = 'ОК';
okBtn.addEventListener('click', async () => {
await terminateCurrentSession({
infoMessage: 'Ваша сессия устарела. Выполните вход заново.',
});
navigate('start-view');
});
card.append(title, details, okBtn);
list.append(card);
return;
}
list.innerHTML = '';
const fail = document.createElement('div');
fail.className = 'card meta-muted';
fail.textContent = `Не удалось загрузить сообщения: ${error.message || 'unknown'}`;
list.append(fail);
}
}
screen.append(list);
loadList();
return screen;
}