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': '핸들을 드래그하여 프로젝트 순서를 변경하세요. 프로젝트를 탭하면 워크트리가 표시되며 같은 방식으로 드래그할 수 있습니다. 체크를 탭하면 완료됩니다.',
'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': '복사하지 못했습니다',
@@ -2074,21 +2081,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': '이미지 미리보기 닫기',