Repository navigation
UI Layer ru
English · Русский
Один модуль Compose Multiplatform (composeApp/) рисует все платформы. Телефонный UI — общий код,
а не Android-ветка; именно поэтому его гоняют десктопные тесты.
composeApp/src/commonMain/kotlin/app/skerry/ui/
app/ состояние оболочки, locals, UI-теги, бэкенд отрисовки
design/ дизайн-система: примитивы, диалоги, меню, поля, папки
desktop/ десктопная оболочка: рейка, вьюпорт, рабочая панель
mobile/ телефонная оболочка: вкладки, шторки, экраны
terminal/ session/ files/ sftp/ remote/ vnc/ rdp/ рабочие поверхности
host/ vault/ identity/ known/ trust/ tunnel/ snippet/ runbook/ teams/ share/ ai/ sync/ metrics/ settings/
i18n/ theme/ nav/ update/ keepalive/
AppDependencies.kt
AppDependencies — граф, который собирает платформенная точка входа и отдаёт корневому
composable (DesktopDesignApp / MobileDesignApp). Не подключённая на платформе подсистема
приходит как null, и UI показывает заглушку, а не падает.
Экраны не используют сырые Material-компоненты. Каталог в
docs/coding-guidelines.md
нормативен; несущие позиции:
| Нужно | Примитив |
|---|---|
| Любой текст |
Txt — сырой Text() не используется нигде (100+ файлов) |
| Любая иконка |
Sym (глиф Material Symbols) + DesignFonts
|
| Кнопки |
PrimaryButton, GhostButton, CancelButton, IconBtn, GlyphButton
|
| Мелкие контролы |
Toggle, Badge, Dot, MeterBar, NumberStepper, HoverTooltip
|
| Строки |
ToggleRow, KeyValueRow, RowNote / NoteBlock
|
| Меню |
MenuPanel + MenuItem / MenuActionRow — каждое меню по правому клику и «⋮», включая контекстное меню текста |
| Диалоги |
ConfirmActionDialog, NoticeDialog, ModalScrim, modalBody
|
| Команда, которую цитирует диалог |
CommandQuote (+ ClippedNotice); команда в строке — CommandQuote.CommandLine
|
| Поля |
FormField + Modifier.fieldName(), ModalTextField, FieldDraft
|
| Папки |
Folders + FolderSectionHeader, GroupSelectField (десктоп) / MobileGroupSelectField
|
| Недоверенный текст |
UntrustedText.untrustedLabel, sanitizeServerText, sanitizeServerHost
|
| Вопрос, который задаёт подключение | PromptQueue |
| Объявления для скринридера | StatusAnnouncer |
| Удержание клавиатуры на живом виджете | KeyboardClaim |
За большинством из них стоят два правила: одно определение на форму (третья самодельная копия —
баг) и доступность приходит из примитива — подпись, опубликованная FormField, становится
доступным именем поля, поэтому поле не может остаться безымянным.
Цвета берутся из дизайн-токенов D.*, зеркалящих блок :root прототипа
(docs/design/Skerry Tablet.html), и никогда не пишутся hex'ом в экране. Новый оттенок — это новый
токен, сверенный с прототипом. Темы: тёмная, светлая и «Системная» за ОС; терминал следует теме
приложения.
Хром повторяет прототипы 1:1 — UI собирается по ним, а не придумывается.
Каждая видимая пользователю строка — ресурс в composeResources, переведённый сразу на
английский, русский и упрощённый китайский. Захардкоженный литерал валит детерминированные
проверки.
Две грабли, зафиксированные в коде:
- у каждой локали свои кавычки (
" "в en и zh,« »в ru — прямые"не используются); - в
composeResourcesплагин раскрывает только\n,\t,\uXXXXи\\, а подстановка — это регексп по%N$s/%N$d, а неString.format: Android-стиль\"или голый%s— баг.StringEscapeTestпрочёсывает все строки во всех локалях по всем четырём пунктам.
Десктоп и мобайл делят состояние формы и логику (*FormState); различается только раскладка.
Новая форма начинается с общего класса состояния и получает два тонких вида. Паритет проверяется на
ревью, а Android-компиляция UI-изменения — стадия гейта (:androidApp:compileDebugKotlin).
Логика не живёт в composable-функциях. Контроллеры (ConnectionController, SessionsController,
RemoteDesktopController, SyncCoordinator, RunbookRunner, …) получают зависимости через
конструктор — класс, который нельзя протестировать без сети, диска или UI, спроектирован неверно.
Конкурентные контроллеры приходят с тестами на отмену и повторный вход.
desktopTest/ui/desktop/ShellHarness запускает реальный UI на демо-графе: runDesktopShell,
runMobileShell, runForm, плюс onField / onCatalog / onTab / press. Обе оболочки идут на
десктопной JVM — мобильный UI общий, поэтому Android-паритет проверяется без эмулятора. Навигация
адресуется через ui/app/UiTags, потому что кнопка рейки рисует лигатуру шрифта, а каждая подпись
локализована.
User guide
- Installation
- Getting started
- Hosts and connections
- Vault and credentials
- Terminal
- Files (SFTP)
- Port forwarding
- Remote desktops
- Snippets and runbooks
- Monitoring and guard
- AI assistant
- Sync and devices
- Teams and sharing
- Settings and shortcuts
- Android
- Troubleshooting
Development
- Architecture
- Building and running
- Connections and transports
- Terminal engine
- Vault and crypto
- Sync protocol
- Remote desktop stacks
- UI layer
- Testing and the gate
- Contributing and releases
Русский — оглавление