SHA256
- 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>
52 lines
1.9 KiB
JavaScript
52 lines
1.9 KiB
JavaScript
import { createTopBar } from '../components/topbar.js';
|
|
import { saveEntryLanguage, state } from '../state.js';
|
|
|
|
export const pageMeta = { id: 'language-view', title: 'Язык' };
|
|
|
|
function resolveReturnPage() {
|
|
const stored = String(sessionStorage.getItem('shine-language-return-page') || '').trim();
|
|
return stored === 'start-view' ? 'start-view' : 'settings-view';
|
|
}
|
|
|
|
export function render({navigate, chrome}) {
|
|
const screen = document.createElement('section');
|
|
screen.className = 'stack language-screen';
|
|
const returnPage = resolveReturnPage();
|
|
let pendingLanguage = state.entrySettings.language === 'en' ? 'en' : 'ru';
|
|
|
|
const topbar = createTopBar({
|
|
title: 'Язык / Language',
|
|
back: { label: '←', onClick: () => {
|
|
sessionStorage.removeItem('shine-language-return-page');
|
|
navigate(returnPage);
|
|
} },
|
|
});
|
|
const embedTopbar = !state.session.isAuthorized;
|
|
if (!embedTopbar) chrome?.setTopbar(topbar);
|
|
|
|
const card = document.createElement('div');
|
|
card.className = 'nav-list language-list';
|
|
card.setAttribute('role', 'radiogroup');
|
|
card.setAttribute('aria-label', 'Язык интерфейса / Interface language');
|
|
[['ru', 'Русский'], ['en', 'English']].forEach(([code, label]) => {
|
|
const row = document.createElement('button');
|
|
row.type = 'button';
|
|
row.className = 'nav-row language-row';
|
|
row.setAttribute('role', 'radio');
|
|
row.setAttribute('aria-checked', String(pendingLanguage === code));
|
|
row.innerHTML = `<span class="nav-row__label"></span>`;
|
|
row.querySelector('.nav-row__label').textContent = label;
|
|
row.addEventListener('click', () => {
|
|
pendingLanguage = code;
|
|
saveEntryLanguage(code);
|
|
sessionStorage.removeItem('shine-language-return-page');
|
|
navigate(returnPage);
|
|
});
|
|
card.append(row);
|
|
});
|
|
|
|
if (embedTopbar) screen.append(topbar);
|
|
screen.append(card);
|
|
return screen;
|
|
}
|