ЛС: токены связей + резолвер визуала + семантический мок (connectedVia/login)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pixel
2026-06-19 19:48:26 +03:00
co-authored by Claude Opus 4.8
parent 7ad74942e0
commit aea6bbcb0e
3 changed files with 72 additions and 32 deletions
@@ -0,0 +1,34 @@
// Экран «Личные сообщения» — единый слой «семантика отношения → визуальное состояние».
// messages-list.js только рендерит готовый результат; здесь вся логика выбора тона/статуса/бейджа.
// Источник полей — мок directMessages (оффлайн-демо). На проде сюда же подставятся реальные
// relationFlagsForTarget / shineConfirmed / shine — UI карточек переписывать не придётся.
// Тон обода аватара. ВАЖНО: «Подтверждён» НЕ красит обод золотым (золото = семья/близкий круг).
// isShining → 'shining' (небесный) ; relationType==='family' → 'family' (золотой) ; иначе 'default' (violet).
// toneOverride — только для тестового мока (в проде не задавать).
export function resolveAvatarTone(msg) {
const o = String(msg?.toneOverride || '').trim();
if (o === 'default' || o === 'family' || o === 'shining') return o;
if (msg?.isShining) return 'shining';
if (msg?.relationType === 'family') return 'family';
return 'default';
}
// Непрочитанные: показываем только при >0; 1–99, далее «99+». Отдельная violet-сфера (НЕ изумруд).
export function resolveUnreadStyle(msg) {
const n = Math.max(0, Math.trunc(Number(msg?.unreadCount ?? msg?.unread ?? 0)) || 0);
if (n <= 0) return null;
return { count: n, label: n > 99 ? '99+' : String(n) };
}
// Итоговое визуальное состояние карточки.
export function resolveDmVisualState(msg) {
const via = Array.isArray(msg?.connectedVia) && msg.connectedVia.length ? msg.connectedVia : null;
return {
tone: resolveAvatarTone(msg), // 'default' | 'family' | 'shining'
shining: Boolean(msg?.isShining),
confirmed: Boolean(msg?.isConfirmed), // галочка ✓ у имени (без слова «Подтверждён»)
via, // путь «через кого»: [{name, photo}, …] | null
unread: resolveUnreadStyle(msg), // { count, label } | null
};
}