UI: новый общий стиль, тёмная/светлая тема, настраиваемая палитра

- styles/main.css: роли цветов (по умолчанию «Индиго»), шкала отступов/скруглений/шрифтов,
  цвета отношений для обеих тем; жёсткие цвета в стилях заменены на роли.
- Палитра: пресеты и личные правки, «Оформление» Авто/День/Ночь, долгое нажатие —
  редактор цветов с экспортом/импортом.
- Каналы: пузыри постов автора, плашки дней, строка «Написать в канал…», «О канале»,
  создание канала с адресом из названия; лента открывается на свежих постах.
- Чаты: плоский список, чипы-фильтры, пузыри, плашки дней; нижняя панель скрыта в переписке.
- Корневые разделы — единая шапка; профиль и чужой профиль — общая карточка;
  настройки, кошелёк, сеансы — меню-списки.
- Нижняя панель: иконки без подписей, бейджи на иконках.
- confirmDialog вместо window.confirm/alert; на телефоне диалоги — шторки снизу.
- docs/UI-Design/ISSUES-for-dev.md — найденные ошибки сервера/UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
q
2026-09-26 10:05:26 +03:00
co-authored by Claude Opus 5.5
parent 6e5b57fd7c
commit f8900e531a
94 changed files with 3337 additions and 2432 deletions
+12 -23
View File
@@ -4,7 +4,7 @@ import { bytesToBase58 } from '../services/crypto-utils.js';
import { extractSeed32FromPkcs8B64 } from '../services/client-key-utils.js';
import { loadEncryptedUserSecrets } from '../services/key-vault.js';
export const pageMeta = { id: 'show-keys-view', title: 'Показать ключи' };
export const pageMeta = { id: 'show-keys-view', title: 'Ключи этого устройства' };
export function render({navigate, chrome}) {
const screen = document.createElement('section');
@@ -23,19 +23,18 @@ export function render({navigate, chrome}) {
};
chrome?.setTopbar(createTopBar({
title: 'Показать ключи',
title: 'Ключи этого устройства',
back: { label: '←', onClick: () => navigate('device-view') },
}));
const card = document.createElement('div');
card.className = 'card stack';
card.className = 'nav-list key-list';
const status = document.createElement('p');
status.className = 'meta-muted';
status.textContent = 'Загружаем сохранённые ключи...';
card.append(status);
const renderField = (id, label) => {
const renderField = (id, label, hint = '') => {
const row = document.createElement('div');
row.className = 'key-card stack';
const eyeIcon = `
@@ -53,8 +52,8 @@ export function render({navigate, chrome}) {
`;
row.innerHTML = `
<div class="row">
<span class="field-label">${label}</span>
<button class="icon-btn key-toggle-btn" type="button" data-toggle="${id}" aria-label="Показать ключ" title="Показать ключ">${eyeOffIcon}</button>
<span class="field-label">${label}${hint ? `<small class="key-card__hint">${hint}</small>` : ''}</span>
<button class="icon-btn key-toggle-btn" type="button" data-toggle="${id}" aria-label="Показать ключ" title="Показать ключ">${eyeIcon}</button>
</div>
<div class="key-value key-value--compact" data-value="${id}">*****</div>
`;
@@ -64,9 +63,9 @@ export function render({navigate, chrome}) {
};
card.append(
renderField('root', 'root key (base58)'),
renderField('blockchain', 'blockchain.key (base58)'),
renderField('device', 'client key (base58)'),
renderField('root', 'Главный ключ', 'Восстановление аккаунта и важные настройки'),
renderField('blockchain', 'Ключ публикаций', 'Подпись ваших записей'),
renderField('device', 'Ключ устройства', 'Вход с этого устройства'),
);
const setMissingState = (id) => {
@@ -91,8 +90,8 @@ export function render({navigate, chrome}) {
valueEl.textContent = visible[id] ? keys[id] : '*****';
btnEl.disabled = false;
btnEl.innerHTML = visible[id]
? field?._eyeIcon || ''
: field?._eyeOffIcon || '';
? field?._eyeOffIcon || ''
: field?._eyeIcon || '';
btnEl.setAttribute('aria-label', visible[id] ? 'Скрыть ключ' : 'Показать ключ');
btnEl.title = visible[id] ? 'Скрыть ключ' : 'Показать ключ';
};
@@ -108,16 +107,6 @@ export function render({navigate, chrome}) {
['root', 'blockchain', 'device'].forEach((id) => updateField(id));
const actions = document.createElement('div');
actions.className = 'auth-footer-actions';
const closeButton = document.createElement('button');
closeButton.className = 'ghost-btn';
closeButton.type = 'button';
closeButton.textContent = 'Назад';
closeButton.addEventListener('click', () => navigate('device-view'));
actions.append(closeButton);
(async () => {
try {
if (!state.session.login || !state.session.storagePwdInMemory) {
@@ -149,6 +138,6 @@ export function render({navigate, chrome}) {
['root', 'blockchain', 'device'].forEach((id) => updateField(id));
})();
screen.append(card, actions);
screen.append(status, card);
return screen;
}