Skip to content

feat(mobile): swipe Chats rows and create Host sections - #2552

Merged
DoodleBears merged 6 commits into
mainfrom
t3/2519-chat-row-swipe
Oct 22, 2026
Merged

DoodleBears merged 6 commits into
mainfrom
t3/2519-chat-row-swipe

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Issue #2519 · Work claim · Human-authorized section creation scope

Why the change

Phone Chats users can swipe or open an accessible row menu to pin, mute, or add a conversation to an existing or newly created section on its Remote Host.

Special things to note

  • Draft: native acceptance outstanding. feat(mobile): choose chat views from the Host drawer #2531 is merged; this PR targets main, integrated through 897e9334768baf26547eb155f9ab1b3e7a0ee61f by ordinary merge (head a0a3f17af55af20e48a8c4bb1d47430bda7b7b99). JavaScript only, with no native dependency/config changes. Android sampled results and captures are now recorded below; complete gesture/menu/keyboard/screen-reader acceptance remains outstanding. The implementation task itself started no shared device resources; the test center executed the dated batch below. iPhone handoff is prepared but not submitted because actual Mac queue access is unavailable.
  • Merge risk: two-way door, medium blast radius. Revert the mobile UI change to restore the old triggers; user-created sections remain valid canonical Host data, manageable from desktop. Affects Chats rows and a new native section sheet. Review iOS edge/preview arbitration, native accessibility, captured Host/client ownership, and partial-failure retry. No migration, new Host API/CLI operation, cross-Host section namespace, or device-local section store.
  • Checks: this source-only integration ran git diff --check (working and staged), both passed. No install, tests, typecheck, build, Host, Metro or device run was performed on the integrated main. Historical results below belong to original head db6186f96da024d5a6d3938fcf7a2d46233fac25 on base 8f4e650db551ae8458211634872ed291ff4e5a4f, not fresh-main validation: final focused suite 36 passed; root/mobile typecheck, lint (existing warnings), formatting, changelog and feature-map checks passed. Broader mobile run: 1,073 passed / 12 failed / 9 skipped; all 12 failures independently reproduced on clean main in the same five files (45 passed / 12 failed), involving locale expectations. Final lifecycle/guard changes were rechecked by the focused suite. Full/native builds and native runtime checks are unrun. CI plan selects related tests plus mobile checks.

Change outline

Android actual-device result — 2026-10-22

PARTIAL — native row actions and Host ownership sampled; failure/retry and accessibility matrix outstanding.

Tested 2026-10-22, physical Android16 arm64,1220×2712; development app. PR source a0a3f17af55af20e48a8c4bb1d47430bda7b7b99, combined batch 8e09ba57d367dff346a4ab5f3c5d53e5c32c90e6, baseline 897e9334768baf26547eb155f9ab1b3e7a0ee61f. Native fingerprint 2cde0026048320af2a7fdcafdc10b68875aadd75; Expo58.0.17/RN0.88/React19.3. Reused compatible arm64 Debug APK SHA256 B3A5DF7CA0D0F1C393523BE945FD49EF7263110A6DAA5B89726073759CA9ED3A. Host/Metro Node24.21 verified; original APK build's Node24.16/24.21 provenance uncertainty retained. Source preparation20files/163tests+mobiletype and serial builds passed separately; they are not phone acceptance.

PASS, sampled: full swipe revealed actions without canonical write; explicit native pin/mute/unpin/unmute changed the intended DM. Actual soft-keyboard pinyin created 测试2552; Host recorded exactly one section and DM assignment, retaining pin per this frozen contract. Native group menu and assignment to that section worked. Unsent draft255299 was dismissed on switching QA Hosts; the other chooser showed only Baseline Only and neither Host received the draft/cross-Host assignment.

Capture qualification: created.png was taken about1.4s after submit and shows selected name/Retry without an error. A later07:32:25 snapshot was back on Chats with successful canonical state. It is an intermediate state, not evidence of persistent failure or of the controlled failure/retry case.

UNTESTED: injected assignment/refresh failures and retry, offline draft retention, in-flight Host-switch refusal, TalkBack/hidden-rail focus, unread action, full font/theme/rotation/CJK caret matrix. Original pin-preserving assignment is tested here; newer Pinned-grid/Organize/unpin-on-assign requirements are excluded. iOS and Human acceptance pending.

Immutable detailed results and artifact provenance. Evidence-only commit 04287a80b6511e5b22e74f81b9725821d6a5851f is a publication reference, not a newly tested runtime head. Screenshots crop status/navigation pixels only. Clips retain original speed, no audio, and are cropped/downscaled; sampled privacy review and exact source intervals are documented in the report. Warning overlays are retained.

Restored original dev APK (pullback hash matched), recorded settings and original reverse mappings; removed own QA pairings/revoked credentials, stopped own Host/Metro/recorders and released lease at07:53:03.733Z. Two original offline Host entries remain; exact original pairing-ID comparison unavailable because the pre-run snapshot omitted IDs, and offline Host-copy state remains pending. No production app changes, uninstall or data clear. No full native, TalkBack, iOS or Human acceptance claim.

Baseline prior row entry point, no action rail/menu — different synthetic roster from candidate

Baseline prior row entry point, no action rail/menu — different synthetic roster from candidate

Candidate full swipe exposes actions; canonical roster unchanged until tap

Candidate full swipe exposes actions; canonical roster unchanged until tap

Actual Android native group overflow menu

Actual Android native group overflow menu

Empty Host section chooser

Empty Host section chooser

Real CJK keyboard input and reachable create control

Real CJK keyboard input and reachable create control

Early selected-section/Retry intermediate state, not final outcome

Early selected-section/Retry intermediate state, not final outcome

Existing section chooser for group assignment

Existing section chooser for group assignment

Other QA Host exposes only its own section

Other QA Host exposes only its own section

Recordings are immutable MP4 download links (GitHub serves these files as application/octet-stream; inline playback is not claimed):

Chats row
  swipe left ─────────┐
  native actions menu ├─ shared row callback
  accessibility action┘    ├─ Pin/Unpin → rosterBatch
                           ├─ Mute/Unmute → channelMuteSet
                           ├─ Mark as read (menu) → channelMarkRead
                           └─ Add to section → native form sheet
                                ├─ read captured Host roster/subscription
                                ├─ select existing → channelAssign
                                └─ New section → sectionCreate → returned ID → channelAssign
                                     assignment fails → retain ID → retry assignment only
                                     refresh fails → retry refresh only
                                     Host/client changes → refuse continuation

The iOS row recognizer excludes the drawer's existing 24-point edge zone. Full swipes only reveal actions. Hidden rail buttons leave the accessibility tree; iOS preview remains inside the row while the native menu has its own trigger. Pin/mute/read reuse their existing Host operations. Cloud rows and Bots without a DM receive no Host swipe actions.

The Human explicitly requested mobile section creation and Remote Host authority. The sheet uses a virtualized Host section list, a keyboard-aware create form, trimmed nonempty names, immediate busy feedback, and separate creation/assignment/refresh errors. It captures the Host client, checks ownership before each continuation, and never persists sections locally. A lost creation response cannot be retried idempotently by the existing API: retain the draft and inspect the refreshed Host list before creating again. Rename/delete/reorder are outside this flow.

Pre-run evidence blocker (superseded for the sampled Android cases above): this Windows task has no assigned Android batch or Mac/iPhone lane. The exact-head native journey specifies default/intermediate/maximum OS text × light/dark, swipe/edge/preview, VoiceOver/TalkBack, actual keyboard/CJK entry, persistence, delayed assignment failure and Host switching. Capture matched base/candidate closed row, revealed rail, native menu, chooser, create keyboard and retry states. Source tests and an HTML explainer are not native evidence or Human acceptance.

Source-only integration: original head db6186f96da024d5a6d3938fcf7a2d46233fac25 + freshly fetched main 897e9334768baf26547eb155f9ab1b3e7a0ee61f → merge head a0a3f17af55af20e48a8c4bb1d47430bda7b7b99. The only manual resolution keeps both Chats row actions and native composer entries in the feature index; DESIGN and verification inventory retain their automatic merges. Main includes #2567 and #2570; those imported changes are distinct from the resolution. No #2571 organization design is included. Previous HTML explainer is bound to the original head, not this integration. Native acceptance remains outstanding.

Closes #2519. Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c.

Reuse row action callbacks for swipe and accessible menus, preserve the iOS drawer edge and preview, and add a Host-bound create/assign sheet with recoverable partial failures.

Issue: #2519
Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fa2a01f3-bfd5-425d-a1dd-f322d36c4045
📥 Commits

Reviewing files that changed from the base of the PR and between 4de4982 and 2a04fe6.

⛔ Files ignored due to path filters: 9
  • .github/pr-screenshots/2552-android/before.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/chooser.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/cjk.mp4 is excluded by !**/*.mp4
  • .github/pr-screenshots/2552-android/cjk.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/created.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/group.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/menu.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/other-host.png is excluded by !**/*.png
  • .github/pr-screenshots/2552-android/swipe.png is excluded by !**/*.png
📒 Files selected for processing: 27
  • .agents/skills/verify-deepseekbot/features/README.md
  • .agents/skills/verify-deepseekbot/features/phone-chat-row-actions.md
  • .github/pr-screenshots/2552-android/README.md
  • .github/pr-screenshots/2552-android/hashes.json
  • .github/pr-screenshots/2554-android/README.md
  • apps/mobile/DESIGN.md
  • apps/mobile/app/(tabs)/(home)/index.tsx
  • apps/mobile/app/_layout.tsx
  • apps/mobile/app/conversation-section.tsx
  • apps/mobile/src/ui/chat/conversation-actions.ts
  • apps/mobile/src/ui/chat/conversation-row.tsx
  • apps/mobile/src/ui/chat/conversation-section-sheet.tsx
  • apps/mobile/src/ui/chat/conversation-sections.ts
  • apps/mobile/src/ui/chat/conversation-swipe-actions.tsx
  • apps/mobile/src/ui/chat/conversation-swipe.android.tsx
  • apps/mobile/src/ui/chat/conversation-swipe.tsx
  • apps/mobile/src/ui/primitives/action-menu-button.ios.tsx
  • apps/mobile/src/ui/primitives/action-menu-button.tsx
  • apps/mobile/src/ui/strings.ts
  • apps/mobile/test/conversation-actions.test.ts
  • apps/mobile/test/conversation-row-layout.test.tsx
  • apps/mobile/test/conversation-section-sheet.test.tsx
  • apps/mobile/test/conversation-sections.test.ts
  • apps/mobile/test/home-search.test.tsx
  • changes/2519-chat-row-swipe.md
  • docs/architecture/botharness-architecture.md
  • scripts/verification-inventory.json
+---------------------------------------------------------------------------------------------------+
| Test your software, or your users will. Test ruthlessly. Don't make your users find bugs for you. |
+---------------------------------------------------------------------------------------------------+
  \
   \     /)/)
        ( '')
        /  |
      o(___)
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DoodleBears

Copy link
Copy Markdown
Contributor Author

Native QA handoff for db6186f96da024d5a6d3938fcf7a2d46233fac25: Android is submitted to the existing Next batch queue, with no assigned runner or lease. iPhone needs coordinator submission to the existing Mac owner. The exact-head journey linked in the body includes swipe/menu parity, iOS edge and peek, Host-only section create/assign/retry, soft keyboard/CJK, screen readers and the DESIGN text/theme matrix. Native screenshots and Human QA remain unrun; this PR stays Draft.

An exact-head HTML explanation of the callback/Host/retry paths was rendered and inspected in T3 at desktop and narrow widths. It has no public GitHub attachment; local/T3 availability is not reviewer-hosted evidence. The PR body and committed journey contain the public review and acceptance details.

@DoodleBears

Copy link
Copy Markdown
Contributor Author

Release integration dependency

Vain's macOS 1.5.0 handoff includes #2519 and final iOS/Android native acceptance. The release task is codex/local/01a16230-879c-7ea2-bdc1-9f65f57a031a; iOS scheduling remains with the shared queue owner.

Fresh metadata for head db6186f96da024d5a6d3938fcf7a2d46233fac25 reports a merge conflict after main advanced to b54b218a487a88373c5bbba5cb45959afc47b20b (#2567). Please provide a current-main-compatible source head and refresh the exact-head native journey before the owner cuts an acceptance batch. Preserve the new iOS composer behavior while retaining this PR's row/section ownership and keyboard checks.

No device was claimed and no native pass is inferred from the existing source tests. The final acceptance SHA will be announced on #2524 only after the integration gate clears; both platforms then build from that SHA. This comment records the blocker, not merge authorization.

Preserve the Chats row actions and native composer journeys in the feature index. DESIGN and verification inventory retain both automatically merged changes.

Validation: git diff --check only; source-only integration, no fresh-main tests or native acceptance.

Issue: #2519

Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
Evidence only; tested PR input remains a0a3f17, combined candidate 8e09ba57d367dff346a4ab5f3c5d53e5c32c90e6 on baseline 897e933. PARTIAL qualification and transient selected/Retry frame limitations remain in the reviewed README.

Issue: #2519

Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
@DoodleBears

DoodleBears commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Windows/Android test-center result: PARTIAL

Tested 2026-10-22, physical Android16 arm64,1220×2712; development app. PR source a0a3f17af55af20e48a8c4bb1d47430bda7b7b99, combined batch 8e09ba57d367dff346a4ab5f3c5d53e5c32c90e6, baseline 897e9334768baf26547eb155f9ab1b3e7a0ee61f. Native fingerprint 2cde0026048320af2a7fdcafdc10b68875aadd75; Expo58.0.17/RN0.88/React19.3. Reused compatible arm64 Debug APK SHA256 B3A5DF7CA0D0F1C393523BE945FD49EF7263110A6DAA5B89726073759CA9ED3A. Host/Metro Node24.21 verified; original APK build's Node24.16/24.21 provenance uncertainty retained. Source preparation20files/163tests+mobiletype and serial builds passed separately; they are not phone acceptance.

PASS, sampled: full swipe revealed actions without canonical write; explicit native pin/mute/unpin/unmute changed the intended DM. Actual soft-keyboard pinyin created 测试2552; Host recorded exactly one section and DM assignment, retaining pin per this frozen contract. Native group menu and assignment to that section worked. Unsent draft255299 was dismissed on switching QA Hosts; the other chooser showed only Baseline Only and neither Host received the draft/cross-Host assignment.

Capture qualification: created.png was taken about1.4s after submit and shows selected name/Retry without an error. A later07:32:25 snapshot was back on Chats with successful canonical state. It is an intermediate state, not evidence of persistent failure or of the controlled failure/retry case.

UNTESTED: injected assignment/refresh failures and retry, offline draft retention, in-flight Host-switch refusal, TalkBack/hidden-rail focus, unread action, full font/theme/rotation/CJK caret matrix. Original pin-preserving assignment is tested here; newer Pinned-grid/Organize/unpin-on-assign requirements are excluded. iOS and Human acceptance pending.

Immutable detailed results and artifact provenance. Evidence-only commit 04287a80b6511e5b22e74f81b9725821d6a5851f is a publication reference, not a newly tested runtime head. Screenshots crop status/navigation pixels only. Clips retain original speed, no audio, and are cropped/downscaled; sampled privacy review and exact source intervals are documented in the report. Warning overlays are retained.

Restored original dev APK (pullback hash matched), recorded settings and original reverse mappings; removed own QA pairings/revoked credentials, stopped own Host/Metro/recorders and released lease at07:53:03.733Z. Two original offline Host entries remain; exact original pairing-ID comparison unavailable because the pre-run snapshot omitted IDs, and offline Host-copy state remains pending. No production app changes, uninstall or data clear. No full native, TalkBack, iOS or Human acceptance claim.

Representative actual native evidence:

Baseline prior row entry point, no action rail/menu — different synthetic roster from candidate

Baseline prior row entry point, no action rail/menu — different synthetic roster from candidate

Candidate full swipe exposes actions; canonical roster unchanged until tap

Candidate full swipe exposes actions; canonical roster unchanged until tap

Actual Android native group overflow menu

Actual Android native group overflow menu

Empty Host section chooser

Empty Host section chooser

Real CJK keyboard input and reachable create control

Real CJK keyboard input and reachable create control

Early selected-section/Retry intermediate state, not final outcome

Early selected-section/Retry intermediate state, not final outcome

Existing section chooser for group assignment

Existing section chooser for group assignment

Other QA Host exposes only its own section

Other QA Host exposes only its own section

Recordings are immutable MP4 download links (GitHub serves these files as application/octet-stream; inline playback is not claimed):

Resolve the additive verification inventory conflict by retaining both phone.chat-row-actions and marketplace.browse. Preserve automatic merges and the published Android evidence. Unverified gutter preparation remains separately saved and is not included.

Validation: lightweight JSON parse and git diff --check only. No local tests, typecheck, build, Host, Metro or device run. Native evidence remains PARTIAL at its recorded tested input.

Issue: #2519

Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
@DoodleBears
DoodleBears marked this pull request as ready for review October 22, 2026 08:27
Formatting only: remove three extra blank lines. Preserve evidence semantics, media, hashes and original immutable evidence references.

Issue: #2519

Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
Preserve #2554 horizontal large-text title/time and one-line preview, its native fixture and evidence, and #2578 encrypted uploads. Automatic merge has no conflicts. Only manual edits format the inherited evidence README and row-layout test; media and hashes remain unchanged.

Validation: existing oxfmt check on the two files and git diff --check passed. No tests/typecheck/install/build or native operations; gutter preparation remains stashed.

Issue: #2519

Agent-Task: codex/local/01a16196-5d76-7442-8c66-95cdef39752c
@DoodleBears
DoodleBears merged commit 265cb6f into main Oct 22, 2026
12 of 13 checks passed
@DoodleBears
DoodleBears deleted the t3/2519-chat-row-swipe branch October 28, 2026 04:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phone Chats: swipe a row to pin, add to a section, or mute

1 participant