// Demo-чат для оффлайн-флоу /messages-list/lab/chat/:id (только demo). // Реальный chat-view.js НЕ трогаем (он завязан на бэкенд/WS); здесь — изолированная мок-страница. // Состояние сообщений берём из dm-lab-store (localStorage). Без сети, без авторизации. import { directMessages } from '../../mock-data.js'; import { getThread, appendOut, markRead } from './dm-lab-store.js'; // showAppChrome:false — у чата свой низ (поле ввода), нижнее меню прячем. export const pageMeta = { id: 'dm-lab-chat', title: 'Чат (demo)', showAppChrome: false }; function findDialog(id) { return (Array.isArray(directMessages) ? directMessages : []).find((m) => m.id === id) || null; } function bubble(m) { const b = document.createElement('div'); b.className = `bubble ${m && m.from === 'out' ? 'out' : 'in'}`; b.textContent = m ? m.text : ''; return b; } export function render({ navigate, route }) { const chatId = String(route?.params?.chatId || '').trim(); const dialog = findDialog(chatId); const name = (dialog && dialog.name) || chatId || 'Диалог'; // Открытие диалога сбрасывает у него непрочитанные (demo). markRead(chatId); const screen = document.createElement('section'); screen.className = 'dm-screen dm-chat-screen'; // Шапка чата: назад + имя собеседника + demo-метка. const head = document.createElement('header'); head.className = 'dm-chat-head'; head.innerHTML = ` ${name} demo `; head.querySelector('.dm-chat-back').addEventListener('click', () => navigate('messages-list/lab')); const log = document.createElement('div'); log.className = 'dm-messages-log'; getThread(chatId).forEach((m) => log.append(bubble(m))); const inputRow = document.createElement('form'); inputRow.className = 'dm-chat-input'; inputRow.innerHTML = ` `; const field = inputRow.querySelector('.dm-input'); const scrollToEnd = () => requestAnimationFrame(() => { log.scrollTop = log.scrollHeight; }); const submit = () => { const msg = appendOut(chatId, field.value); if (!msg) return; field.value = ''; log.append(bubble(msg)); scrollToEnd(); }; inputRow.addEventListener('submit', (e) => { e.preventDefault(); submit(); }); field.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submit(); } }); screen.append(head, log, inputRow); scrollToEnd(); return screen; }