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": "Desbloquear y conectar",
"mobile.connect.cancelPassword": "Usar otro servidor",
"mobile.connect.connecting": "Conectando...",
"mobile.connect.notice.unreachable": "No se pudo conectar con {label}. Comprueba que el servidor esté en marcha.",
"mobile.connect.notice.authExpired": "El acceso a {label} caducó o fue revocado. Inicia sesión de nuevo.",
"mobile.connect.recovery.description": "No se pudo conectar con el servidor guardado. Comprueba que esté en marcha o elige otra instancia.",
"mobile.connect.scanQr": "Escanear código QR",
"mobile.connect.welcome.scanHint": "En tu ordenador, abre «Añadir un dispositivo» para mostrar un código QR y escanéalo aquí.",
"mobile.connect.advanced": "Avanzado",
@@ -89,9 +92,9 @@ export const dict: Record<I18nKey, string> = {
"mobile.nav.settings": "Ajustes",
"mobile.surface.closeAria": "Cerrar",
"mobile.header.openMenuAria": "Abrir menú",
"mobile.header.openWorkspaceAria": "Abrir panel de trabajo",
"mobile.header.openMetadataAria": "Abrir metadatos de la sesión",
"mobile.header.metadata.context": "Contexto",
"mobile.header.metadata.branch": "Rama",
"mobile.header.metadata.usage": "Uso",
"mobile.menu.titleAria": "Herramientas del espacio de trabajo",
"mobile.menu.files": "Archivos",
@@ -123,17 +126,19 @@ export const dict: Record<I18nKey, string> = {
"mobile.sessions.newChat": "Nuevo chat",
"mobile.sessions.editOrder": "Reordenar proyectos",
"mobile.sessions.doneEditing": "Listo",
"mobile.sessions.editOrderHint": "Arrastra el asa o usa las flechas para reordenar los proyectos. Toca la marca para finalizar.",
"mobile.sessions.editOrderHint": "Arrastra el asa para reordenar los proyectos. Toca un proyecto para mostrar sus worktrees y arrástralos también. Toca la marca para terminar.",
"mobile.sessions.dragHandleAria": "Arrastra {label} para reordenar",
"mobile.sessions.moveUpAria": "Mover {label} arriba",
"mobile.sessions.moveDownAria": "Mover {label} abajo",
"mobile.sessions.removeProjectAria": "Eliminar {label}",
"mobile.sessions.cancelRemoveProjectAria": "Cancelar eliminación de {label}",
"mobile.sessions.confirmRemoveProject": "Cerrar",
"mobile.sessions.confirmRemoveProjectAria": "Confirmar eliminación de {label}",
"mobile.sessions.toast.projectRemoved": "Se eliminó {label}",
"mobile.sessions.archiveSessionAria": "Archivar {title}",
"mobile.sessions.cancelArchiveAria": "Cancelar archivar {title}",
"mobile.sessions.renameSessionAria": "Renombrar {title}",
"mobile.sessions.renameError": "No se pudo renombrar la sesión",
"mobile.sessions.deleteSessionAria": "Eliminar {title}",
"mobile.sessions.confirmDeleteSessionAria": "Confirmar eliminación de {title}",
"mobile.sessions.editProjectAria": "Editar {label}",
"mobile.projectEdit.worktreesTitle": "Worktrees",
"mobile.projectEdit.worktreesEmpty": "Este proyecto aún no tiene worktrees.",
@@ -180,6 +185,8 @@ export const dict: Record<I18nKey, string> = {
"mobile.files.copyPathAria": "Copiar ruta del archivo",
"mobile.files.copyContent": "Copiar contenido",
"mobile.files.copyContentAria": "Copiar contenido del archivo",
"mobile.files.editAria": "Editar archivo",
"mobile.files.doneEditingAria": "Terminar edición",
"mobile.files.toast.pathCopied": "Ruta copiada",
"mobile.files.toast.contentCopied": "Contenido copiado",
"mobile.files.toast.copyFailed": "No se pudo copiar",
@@ -2040,21 +2047,6 @@ export const dict: Record<I18nKey, string> = {
"chat.chatInput.drop.insertMention": "Suelta para insertar como mención",
"chat.chatInput.drop.attachFiles": "Suelta archivos aquí para adjuntar",
"chat.chatInput.fileFallback": "archivo",
"chat.mobileStatus.editProjects.title": "Editar proyectos",
"chat.mobileStatus.editProjects.footer": "Arrastra los elementos para reordenar, o use flechas para mover. Toca editar para cambiar los detalles.",
"chat.mobileStatus.editProjects.empty": "No hay proyectos para editar",
"chat.mobileStatus.projects.empty": "No hay proyectos",
"chat.mobileStatus.projects.addAria": "Añadir proyecto",
"chat.mobileStatus.projects.removeTitle": "Eliminar proyecto",
"chat.mobileStatus.projects.removeDescriptionPrefix": "¿Estás seguro de que quieres eliminar",
"chat.mobileStatus.projects.cancel": "Cancelar",
"chat.mobileStatus.projects.remove": "Eliminar",
"chat.mobileStatus.new": "Nuevo",
"chat.mobileStatus.noSessionsInProject": "No hay sesiones en este proyecto",
"chat.mobileStatus.swipeHint": "← Desliza aquí para abrir los paneles laterales →",
"chat.mobileStatus.toast.addProjectFailed": "No se pudo añadir el proyecto",
"chat.mobileStatus.toast.selectValidDirectory": "Selecciona un directorio válido.",
"chat.mobileStatus.toast.selectDirectoryFailed": "No se pudo seleccionar el directorio",
"chat.toolOutputDialog.image.previousAria": "Imagen anterior",
"chat.toolOutputDialog.image.nextAria": "Imagen siguiente",
"chat.toolOutputDialog.image.closeAria": "Cerrar vista previa de imagen",