diff --git a/shine-UI/js/pages/user-profile-view.js b/shine-UI/js/pages/user-profile-view.js index c3bf2b2c..837a329a 100644 --- a/shine-UI/js/pages/user-profile-view.js +++ b/shine-UI/js/pages/user-profile-view.js @@ -1,8 +1,8 @@ import { renderHeader } from '../components/header.js'; import { SHINE_CONNECTIONS_LOGO_SRC } from '../components/shine-logo.js'; import { renderUserAvatar } from '../components/avatar-image.js'; -import { authService, state } from '../state.js'; -import { loadRelationsForPair, loadUserProfileCard } from '../services/user-connections.js'; +import { state } from '../state.js'; +import { loadUserProfileCard } from '../services/user-connections.js'; import { makeProfileLinksRoute } from '../services/shine-routes.js'; import { navigateBack } from '../router.js'; @@ -17,13 +17,6 @@ function escapeHtml(text) { .replaceAll("'", '''); } -function effectiveSocial(flags = {}) { - if (flags.outCloseFriend) return 'close_friend'; - if (flags.outFriend) return 'friend'; - if (flags.outContact) return 'contact'; - return 'none'; -} - function metricHtml({ kind, label, value, glow = false, positionClass = '' }) { const numericValue = Number(value || 0); return ` @@ -58,8 +51,8 @@ function openProfileSheet(title, html) { }); } -function aboutSheetHtml(card) { - return `
${escapeHtml(card?.about || 'Не заполнено')}
`; +function spiritualPathSheetHtml(card) { + return `
${escapeHtml(card?.spiritualPath || 'Не заполнено')}
`; } function contactsSheetHtml(card) { @@ -86,20 +79,6 @@ function addIconHtml() { `; } -function relationMenuHtml(flags = {}) { - const current = effectiveSocial(flags); - const rows = [ - ['friend', 'Друг'], - ['close_friend', 'Близкий друг'], - ['contact', 'Контакт'], - ]; - return rows.map(([kind, label]) => ` - `).join(''); -} - export function render({ navigate, route, chrome }) { const requestedLogin = String(route?.params?.login || '').trim(); const selfLogin = String(state.session.login || '').trim(); @@ -122,66 +101,6 @@ export function render({ navigate, route, chrome }) { screen.append(status, body); let card = null; - let relationFlags = null; - let relationLoadPromise = null; - let addMenu = null; - let addActionButton = null; - - function updateRelationUi() { - if (!addMenu) return; - addMenu.innerHTML = relationMenuHtml(relationFlags || {}); - const social = effectiveSocial(relationFlags || {}); - addActionButton?.classList.toggle('is-active', social !== 'none'); - addActionButton?.setAttribute('aria-label', social === 'none' ? 'Добавить' : 'Изменить связь'); - } - - async function ensureRelationFlags() { - if (relationFlags) return relationFlags; - if (relationLoadPromise) return relationLoadPromise; - if (!selfLogin || !card?.login) return {}; - relationLoadPromise = loadRelationsForPair({ currentLogin: selfLogin, targetLogin: card.login }) - .then((flags) => { - relationFlags = flags || {}; - updateRelationUi(); - return relationFlags; - }) - .finally(() => { - relationLoadPromise = null; - }); - return relationLoadPromise; - } - - async function setRelationKind(kind, enabled) { - await authService.setUserRelation({ - login: selfLogin, - toLogin: card.login, - kind, - enabled, - storagePwd: state.session.storagePwdInMemory, - }); - } - - async function changeSocial(next) { - const flags = await ensureRelationFlags(); - const current = effectiveSocial(flags); - if (current === next) return; - - if (next === 'contact') { - if (flags.outCloseFriend) await setRelationKind('close_friend', false); - if (flags.outFriend) await setRelationKind('friend', false); - if (!flags.outContact) await setRelationKind('contact', true); - } - if (next === 'friend') { - if (flags.outCloseFriend) await setRelationKind('close_friend', false); - if (!flags.outFriend) await setRelationKind('friend', true); - } - if (next === 'close_friend' && !flags.outCloseFriend) { - await setRelationKind('close_friend', true); - } - - relationFlags = await loadRelationsForPair({ currentLogin: selfLogin, targetLogin: card.login }); - updateRelationUi(); - } function renderProfile() { if (!card) return; @@ -189,11 +108,18 @@ export function render({ navigate, route, chrome }) { const stats = card.stats || {}; const official = card.accountRole === 'primary'; const shining = card.shineStatus === 'shining'; + const fullName = [card.firstName, card.lastName] + .map((value) => String(value || '').trim()) + .filter(Boolean) + .join(' '); + const about = String(card.about || '').trim(); const title = header.querySelector('.page-title'); if (title) title.textContent = card.login; body.innerHTML = ` + ${fullName ? `
${escapeHtml(fullName)}
` : ''} +
${metricHtml({ kind: 'primary_received', label: 'Официальный', value: stats.primaryReceivedCount, glow: official, positionClass: 'is-top-left' })} ${metricHtml({ kind: 'shine_received', label: 'Сияющий', value: stats.shineReceivedCount, glow: shining, positionClass: 'is-top-right' })} @@ -202,16 +128,17 @@ export function render({ navigate, route, chrome }) { ${metricHtml({ kind: 'close_friends', label: 'Близкие друзья', value: stats.closeFriendsCount, positionClass: 'is-bottom-right' })}
-
+ ${about ? `
${escapeHtml(about)}
` : ''} + +
${metricHtml({ kind: 'channels_following', label: 'Подписки', value: stats.followingChannelsCount, positionClass: 'is-channel-metric' })} ${metricHtml({ kind: 'channels_owned', label: 'Каналы', value: stats.ownedPublicChannelsCount, positionClass: 'is-channel-metric' })}
${!isSelf ? `
- ` : ''} `; @@ -239,14 +166,7 @@ export function render({ navigate, route, chrome }) { glow: shining, })); - addMenu = body.querySelector('.user-profile-add-menu'); - addActionButton = body.querySelector('[data-profile-action="add"]'); - updateRelationUi(); status.textContent = ''; - - if (!isSelf && selfLogin) { - void ensureRelationFlags().catch(() => {}); - } } body.addEventListener('click', async (event) => { @@ -259,8 +179,8 @@ export function render({ navigate, route, chrome }) { } const detailButton = event.target.closest('[data-profile-detail]'); - if (detailButton?.dataset.profileDetail === 'about') { - openProfileSheet('О себе', aboutSheetHtml(card)); + if (detailButton?.dataset.profileDetail === 'spiritual-path') { + openProfileSheet('Духовный путь', spiritualPathSheetHtml(card)); return; } if (detailButton?.dataset.profileDetail === 'contacts') { @@ -268,38 +188,15 @@ export function render({ navigate, route, chrome }) { return; } - const relationButton = event.target.closest('[data-relation-kind]'); - if (relationButton) { + const actionButton = event.target.closest('[data-profile-action]'); + const action = actionButton?.dataset.profileAction; + if (action === 'add') { if (!selfLogin) { status.className = 'status-line user-profile-status is-unavailable'; status.textContent = 'Для добавления пользователя необходимо войти.'; return; } - const next = relationButton.dataset.relationKind; - try { - addMenu?.classList.add('is-busy'); - await changeSocial(next); - if (addMenu) addMenu.hidden = true; - addActionButton?.setAttribute('aria-expanded', 'false'); - status.className = 'status-line user-profile-status'; - status.textContent = ''; - } catch (error) { - status.className = 'status-line user-profile-status is-unavailable'; - status.textContent = `Ошибка: ${error?.message || 'Не удалось изменить связь'}`; - } finally { - addMenu?.classList.remove('is-busy'); - } - return; - } - - const actionButton = event.target.closest('[data-profile-action]'); - const action = actionButton?.dataset.profileAction; - if (action === 'add') { - if (!addMenu) return; - const willOpen = addMenu.hidden; - addMenu.hidden = !willOpen; - actionButton.setAttribute('aria-expanded', willOpen ? 'true' : 'false'); - if (willOpen && selfLogin) void ensureRelationFlags().catch(() => {}); + navigate(`SHiNE/${encodeURIComponent(card.login)}/manage`); return; } if (action === 'links') { @@ -311,17 +208,6 @@ export function render({ navigate, route, chrome }) { } }); - const handleOutsidePointer = (event) => { - if (!addMenu || addMenu.hidden) return; - if (event.target instanceof Node && body.contains(event.target)) { - const insideActions = event.target.closest?.('.user-profile-actions-wrap'); - if (insideActions) return; - } - addMenu.hidden = true; - addActionButton?.setAttribute('aria-expanded', 'false'); - }; - document.addEventListener('pointerdown', handleOutsidePointer); - async function refresh() { card = await loadUserProfileCard(requestedLogin); renderProfile(); @@ -333,7 +219,6 @@ export function render({ navigate, route, chrome }) { }); screen.cleanup = () => { - document.removeEventListener('pointerdown', handleOutsidePointer); const root = document.getElementById('modal-root'); if (root?.querySelector('#user-profile-sheet-backdrop')) root.innerHTML = ''; };