Добавить SHiNE теги в DM и безопасный рендер превью

This commit is contained in:
AidarKC
2026-07-10 18:57:44 +04:00
parent 076b43e542
commit 0d2d7b6dc5
10 changed files with 358 additions and 18 deletions
+19 -4
View File
@@ -10,6 +10,7 @@ import {
import { loadCurrentRelations } from '../services/user-connections.js';
import { renderUserAvatar } from '../components/avatar-image.js';
import { loadProfileSnapshot } from '../services/user-profile-params.js';
import { parseDmTechBlocks } from '../services/dm-tech-blocks.js';
export const pageMeta = { id: 'messages-list', title: 'Личные сообщения' };
const dmAvatarSnapshotCache = new Map();
@@ -64,6 +65,12 @@ function createDmAvatar(login) {
return avatarEl;
}
function resolveLastMessagePreview(text = '') {
const parsed = parseDmTechBlocks(String(text || ''));
const display = String(parsed.displayText || '').trim();
return display || '';
}
function formatChatRowTime(ts) {
const value = Number(ts || 0);
if (!Number.isFinite(value) || value <= 0) return '';
@@ -88,12 +95,14 @@ export function render({ navigate }) {
<div class="dm-head-brand">
<div class="dm-head-hex">${(login[0] || 'A').toUpperCase()}</div>
<div class="dm-head-id">
<span class="dm-head-name">${login}</span>
<span class="dm-head-name"></span>
</div>
</div>
<h1 class="dm-head-title">Контакты</h1>
<button type="button" class="dm-head-plus" aria-label="Новый диалог">+</button>
`;
const headName = head.querySelector('.dm-head-name');
if (headName) headName.textContent = login;
head.querySelector('.dm-head-plus')?.addEventListener('click', () => navigate('contact-search-view'));
const divider = document.createElement('div');
@@ -113,19 +122,25 @@ export function render({ navigate }) {
row.innerHTML = `
<div class="dm-row-main">
<div class="dm-row-titleline dm-row-titlewrap">
<strong class="dm-row-title">${item.name}</strong>
<strong class="dm-row-title"></strong>
${item.notInContacts ? '<span class="dm-contact-note">не в контактах</span>' : ''}
</div>
<p class="dm-row-last-message">${item.lastMessage}</p>
<p class="dm-row-last-message"></p>
</div>
<div class="dm-row-meta-col">
${item.unread ? `<span class="dm-unread-badge">${item.unread > 99 ? '99+' : item.unread}</span>` : '<span class="dm-row-meta-spacer" aria-hidden="true"></span>'}
<div class="dm-row-meta-line">
${item.time ? `<span class="dm-row-time">${item.time}</span>` : '<span class="dm-row-time dm-row-time--empty"></span>'}
${item.time ? '<span class="dm-row-time"></span>' : '<span class="dm-row-time dm-row-time--empty"></span>'}
<span class="dm-chevron">${SVG_CHEVRON}</span>
</div>
</div>
`;
const titleEl = row.querySelector('.dm-row-title');
const previewEl = row.querySelector('.dm-row-last-message');
const timeEl = row.querySelector('.dm-row-time');
if (titleEl) titleEl.textContent = String(item.name || '');
if (previewEl) previewEl.textContent = resolveLastMessagePreview(item.lastMessage) || 'Диалог пока пуст.';
if (timeEl) timeEl.textContent = String(item.time || '');
row.prepend(avatarWrap);
row.addEventListener('click', () => navigate(`chat-view/${encodeURIComponent(normalizeDmChatId(item.id))}`));
return row;