feat(mobile): mobile app navigation rework and beta-feedback closeout (#2561)

Navigation model rebuilt around two full-width drawers and a minimal
header (sessions / title-switcher / usage ring / workspace):

- Left sessions drawer: cross-project tree with live status indicators,
  swipe actions on sessions (rename/archive/delete) and on group headers
  (project edit / two-step close, worktree delete), reorder-only edit
  mode with collapsible project cards and draggable worktrees, app-level
  footer (connected instance, settings, pending web update).
- Right workspace drawer: Changes / Files / Terminal / Notes / MCP as
  pill tabs (inactive tabs icon-only); panes stay mounted once visited.
  The full desktop file editor serves the Files tab; read/skill tool taps
  in chat open the file there at the requested line.
- Header session switcher on title tap: 10 cross-project recents with
  live busy/attention indicators and project · branch metadata; the
  usage ring opens a metadata overlay with an explicit loading state.
- The overflow menu is gone on phones (its destinations moved into the
  drawers); iPad keeps it until its dedicated layout pass.

Correctness and continuity:

- /auth/session answers bearer-first, so a stale WebView cookie can no
  longer mask a revoked device token; cold launches classify failures
  fast and land on an explicit connect screen.
- Authoritative session snapshots raise frozen ordering baselines and
  stale live ranks — recents stay truthful after the app slept.
- Cold launches reopen the last active session per instance (persisted
  pointer, confirmed against a sessions snapshot; a user-opened draft
  clears it), with a logo hold instead of a draft flash.

Also: collapsed pill composer gains the stop control; chat tool rows
share one 36px rhythm; Task subtool rows truncate; larger bottom safe
area so the composer clears big-screen corner radii; Capacitor build
hides About/Update (store updates apply there); widgets link to the
sessions drawer with a list icon; MobileApp split into focused modules;
five mobile-surface detectors unified; translucent borders normalized to
70%; all new strings translated across the 10 locales.

iPad and foldable layouts are intentionally untouched - separate next version PR.
This commit is contained in:
Bohdan Triapitsyn
2026-08-01 21:16:36 +03:00
committed by GitHub
parent ea8cc5d7b0
commit 86ef96302d
69 changed files with 5006 additions and 4291 deletions
+11 -19
View File
@@ -53,6 +53,9 @@ export const dict: Record<I18nKey, string> = {
"mobile.connect.unlockButton": "Розблокувати і підключити",
"mobile.connect.cancelPassword": "Інший сервер",
"mobile.connect.connecting": "Підключення...",
"mobile.connect.notice.unreachable": "Не вдалося з'єднатися з {label}. Перевірте, що сервер запущено.",
"mobile.connect.notice.authExpired": "Доступ до {label} протух або був відкликаний. Увійдіть знову.",
"mobile.connect.recovery.description": "Не вдалося з'єднатися зі збереженим сервером. Перевірте, що він запущений, або оберіть інший інстанс.",
"mobile.connect.scanQr": "Сканувати QR-код",
"mobile.connect.welcome.scanHint": "На компʼютері відкрийте «Додати пристрій», щоб показати QR-код, і відскануйте його тут.",
"mobile.connect.advanced": "Додатково",
@@ -89,9 +92,9 @@ export const dict: Record<I18nKey, string> = {
"mobile.nav.settings": "Налаштування",
"mobile.surface.closeAria": "Закрити",
"mobile.header.openMenuAria": "Відкрити меню",
"mobile.header.openWorkspaceAria": "Відкрити робочу панель",
"mobile.header.openMetadataAria": "Відкрити метадані сесії",
"mobile.header.metadata.context": "Контекст",
"mobile.header.metadata.branch": "Гілка",
"mobile.header.metadata.usage": "Використання",
"mobile.menu.titleAria": "Інструменти робочого простору",
"mobile.menu.files": "Файли",
@@ -123,17 +126,19 @@ export const dict: Record<I18nKey, string> = {
"mobile.sessions.newChat": "Новий чат",
"mobile.sessions.editOrder": "Змінити порядок проєктів",
"mobile.sessions.doneEditing": "Готово",
"mobile.sessions.editOrderHint": "Перетягни ручку або скористайся стрілками, щоб змінити порядок проєктів. Натисни галочку щоб завершити.",
"mobile.sessions.editOrderHint": "Перетягни ручку, щоб змінити порядок проєктів. Торкнись проєкту, щоб показати його worktree, і перетягуй їх так само. Натисни галочку, щоб завершити.",
"mobile.sessions.dragHandleAria": "Перетягни {label}, щоб змінити порядок",
"mobile.sessions.moveUpAria": "Перемістити {label} вгору",
"mobile.sessions.moveDownAria": "Перемістити {label} вниз",
"mobile.sessions.removeProjectAria": "Видалити {label}",
"mobile.sessions.cancelRemoveProjectAria": "Скасувати видалення {label}",
"mobile.sessions.confirmRemoveProject": "Закрити",
"mobile.sessions.confirmRemoveProjectAria": "Підтвердити видалення {label}",
"mobile.sessions.toast.projectRemoved": "Видалено {label}",
"mobile.sessions.archiveSessionAria": "Архівувати {title}",
"mobile.sessions.cancelArchiveAria": "Скасувати архівування {title}",
"mobile.sessions.renameSessionAria": "Перейменувати {title}",
"mobile.sessions.renameError": "Не вдалося перейменувати сесію",
"mobile.sessions.deleteSessionAria": "Видалити {title}",
"mobile.sessions.confirmDeleteSessionAria": "Підтвердити видалення {title}",
"mobile.sessions.editProjectAria": "Редагувати {label}",
"mobile.projectEdit.worktreesTitle": "Ворктрі",
"mobile.projectEdit.worktreesEmpty": "У цьому проєкті ще немає ворктрі.",
@@ -180,6 +185,8 @@ export const dict: Record<I18nKey, string> = {
"mobile.files.copyPathAria": "Скопіювати шлях до файлу",
"mobile.files.copyContent": "Скопіювати вміст",
"mobile.files.copyContentAria": "Скопіювати вміст файлу",
"mobile.files.editAria": "Редагувати файл",
"mobile.files.doneEditingAria": "Завершити редагування",
"mobile.files.toast.pathCopied": "Шлях скопійовано",
"mobile.files.toast.contentCopied": "Вміст скопійовано",
"mobile.files.toast.copyFailed": "Не вдалося скопіювати",
@@ -2040,21 +2047,6 @@ export const dict: Record<I18nKey, string> = {
"chat.chatInput.drop.insertMention": "Відпустіть, щоб вставити як згадку",
"chat.chatInput.drop.attachFiles": "Перетягніть файли сюди, щоб прикріпити",
"chat.chatInput.fileFallback": "файл",
"chat.mobileStatus.editProjects.title": "Редагувати проєкти",
"chat.mobileStatus.editProjects.footer": "Перетягніть елементи, щоб змінити порядок, або використовуйте стрілки, щоб перемістити. Натисніть «Редагувати», щоб змінити деталі.",
"chat.mobileStatus.editProjects.empty": "Немає проєктів для редагування",
"chat.mobileStatus.projects.empty": "Жодних проєктів",
"chat.mobileStatus.projects.addAria": "Додати проєкт",
"chat.mobileStatus.projects.removeTitle": "Видалити проєкт",
"chat.mobileStatus.projects.removeDescriptionPrefix": "Ви впевнені, що хочете видалити",
"chat.mobileStatus.projects.cancel": "Скасувати",
"chat.mobileStatus.projects.remove": "Видалити",
"chat.mobileStatus.new": "Новий",
"chat.mobileStatus.noSessionsInProject": "У цьому проєкті немає сесій",
"chat.mobileStatus.swipeHint": "← Проведіть пальцем тут, щоб відкрити бічні панелі →",
"chat.mobileStatus.toast.addProjectFailed": "Не вдалося додати проєкт",
"chat.mobileStatus.toast.selectValidDirectory": "Виберіть правильний каталог.",
"chat.mobileStatus.toast.selectDirectoryFailed": "Не вдалося вибрати каталог",
"chat.toolOutputDialog.image.previousAria": "Попереднє зображення",
"chat.toolOutputDialog.image.nextAria": "Наступне зображення",
"chat.toolOutputDialog.image.closeAria": "Закрити попередній перегляд зображення",