17 KiB
UX/UI-аудит Windows-клиента
Дата: 2026-07-08
Область аудита
Проверен текущий React UI apps/windows-client для Vite/Tauri как компактная Windows-утилита управления proxy-маршрутизацией приложений. Аудит выполнялся в browser-preview на http://127.0.0.1:5174/, поэтому нативные Tauri-команды были недоступны, а интерфейс показывал preview/runtime-ошибки. Все выводы ниже привязаны к скриншотам, снятым в этом прогоне.
Цель пользователя
Главная задача пользователя - быстро управлять службами и понять:
- какие компоненты установлены;
- какие службы запущены, остановлены или отсутствуют;
- какое действие доступно прямо сейчас: установить, удалить, запустить, остановить, обновить, добавить или применить;
- что сейчас маршрутизируется;
- через какую цепочку компонентов идет трафик;
- готовы ли ProxiFyre и опциональный Local sing-box;
- можно ли безопасно применить изменения;
- что делать дальше, если что-то сломано.
Цель по доступности: интерфейс должен быть управляемым с клавиатуры, с понятными статусами, читаемым восстановлением после ошибок, предсказуемыми focus states и устойчивой адаптацией к узким размерам Windows-окна.
Доказательства
01-summary-desktop.png- панель "Сводка", desktop-ширина. Состояние: смешанное. Главный статус виден, но примененное состояние еще "загружается", а рядом уже показан бейдж "Совпадает".02-proxifyre-desktop.png- панель ProxiFyre, desktop-ширина. Состояние: в целом рабочее. Состав компонента и список приложений компактны, но главное действие apply доступно даже при отсутствующих prerequisites.03-proxy-desktop.png- панель "VPN / Прокси", desktop-ширина. Состояние: рабочее. Настройка маршрута понятна, но route path выглядит как вторичный текст, а apply-action выглядит валидным до того, как маршрут может успешно примениться.04-proxy-validation-desktop.png- невалидный proxy input. Состояние: хорошая база. Inline-валидация находится рядом с полем и отключает действие проверки.05-summary-narrow.png- панель "Сводка", узкая ширина. Состояние: напряженное. Контент перестраивается, но нижний log dock и длинные сообщения обрезают важную информацию.06-proxifyre-narrow.png- панель ProxiFyre, узкая ширина. Состояние: напряженное. Контролы складываются неплохо, но setup chips переполняются по горизонтали, а нижний dock конкурирует с основной задачей.
Доменное направление
Ключевые понятия домена: цепочка маршрута, здоровье компонентов, локальный runtime, внешний endpoint, выбранные приложения, сгенерированный конфиг, граница apply/restart, диагностика.
Цветовой мир: темная Windows-оболочка, терминальный черный, зеленый для driver/service ready, amber для предупреждений, красный для блокеров/firewall, синий для links/actions, slate для config-файлов.
Сигнатурный элемент, который стоит усилить: Service Control Row - повторяемая строка компонента, где слева состояние службы, в центре человекочитаемый статус, справа одно главное действие и меню дополнительных действий. Route-chain readout тоже нужен, но как объяснение эффекта этих служб: Apps -> ProxiFyre -> target -> VPN/server.
Дефолты, которые стоит отбрасывать:
- generic dashboard cards -> service-control utility;
- большая зеленая apply-кнопка всегда видна -> apply gated by readiness + inline blockers;
- raw logs как главный error surface -> сначала человеческое recovery-сообщение, raw details вторым уровнем.
- разрозненные кнопки и анимации -> shared component base с едиными variants/states/motion tokens.
Сильные стороны
- Приложение уже ощущается как компактная desktop-утилита, а не как сайт. Фиксированный header, tabs, плотные панели и темная системная палитра подходят задаче.
- Продуктовая модель сильная: ProxiFyre и Local sing-box разделены, sing-box не сделан обязательным.
- Inline-валидация SOCKS5-поля расположена рядом с полем и отключает "Проверить", когда формат неверный.
- Зона добавления приложения использует иконки с доступными labels и tooltip, поэтому плотный workflow остается сканируемым.
- Для основных анимаций есть
prefers-reduced-motion. - UI использует настоящие
buttonи tab roles, а не click-only divs. Это хорошая база для доступности.
UX-риски
-
Apply выглядит доступным, когда маршрут еще не actionable.
- Доказательства:
02-proxifyre-desktop.png,03-proxy-desktop.png. - ProxiFyre отсутствует и список приложений пуст, но "Обновить конфиг" / "Обновить маршрут" ярко-зеленые. Это провоцирует failed action вместо направленного setup.
- Доказательства:
-
Главная цепочка маршрута не является визуальным фокусом.
- Доказательства:
01-summary-desktop.png,03-proxy-desktop.png. - Самая важная mental model - путь трафика, но сейчас он показан plain text в таблице или вторичном блоке. Пользователь вынужден читать фрагменты статуса вместо того, чтобы сразу увидеть цепочку.
- Доказательства:
-
В "Сводке" есть противоречивое состояние.
- Доказательство:
01-summary-desktop.png. - "Состояние загружается" показано рядом с "Совпадает", а система одновременно говорит "Не настроено". Это может создать ощущение, что действий не требуется.
- Доказательство:
-
Preview/native command failures слишком сырые.
- Доказательства: все скриншоты.
- Dock показывает
Cannot read properties of undefined (reading 'invoke'). Для разработчика это полезно, но как первичный пользовательский error surface это шум.
-
Bottom log dock конфликтует с узкой компоновкой.
- Доказательства:
05-summary-narrow.png,06-proxifyre-narrow.png. - Важные сообщения обрезаются до "Компонен..." и "Cannot read prop..."; dock постоянно занимает вертикальное место в и так коротком окне.
- Доказательства:
-
ProxiFyre setup chips плохо перестраиваются.
- Доказательство:
06-proxifyre-narrow.png. - Горизонтальная chip-лента скрывает третий dependency и ухудшает диагностическую ясность.
- Доказательство:
-
Терминология немного смешана.
- Доказательства:
01-summary-desktop.png,03-proxy-desktop.png. config,TCP check,VPN сервер,Local sing-box,ProxiFyre- все эти термины допустимы, но нужен единый принцип: сначала пользовательский русский, технический идентификатор вторым уровнем.
- Доказательства:
-
Компонентная база пока не выражена как система.
- Доказательства:
02-proxifyre-desktop.png,03-proxy-desktop.png,06-proxifyre-narrow.png. - Кнопки "Обновить", "Установить", "Открыть", "Проверить", add-icon buttons и service actions выглядят близко, но пока не читаются как строгая система variants. Из-за этого сложно гарантировать одинаковые hover/loading/disabled/focus states и одинаковую motion-модель.
- Доказательства:
Риски доступности
- Tablist использует
role="tab", но не видно поддержки ожидаемого arrow-key behavior и roving tab index. Пользователю с клавиатурой, вероятно, придется проходить все tabs через Tab вместо Left/Right. - Focus visibility есть через browser defaults, но визуально она тяжелая и не согласована со стилем приложения. Нужен отдельный
:focus-visibletoken для buttons, tabs, inputs и icon controls. - Status dots сильно полагаются на цвет. Стоит дублировать состояние видимым текстом или
aria-label/screen-reader text там, где текст рядом не объясняет статус. - Footer использует
aria-live, но повторяющиеся raw runtime errors могут быть шумными для assistive tech. Сначала стоит объявлять короткий статус, а подробный error text держать за "Посмотреть". - На узкой ширине truncation может скрывать actionable-часть сообщений и button labels.
- Скриншоты не доказывают полный keyboard order, screen-reader output или contrast ratios. Для этого нужен интерактивный accessibility pass.
План улучшений
P0 - Сделать service-control flow заслуживающим доверия
-
Ввести shared component base:
Buttonс variants:primary,neutral,add,danger,icon;Tabsс единым keyboard behavior и animation contract;ServiceControlRowдля ProxiFyre, Local sing-box и будущих служб;StatusPill,Field,ActionMenu,LogDock;- единые states: default, hover, active, focus-visible, disabled, loading.
-
Нормализовать motion tokens:
- button press: 100-140ms;
- tab switch: 180-240ms, только
opacity+transform; - popover/menu: 150-180ms;
- service operation: видимый loading state, чтобы интерфейс не ощущался зависшим;
- не использовать
transition: all.
-
Заменить raw preview/native invocation failures на дружелюбное состояние:
- "Desktop-команды недоступны в browser preview. Запусти через Tauri для управления службами."
- Raw error оставить только в деталях лога.
-
Заблокировать primary apply actions до готовности:
- disabled + explanation, когда список приложений пуст;
- disabled + explanation, когда ProxiFyre отсутствует;
- disabled + explanation, когда выбран local route без установленного/запущенного sing-box или выбранного сервера;
- "Открыть конфиг" оставить вторичным действием, не равным apply по весу.
-
Исправить язык summary-state:
- использовать взаимоисключающие состояния: "Проверяю", "Не готово", "Готово к применению", "Применено", "Есть черновик";
- не показывать "Совпадает", пока saved/applied state реально не загружен.
P1 - Пересобрать главную mental model
-
Вынести route-chain component как объясняющий элемент:
- узел
Appsс количеством; - узел
ProxiFyreсо статусом installed/running; - узел
Target: external SOCKS5 или Local sing-box; - узел
Server, когда активен local sing-box; - каждый сломанный узел показывает одно следующее действие.
- узел
-
Переработать "Сводку" в command center:
- сверху: route-chain и readiness системы;
- посередине: applied vs draft diff, только если есть отличие;
- снизу: максимум два next actions;
- длинные config paths и подробный состав компонентов убрать из первого взгляда.
-
Разделить "настроить маршрут" и "применить маршрут":
- Proxy panel отвечает за endpoint choice и connection check;
- ProxiFyre panel отвечает за app selection и service readiness;
- Summary подтверждает объединенный маршрут и применяет только при готовности.
P2 - Усилить responsive и component craft
-
Превратить setup chips в wrapping checklist на узких ширинах.
-
Сделать log dock адаптивным:
- desktop: persistent compact dock подходит;
- narrow: collapsed toast/details sheet вместо постоянного full-width footer.
-
Определить design tokens:
- surfaces: canvas, panel, inset, elevated;
- text: primary, secondary, muted, disabled;
- status: ready, warning, blocked, checking;
- focus ring и border intensities.
-
Стандартизировать copy:
- последовательно использовать "конфиг" или "конфигурация";
- заменить "TCP check" на "TCP-проверка";
Local sing-boxоставить техническим именем компонента, но в user-facing headings связывать с "локальный прокси".
P3 - Verification pass
- Добавить focused interaction QA:
- keyboard tab order;
- arrow-key tab navigation;
- focus return из menus/popovers;
- disabled-action explanations;
- empty, loading, error, missing-component, ready и unapplied-change states.
- Добавить responsive visual snapshots:
- 1280x720 desktop;
- 800x600 compact desktop;
- 420x720 narrow window;
- длинные proxy/server names и длинные Windows paths.
Рекомендуемый первый redesign slice
Сначала стоит сделать shared UI foundation: Button, Tabs, ServiceControlRow, StatusPill, Field, ActionMenu, LogDock и motion tokens. После этого собрать ProxiFyre и Local sing-box через один ServiceControlRow, а route-chain использовать как объясняющий компонент в "Сводке" и "VPN / Прокси". Такой порядок сначала стабилизирует поведение кнопок/табы/анимации, затем улучшит ориентацию и recovery без переписывания всего UI.