feat(ui): lobby site-style sidebar + profile screen (#47)

- Wrap lobby and profile in a shared `lobby-shell.svelte` chrome:
  page-list sidebar (Overview/Profile) and a top "Player-xxxx"
  identity strip mirroring the project site's monospace look.
- Strip the legacy `lobby.title`, device-session-id `<code>`, and
  `lobby.greeting` paragraph; the identity strip both names the user
  and opens the profile editor.
- Add a top-level `profile` AppScreen with a three-field form
  (`display_name`, `preferred_language`, `time_zone`) backed by a new
  `src/api/account.ts` wrapper around `user.account.get`,
  `user.profile.update`, and `user.settings.update`. Saving switches
  the active i18n locale in-place when the new preferred language is
  one the UI ships translations for.
- Update e2e fixture + auth-flow / lobby-flow specs to use the new
  `lobby-account-name` testid and wait for the loaded identity before
  releasing pending `SubscribeEvents` (webkit revocation race). New
  `profile-screen.spec.ts` covers navigation, edit-save, and cancel.
- Sync `ui/docs/lobby.md` and `ui/docs/navigation.md` to the new
  layout.

Closes #47
This commit is contained in:
Ilia Denisov
2026-05-26 13:42:10 +02:00
parent b03993fcb1
commit 2ecdecad1e
15 changed files with 1122 additions and 132 deletions
+18 -3
View File
@@ -51,11 +51,11 @@ const ru: Record<keyof typeof en, string> = {
"login.device_key_not_ready":
"ключ устройства ещё не готов, перезагрузите страницу",
"lobby.title": "вы вошли в систему",
"lobby.device_session_id_label": "идентификатор сессии устройства",
"lobby.greeting": "здравствуйте, {name}!",
"lobby.account_loading": "загрузка профиля…",
"lobby.logout": "выйти",
"lobby.nav.aria_label": "разделы лобби",
"lobby.nav.overview": "Обзор",
"lobby.nav.profile": "Профиль",
"lobby.section.my_games": "мои игры",
"lobby.section.invitations": "ожидающие приглашения",
"lobby.section.applications": "мои заявки",
@@ -104,6 +104,21 @@ const ru: Record<keyof typeof en, string> = {
"lobby.error.internal_error": "внутренняя ошибка сервера",
"lobby.error.unknown": "{message}",
"profile.title": "Профиль",
"profile.loading": "загрузка профиля…",
"profile.field.user_name": "идентификатор",
"profile.field.email": "электронная почта",
"profile.field.display_name": "отображаемое имя",
"profile.field.preferred_language": "язык интерфейса",
"profile.field.time_zone": "часовой пояс",
"profile.hint.display_name": "показывается там, где нужно более «человеческое» имя, чем системный идентификатор. Пустое значение — вернётся к идентификатору.",
"profile.hint.time_zone": "имя часового пояса IANA (например, Europe/Moscow, America/New_York). В подсказке — текущий пояс твоего браузера.",
"profile.save": "сохранить",
"profile.saving": "сохраняем…",
"profile.cancel": "отмена",
"profile.error.language_required": "язык не должен быть пустым",
"profile.error.time_zone_required": "часовой пояс не должен быть пустым",
"game.shell.unknown": "?",
"game.shell.connection.online": "онлайн",
"game.shell.connection.reconnecting": "переподключение…",