SHA256
Палитра «Сияние» по умолчанию, новые роли цветов. Лента канала: плоские записи, ряд действий с равным шагом иконок, дата у записи. Обсуждение со строкой ввода, личный чат, шторки. Вход и регистрация: стартовый экран (надпись «СИЯНИЕ», сияние мандалы), настройки входа со статусами серверов, статус логина в одну строку, вход с другого устройства (код, таймер, шаги), сохранение ключей с переключателями. Корневые разделы – заголовок по центру; фильтр чатов – переключатель; уведомления – список как в чатах; фото – просмотр на весь экран. Общее: один зазор под шапкой (--page-top-gap), переключатели высотой с поле ввода, второстепенные кнопки по одной роли (в том числе на экранах устройств и серверов), иконки только из ui-icon.js, полоса прокрутки скрыта, среднее тире в текстах интерфейса. Что нужно от сервера и разработчика – docs/UI-Design/UI-v4-for-dev.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.6 KiB
JavaScript
64 lines
2.6 KiB
JavaScript
import { openSheet } from './sheet.js';
|
|
import { iconHtml } from './ui-icon.js';
|
|
import { showToast } from '../services/channels-ux.js';
|
|
|
|
// «Поделиться записью / комментарием»: что именно отправляется, ссылка и «Скопировать ссылку».
|
|
// Системное меню «Поделиться» — вторым действием, если браузер его умеет.
|
|
export function openShareSheet({ title = 'Поделиться', kicker = '', text = '', url = '' } = {}) {
|
|
return openSheet({
|
|
title,
|
|
className: 'share-sheet',
|
|
content: (sheet) => {
|
|
const wrap = document.createElement('div');
|
|
wrap.className = 'share-sheet__content';
|
|
|
|
const preview = document.createElement('div');
|
|
preview.className = 'share-sheet__preview';
|
|
const k = document.createElement('strong');
|
|
k.textContent = kicker;
|
|
const t = document.createElement('p');
|
|
t.textContent = text;
|
|
preview.append(k, t);
|
|
|
|
const label = document.createElement('label');
|
|
label.className = 'share-sheet__label';
|
|
label.textContent = 'Ссылка';
|
|
const field = document.createElement('input');
|
|
field.className = 'share-sheet__link';
|
|
field.readOnly = true;
|
|
field.value = url;
|
|
field.addEventListener('focus', () => field.select());
|
|
label.append(field);
|
|
|
|
const copy = document.createElement('button');
|
|
copy.type = 'button';
|
|
copy.className = 'primary-btn share-sheet__copy';
|
|
copy.innerHTML = `${iconHtml('copy')}<span>Скопировать ссылку</span>`;
|
|
copy.addEventListener('click', async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(url);
|
|
showToast('Ссылка скопирована');
|
|
sheet.close();
|
|
} catch {
|
|
field.focus();
|
|
field.select();
|
|
showToast('Выделил ссылку – скопируйте её вручную', { kind: 'error' });
|
|
}
|
|
});
|
|
wrap.append(preview, label, copy);
|
|
|
|
if (navigator.share) {
|
|
const system = document.createElement('button');
|
|
system.type = 'button';
|
|
system.className = 'secondary-btn share-sheet__system';
|
|
system.innerHTML = `${iconHtml('share')}<span>Другое приложение…</span>`;
|
|
system.addEventListener('click', async () => {
|
|
try { await navigator.share({ title: kicker, text, url }); sheet.close(); } catch { /* отменили */ }
|
|
});
|
|
wrap.append(system);
|
|
}
|
|
return wrap;
|
|
},
|
|
});
|
|
}
|