SHA256
Обновить UI и документы личных сообщений
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
import { buildIdentityLines } from '../services/user-connections.js';
|
||||
import { renderUserAvatar } from '../components/avatar-image.js';
|
||||
import { createOverflowDots } from '../components/overflow-dots.js';
|
||||
import { createDropdownMenu } from '../components/dropdown-menu.js';
|
||||
|
||||
export const pageMeta = { id: 'profile-view', title: 'Профиль' };
|
||||
|
||||
@@ -110,84 +111,19 @@ export function render({ navigate, chrome }) {
|
||||
</div>
|
||||
`;
|
||||
|
||||
const profileMenuWrap = topbar.querySelector('.profile-head-menu-wrap');
|
||||
const profileMenuButton = topbar.querySelector('.profile-head-menu-btn');
|
||||
profileMenuButton?.append(createOverflowDots());
|
||||
let profileMenuPortal = null;
|
||||
|
||||
const closeProfileMenu = () => {
|
||||
profileMenuPortal?.remove();
|
||||
profileMenuPortal = null;
|
||||
profileMenuButton?.setAttribute('aria-expanded', 'false');
|
||||
profileMenuWrap?.classList.remove('is-open');
|
||||
};
|
||||
|
||||
const positionProfileMenu = () => {
|
||||
if (!profileMenuPortal || !profileMenuButton) return;
|
||||
const rect = profileMenuButton.getBoundingClientRect();
|
||||
const margin = 10;
|
||||
const menuWidth = profileMenuPortal.offsetWidth || 224;
|
||||
const left = Math.max(margin, Math.min(window.innerWidth - menuWidth - margin, rect.right - menuWidth));
|
||||
profileMenuPortal.style.left = `${Math.round(left)}px`;
|
||||
profileMenuPortal.style.top = `${Math.round(rect.bottom + 7)}px`;
|
||||
};
|
||||
|
||||
const openProfileMenu = () => {
|
||||
if (!profileMenuButton || profileMenuPortal) return;
|
||||
const portal = document.createElement('div');
|
||||
portal.className = 'dm-head-menu dm-head-menu--portal profile-head-menu';
|
||||
portal.setAttribute('role', 'menu');
|
||||
portal.innerHTML = `
|
||||
<button type="button" class="dm-head-menu-item profile-head-menu-item" role="menuitem" data-top-action="profile">
|
||||
<img src="/assets/profile-icon-profile.svg" alt="" aria-hidden="true" />
|
||||
<span>Редактировать профиль</span>
|
||||
</button>
|
||||
<button type="button" class="dm-head-menu-item profile-head-menu-item" role="menuitem" data-top-action="wallet">
|
||||
<img src="/assets/profile-icon-wallet.svg" alt="" aria-hidden="true" />
|
||||
<span>Кошелёк</span>
|
||||
</button>
|
||||
<button type="button" class="dm-head-menu-item profile-head-menu-item" role="menuitem" data-top-action="settings">
|
||||
<img src="/assets/profile-icon-settings.svg" alt="" aria-hidden="true" />
|
||||
<span>Настройки</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
const goTo = (route) => {
|
||||
closeProfileMenu();
|
||||
navigate(route);
|
||||
};
|
||||
portal.querySelector('[data-top-action="profile"]')?.addEventListener('click', () => goTo('profile-edit-view'));
|
||||
portal.querySelector('[data-top-action="wallet"]')?.addEventListener('click', () => goTo('wallet-view'));
|
||||
portal.querySelector('[data-top-action="settings"]')?.addEventListener('click', () => goTo('settings-view'));
|
||||
portal.addEventListener('click', (event) => event.stopPropagation());
|
||||
|
||||
document.body.append(portal);
|
||||
profileMenuPortal = portal;
|
||||
profileMenuButton.setAttribute('aria-expanded', 'true');
|
||||
profileMenuWrap?.classList.add('is-open');
|
||||
positionProfileMenu();
|
||||
};
|
||||
|
||||
profileMenuButton?.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (profileMenuPortal) closeProfileMenu();
|
||||
else openProfileMenu();
|
||||
const profileMenu = createDropdownMenu({
|
||||
anchorEl: profileMenuButton,
|
||||
className: 'profile-head-menu',
|
||||
minWidth: 230,
|
||||
items: [
|
||||
{ label: 'Редактировать профиль', iconSrc: '/assets/profile-icon-profile.svg', action: () => navigate('profile-edit-view') },
|
||||
{ label: 'Кошелёк', iconSrc: '/assets/profile-icon-wallet.svg', action: () => navigate('wallet-view') },
|
||||
{ label: 'Настройки', iconSrc: '/assets/profile-icon-settings.svg', action: () => navigate('settings-view') },
|
||||
],
|
||||
});
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!profileMenuPortal) return;
|
||||
if (profileMenuPortal.contains(event.target) || profileMenuButton?.contains(event.target)) return;
|
||||
closeProfileMenu();
|
||||
});
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key !== 'Escape' || !profileMenuPortal) return;
|
||||
closeProfileMenu();
|
||||
profileMenuButton?.focus();
|
||||
});
|
||||
window.addEventListener('resize', positionProfileMenu, { passive: true });
|
||||
window.addEventListener('scroll', positionProfileMenu, { passive: true, capture: true });
|
||||
|
||||
chrome?.setTopbar(topbar);
|
||||
|
||||
const card = document.createElement('div');
|
||||
@@ -382,5 +318,6 @@ export function render({ navigate, chrome }) {
|
||||
updateAvatarUi();
|
||||
refreshProfileSnapshot();
|
||||
|
||||
screen.cleanup = () => profileMenu.destroy();
|
||||
return screen;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user