SHiNE-server/shine-UI/js/mock-data.js
AidarKC 3e4759a0c9 Связи: полировка карты связей (свечение, прорастание линий, CSS-фильтры)
- Линии: тонкие дуги Безье (градиент неон-центр → цвет роли); связь к «сияющему»
  монолитно светится статичной тенью drop-shadow (без бегущих импульсов).
- Прорастание новых линий из центра: stroke-dasharray/dashoffset синхронно с
  разлётом узла (кончик трекает аватарку); старые линии исчезают мгновенно.
- Ghost-слой: только аватарки (без линий), 1000мс — нет висящих «ошмётков».
- CSS-bloom разлёта на компоновщике (устойчив к троттлингу rAF; завершение по таймеру).
- Сияющие узлы: мягкая медленная пульсация 3.6с (многослойная box-shadow + SVG-ореол);
  тестовые фото-аватарки.
- Фильтры слоёв в лаборатории + фикс перехвата click сценой (stopPropagation на чипах);
  фейд скрываемых на месте (opacity 0 + scale 0.8, 300мс), фиксация без физики (ноль тряски).
- Бамп client.version → 1.2.137; обновлена документация фичи.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 17:06:45 +03:00

407 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const profile = {
login: '@shine.alex',
name: '',
avatarInitials: 'АС',
phone: '+7 (916) 221-45-88',
address: 'Москва, Пресненская наб., 12',
email: 'alex.shine@demo.local',
socials: '@alexshine / t.me/alexshine',
badges: ['Официальный аккаунт', 'Сияющий'],
};
export const wallet = {
balanceSOL: '182.4571',
publicAddress: '9sVAXJ2CqP3BrtC6AFeQHhcuWjN1kUyhY7L8pkQJxMZe',
updatedAt: 'сегодня, 14:42',
};
export const deviceSessions = [
{
sessionId: 'sess_7c5e5c4b',
clientInfoFromClient: 'Android 15; Pixel 9',
clientInfoFromRequest: 'UA=Java-http-client/17.0.18; remote=127.0.0.1',
geo: 'RU/Moscow',
lastAuthenticatedAtMs: 1774600010500,
},
{
sessionId: 'sess_90ab11de',
clientInfoFromClient: 'iOS 19; iPhone 17',
clientInfoFromRequest: 'UA=ShineMobile/2.4; remote=10.0.2.12',
geo: 'RU/Moscow',
lastAuthenticatedAtMs: 1774553310000,
},
{
sessionId: 'sess_3ea4f11c',
clientInfoFromClient: 'Windows 11; Chrome 124',
clientInfoFromRequest: 'UA=Mozilla/5.0; remote=192.168.1.21',
geo: 'RU/Kazan',
lastAuthenticatedAtMs: 1774499010000,
},
];
export const directMessages = [
{
id: 'u1',
name: 'Марина К.',
initials: 'МК',
lastMessage: 'Вечером скину обновления по макетам.',
time: '15:08',
unread: 2,
},
{
id: 'u2',
name: 'Илья П.',
initials: 'ИП',
lastMessage: 'Спасибо, уже проверяю!',
time: '14:31',
unread: 0,
},
{
id: 'u3',
name: 'Елена Д.',
initials: 'ЕД',
lastMessage: 'Тестовый стенд снова доступен.',
time: '13:02',
unread: 5,
},
{
id: 'u4',
name: 'Никита О.',
initials: 'НО',
lastMessage: 'Отлично, давай так и сделаем.',
time: 'вчера',
unread: 0,
},
];
export const contactDirectory = [
{
id: 'u5',
name: 'Марк С.',
initials: 'МС',
about: 'Продуктовый аналитик, любит короткие созвоны и длинные отчёты.',
},
{
id: 'u6',
name: 'Мария Л.',
initials: 'МЛ',
about: 'UI-дизайнер, собирает референсы и следит за визуальным стилем.',
},
{
id: 'u7',
name: 'Марина Р.',
initials: 'МР',
about: 'Контент-менеджер, ведёт каналы и готовит анонсы.',
},
{
id: 'u8',
name: 'Максим В.',
initials: 'МВ',
about: 'Frontend-разработчик, отвечает за анимации и адаптивность.',
},
{
id: 'u9',
name: 'Мадина А.',
initials: 'МА',
about: 'Комьюнити-менеджер, быстро находит нужных людей.',
},
{
id: 'u10',
name: 'Ирина П.',
initials: 'ИП',
about: 'Редактор новостей, помогает с текстами и публикациями.',
},
{
id: 'u11',
name: 'Николай Д.',
initials: 'НД',
about: 'Технический писатель, структурирует знания по продукту.',
},
{
id: 'u12',
name: 'Егор Т.',
initials: 'ЕТ',
about: 'QA-инженер, любит проверять сложные сценарии вручную.',
},
];
export const chatMessages = {
u1: [
{ from: 'in', text: 'Привет! Видел новые карточки?' },
{ from: 'out', text: 'Да, смотрятся сильно. Нужен финальный текст.' },
{ from: 'in', text: 'Вечером скину обновления по макетам.' },
],
u2: [
{ from: 'out', text: 'Скинул доступы в чат команды.' },
{ from: 'in', text: 'Спасибо, уже проверяю!' },
],
u3: [
{ from: 'in', text: 'Тестовый стенд снова доступен.' },
{ from: 'out', text: 'Отлично, запускаю прогон сценариев.' },
],
u4: [
{ from: 'in', text: 'Подтверждаю план на завтра.' },
{ from: 'out', text: 'Отлично, давай так и сделаем.' },
],
};
export const channels = [
{
id: 'ch0',
name: 'Личный канал',
initials: 'ЛК',
ownerLogin: '@shine.alex',
ownerName: 'Вы',
description: 'Ваш основной канал (нулевой).',
lastMessage: 'Добро пожаловать в личный канал.',
time: '16:05',
messagesCount: 14,
kind: 'own-personal',
},
{
id: 'ch1',
name: 'Команда продукта',
initials: 'КП',
ownerLogin: '@shine.alex',
ownerName: 'Вы',
description: 'Канал команды, который вы создали.',
lastMessage: 'Обновили roadmap на апрель.',
time: '15:42',
messagesCount: 8,
kind: 'own',
},
{
id: 'ch2',
name: 'Новости Bob',
initials: 'NB',
ownerLogin: '@bob',
ownerName: 'Bob',
description: 'Основной канал пользователя Bob.',
lastMessage: 'Вышел новый дайджест разработчика.',
time: '15:20',
messagesCount: 5,
kind: 'followed-user-channel',
},
{
id: 'ch3',
name: 'Стендап команды Bob',
initials: 'SB',
ownerLogin: '@bob',
ownerName: 'Bob',
description: 'Второй канал пользователя Bob.',
lastMessage: 'Перенесли созвон на 19:30.',
time: 'вчера',
messagesCount: 11,
kind: 'followed-user-channel',
},
{
id: 'ch4',
name: 'Анекдоты дня',
initials: 'АД',
ownerLogin: '@fun.club',
ownerName: 'Fun Club',
description: 'Публичный развлекательный канал по подписке.',
lastMessage: 'Сегодня в выпуске 5 новых шуток.',
time: 'вчера',
messagesCount: 33,
kind: 'subscribed',
},
];
export const channelPosts = {
ch0: [
{
id: 'p0-1',
title: 'Первый личный пост',
body: 'Этот канал всегда ваш и стоит в списке первым.',
},
{
id: 'p0-2',
title: 'Планы',
body: 'Сюда удобно сохранять личные заметки и объявления.',
},
],
ch1: [
{
id: 'p1',
title: 'Новый экран профиля',
body: 'Добавлены бейджи статуса, переработан верхний блок и улучшены быстрые переходы.',
},
{
id: 'p2',
title: 'Навигация без перезагрузки',
body: 'Переходы между экранами теперь стабильнее работают в SPA-режиме через hash-router.',
},
],
ch2: [
{
id: 'p3',
title: 'Анекдот утра',
body: 'Разработчик говорит: "Я починил один баг". Баги в ответ: "Нас было трое".',
},
{
id: 'p4',
title: 'Анекдот про дедлайн',
body: 'Дедлайн был настолько близко, что команда начала здороваться с ним по имени.',
},
],
ch3: [
{
id: 'p5',
title: 'Утренний дайджест',
body: 'Собрали ключевые новости дня: обновления продуктов, движения рынка и заметные релизы.',
},
{
id: 'p6',
title: 'Что обсуждают сегодня',
body: 'В фокусе дня: рост интереса к мобильным dApp-интерфейсам и новые анонсы сообществ.',
},
],
};
export const notifications = {
replies: [
{ id: 'r1', title: 'Марина К. ответила на ваш комментарий', text: 'Согласна, такую структуру и оставим.', time: '12 минут назад' },
{ id: 'r2', title: 'Илья П. ответил в обсуждении', text: 'Добавил примеры экранов для onboarding.', time: '48 минут назад' },
],
events: [
{ id: 'e1', title: 'Елена Д. добавила вас в друзья', text: 'Теперь вы в связях первого уровня.', time: 'сегодня' },
{ id: 'e2', title: 'Никита О. удалил из друзей', text: 'Связь перенесена в архив событий.', time: 'вчера' },
{ id: 'e3', title: 'Марина К. поставила лайк', text: 'Оценен ваш пост о прототипе.', time: '2 дня назад' },
],
};
export const networkGraph = {
center: { id: 'me', name: 'Вы', initials: 'ВЫ', x: 50, y: 50 },
peers: [
{ id: 'p1', name: 'Марина', initials: 'МК', x: 20, y: 24 },
{ id: 'p2', name: 'Илья', initials: 'ИП', x: 80, y: 22 },
{ id: 'p3', name: 'Елена', initials: 'ЕД', x: 18, y: 78 },
{ id: 'p4', name: 'Никита', initials: 'НО', x: 82, y: 76 },
],
};
// Мок интерактивной карты связей в форме ТЗ (focusUser + connections[]).
// Используется лабораторным режимом `network-view/lab` для проверки физики/центрирования.
// relationType: family | friend | business | contact; connectionStrength: 0..1 (сильнее → ближе к центру);
// status: 'shining' даёт эффект свечения; hasOwnConnections — есть ли у узла свои связи (для глубины).
export const networkGraphMock = {
focusUser: { id: 'u_100', login: 'ivan', name: 'Иван', avatar: 'url_to_image', status: 'shining' },
connections: [
{ id: 'u_101', login: 'alisa', name: 'Алиса', avatar: 'url_to_image', relationType: 'family', connectionStrength: 0.95, hasOwnConnections: true, status: 'shining' },
{ id: 'u_102', login: 'pavel', name: 'Павел', avatar: 'url_to_image', relationType: 'business', connectionStrength: 0.45, hasOwnConnections: false },
{ id: 'u_103', login: 'marina', name: 'Марина', avatar: 'url_to_image', relationType: 'friend', connectionStrength: 0.8, hasOwnConnections: true },
{ id: 'u_104', login: 'ilya', name: 'Илья', avatar: 'url_to_image', relationType: 'friend', connectionStrength: 0.6, hasOwnConnections: true },
{ id: 'u_105', login: 'elena', name: 'Елена', avatar: 'url_to_image', relationType: 'family', connectionStrength: 0.88, hasOwnConnections: false },
{ id: 'u_106', login: 'nikita', name: 'Никита', avatar: 'url_to_image', relationType: 'contact', connectionStrength: 0.3, hasOwnConnections: false },
{ id: 'u_107', login: 'oleg', name: 'Олег', avatar: 'url_to_image', relationType: 'business', connectionStrength: 0.55, hasOwnConnections: true, status: 'shining' },
{ id: 'u_108', login: 'sveta', name: 'Света', avatar: 'url_to_image', relationType: 'friend', connectionStrength: 0.7, hasOwnConnections: false },
{ id: 'u_109', login: 'dmitry', name: 'Дмитрий', avatar: 'url_to_image', relationType: 'contact', connectionStrength: 0.4, hasOwnConnections: true },
{ id: 'u_110', login: 'anna', name: 'Анна', avatar: 'url_to_image', relationType: 'family', connectionStrength: 0.92, hasOwnConnections: false },
],
};
// Связанный мульти-пользовательский граф для лаборатории (network-view/lab):
// у каждого пользователя свой набор связей, тап по узлу переключает карту на его сеть.
// Сияющими считаем ivan/alisa/oleg — у них статус подсвечивается и в их карточках у других.
const NETWORK_NAMES = {
ivan: 'Иван', alisa: 'Алиса', pavel: 'Павел', elena: 'Елена', dmitry: 'Дмитрий',
oleg: 'Олег', nina: 'Нина', marina: 'Марина', sveta: 'Света', kirill: 'Кирилл',
};
const NETWORK_SHINING = new Set(['ivan', 'alisa', 'oleg', 'marina', 'nina']);
// Тестовые аватарки-фото (реальные лица по сид-номеру pravatar) — только для лаборатории.
// Если сети нет — узлы мягко падают на инициалы (img.onerror).
const NETWORK_PHOTOS = {
ivan: 'https://i.pravatar.cc/150?img=12', alisa: 'https://i.pravatar.cc/150?img=5',
pavel: 'https://i.pravatar.cc/150?img=13', elena: 'https://i.pravatar.cc/150?img=9',
dmitry: 'https://i.pravatar.cc/150?img=33', oleg: 'https://i.pravatar.cc/150?img=52',
nina: 'https://i.pravatar.cc/150?img=47', marina: 'https://i.pravatar.cc/150?img=44',
sveta: 'https://i.pravatar.cc/150?img=24', kirill: 'https://i.pravatar.cc/150?img=60',
};
function networkConn(login, relationType, connectionStrength) {
return {
id: login,
login,
name: NETWORK_NAMES[login] || login,
avatar: null,
photo: NETWORK_PHOTOS[login] || null,
relationType,
connectionStrength,
hasOwnConnections: true,
status: NETWORK_SHINING.has(login) ? 'shining' : '',
};
}
function networkPerson(login, connections) {
return {
focusUser: {
id: login,
login,
name: NETWORK_NAMES[login] || login,
avatar: null,
photo: NETWORK_PHOTOS[login] || null,
status: NETWORK_SHINING.has(login) ? 'shining' : '',
},
connections,
};
}
export const networkGraphUsers = {
ivan: networkPerson('ivan', [
networkConn('alisa', 'friend', 0.9),
networkConn('pavel', 'friend', 0.7),
networkConn('elena', 'family', 0.95),
networkConn('dmitry', 'family', 0.95),
networkConn('oleg', 'business', 0.5),
networkConn('nina', 'contact', 0.35),
networkConn('kirill', 'friend', 0.6),
]),
alisa: networkPerson('alisa', [
networkConn('ivan', 'friend', 0.9),
networkConn('marina', 'friend', 0.8),
networkConn('sveta', 'contact', 0.4),
networkConn('elena', 'contact', 0.3),
]),
pavel: networkPerson('pavel', [
networkConn('ivan', 'friend', 0.7),
networkConn('oleg', 'business', 0.6),
networkConn('kirill', 'friend', 0.5),
]),
elena: networkPerson('elena', [
networkConn('ivan', 'family', 0.95),
networkConn('dmitry', 'family', 0.9),
networkConn('alisa', 'contact', 0.3),
]),
dmitry: networkPerson('dmitry', [
networkConn('ivan', 'family', 0.95),
networkConn('elena', 'family', 0.9),
networkConn('pavel', 'business', 0.4),
]),
oleg: networkPerson('oleg', [
networkConn('pavel', 'business', 0.6),
networkConn('ivan', 'business', 0.5),
networkConn('nina', 'contact', 0.45),
]),
nina: networkPerson('nina', [
networkConn('ivan', 'contact', 0.35),
networkConn('oleg', 'contact', 0.45),
networkConn('sveta', 'friend', 0.5),
]),
marina: networkPerson('marina', [
networkConn('alisa', 'friend', 0.8),
networkConn('sveta', 'friend', 0.7),
networkConn('kirill', 'contact', 0.4),
]),
sveta: networkPerson('sveta', [
networkConn('marina', 'friend', 0.7),
networkConn('alisa', 'contact', 0.4),
networkConn('nina', 'friend', 0.5),
]),
kirill: networkPerson('kirill', [
networkConn('ivan', 'friend', 0.6),
networkConn('pavel', 'friend', 0.5),
networkConn('marina', 'contact', 0.4),
]),
};