Skip to content

Adapt iPhone Duo layouts, rail navigation, and native sheets - #8568

Merged
brow merged 38 commits into
mainfrom
kennylopez-iphone-duo-devicehub
Nov 12, 2026
Merged

brow merged 38 commits into
mainfrom
kennylopez-iphone-duo-devicehub

Conversation

@klopez4212

@klopez4212 klopez4212 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Duo keeps conversations and Settings details open across closed, book and flat postures. Book mode splits at the fold; flattening restores the sidebar. Native rail controls, full-width navigation backdrops and sheet-local safe areas keep content aligned. Ordinary iPhones remain single-pane in portrait and landscape; tablet and Duo split layouts remain enabled.

Includes the recovered preview's matching pane widths, Buzz empty-pane mark, stable Settings chevrons, Bestie pane routing and Duo-only upward New menu attachment. Current main's Activity redesign, Search content fade and unread-navigation button are retained. Menu selection checks sit beside their labels.

Shared mobile changes remain in scope: the native iOS status editor, Appearance preview layout, avatar crop preservation, onboarding footer layout, profile/invite sheet geometry and nested conversation navigation. This PR is not exclusively Duo-gated. Nested navigator observers preserve recording cancellation and navigation callbacks; crop resizing preserves the selected image region. iOS 27.1 APIs remain compile-time and runtime gated.

Validation on the reconciled source: Flutter analysis, Activity/Home journeys, the full mobile test suite, file-size checks and Swift package tests. The iPhone single-pane fix was also exercised on an iPhone 18 Pro simulator before reconciliation. Fresh hosted CI and physical-device confirmation of the reconciled build are separate and remain pending.

@klopez4212
klopez4212 marked this pull request as ready for review October 24, 2026 18:07
@klopez4212
klopez4212 requested a review from a team as a code owner October 24, 2026 18:07
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T18:40:39.127519Z e05a50c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 24, 2026
@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is aa9b44ef369759b9d564214c7f6101fb0b200de2...e05a50c12d1242fc81a2e4a0c105c8c58546b7c2.
A new review must complete for this exact range. When manual authorization
is required, a user with write access must comment exactly
@buzz-security-review e05a50c12d1242fc81a2e4a0c105c8c58546b7c2 to authorize a new review.
Any previous review applies only to its recorded range.

@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 24, 2026
@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b59d69869b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:bot: Jude’s code review agent

Verdict: REQUEST CHANGES

Reviewed: 9e8c9fc04daf20259cd259dcaec89109587cc7f5..b59d69869bb4a4530d4d0c94e9a60acbcfcb1bfb (exact head b59d69869bb4a4530d4d0c94e9a60acbcfcb1bfb)

Risk: high. This PR changes Mobile native iOS layout/navigation/sheet behavior, and the exact-head required iOS gates do not compile.

Blocking finding

[P1] The iOS native/release builds fail because the PR references SDK symbols unavailable to the current CI SDK

The live exact-head CI is red for both required Swift gates:

  • Mobile Swift Domain / Mobile Swift (Release) fails with Swift compiler errors for UIHingeInteraction, UIWindow.reservedRegions, UISheetPresentationController.preferredPlacement, and UIBarButtonItem.axisBehavior.
  • Mobile Swift Domain / Mobile Swift (Native) fails on the same new API surface, including preferredPlacement and axisBehavior in the native control compile harness.

Putting these references behind #available(iOS 27.1, *) is not sufficient: runtime availability checks do not make symbols compile when the build SDK does not define them. The current required build environment cannot compile this PR.

Author action: remove or compile-time fence every iOS 27.1 SDK-only reference so the app and native Swift harness compile with the repository’s current CI SDK, while preserving a fallback path on older SDKs. Add/adjust native Swift coverage so this exact class of SDK-availability regression fails before merge.

Verification owner: author for the compile fix and regression; reviewer/CI for exact-head re-run of Mobile Swift Native and Mobile Swift Release.

Integrated review context

The systems lane surfaced the required-gate failure directly from live CI at this exact head. I independently rechecked the live PR head and sampled the failing job logs before filing this review:

  • Release job evidence included:
    • Swift Compiler Error (Xcode): Cannot find 'UIHingeInteraction' in scope
    • Value of type 'UIWindow' has no member 'reservedRegions'
    • Value of type 'UISheetPresentationController' has no member 'preferredPlacement'
    • Value of type 'UIBarButtonItem' has no member 'axisBehavior'
  • Native job evidence included the same unavailable preferredPlacement and axisBehavior members.

The product/UI lane had not produced a separate terminal finding before this required compile gate was confirmed. This blocker is already author-actionable and PR-caused; further product validation cannot clear a PR that the required mobile native/release gates cannot build.

Validation:

  • gh api user --jq .login → jedwards27; PR author is klopez4212.
  • Live PR state rechecked before review: open, non-draft, head b59d69869bb4a4530d4d0c94e9a60acbcfcb1bfb.
  • gh pr view 8568 --json statusCheckRollup showed Mobile Swift Domain / Mobile Swift (Native) and Mobile Swift Domain / Mobile Swift (Release) failing at this head.
  • Failing job logs were inspected for the Swift compiler errors above.

Author action: fix the SDK-availability compile failures and rerun the required mobile Swift gates.

Residual risk: broader iPhone Duo layout/accessibility/runtime behavior still needs re-review after the build is fixed. The current review is blocked at the required compile gate.

🧹 workspace cleaned: no Carl review checkout was created for this CI-gate review; REPOS/*-carl sweep was clean.

@klopez4212
klopez4212 marked this pull request as draft October 27, 2026 14:27
@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 27, 2026
@klopez4212
klopez4212 marked this pull request as ready for review October 27, 2026 14:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 578a235971

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 :bot: Jude’s code review agent

Requesting changes on exact head 884a4863a2ca48e5b5487af789474311e9aff3f5.

Required changes

  1. P1 — Move the shared conversation-pane primitive out of features/home.
    mobile/lib/features/home/adaptive_conversation_pane.dart now defines reusable navigation/list-detail infrastructure (ConversationPaneController at line 25, AdaptiveConversationPane at line 74, and openConversationPane at line 276), but sibling features still import it directly from Home (mobile/lib/features/activity/activity_page.dart:1, mobile/lib/features/channels/channel_detail_page.dart:1, mobile/lib/features/channels/channels_page.dart:1, mobile/lib/features/channels/me/me_page.dart:1, mobile/lib/features/channels/thread_detail_page.dart:1, mobile/lib/features/search/search_page.dart:1, mobile/lib/features/settings/settings_page.dart:1). AGENTS.md:743 says feature modules must not import from other feature modules, only from shared/. This leaves the shared conversation-pane contract on a forbidden feature boundary.
    Author action: move the shared conversation-pane controller/widgets/helper under mobile/lib/shared/..., then update production and test imports so features depend on shared, not features/home.

  2. P2 — Ensure the Duo avatar crop route has one accessible cancel owner.
    mobile/lib/features/profile/profile_avatar_crop_page.dart:101-115 publishes a Duo rail action labeled Cancel photo positioning, while mobile/lib/features/profile/profile_avatar_crop_page.dart:131-141 still renders the AppBar leading Cancel button for the same dismiss action. In Duo crop mode that gives users and VoiceOver two actionable cancel controls for one route-level intent, so the rail adaptation duplicates ownership instead of relocating it.
    Author action: when the Duo rail cancel action is active, omit/hide the AppBar leading Cancel, or do not publish the rail cancel action; add a regression proving Duo crop mode exposes only one accessible cancel control.

Freshness / validation

  • Exact PR head was refreshed immediately before this review: 884a4863a2ca48e5b5487af789474311e9aff3f5; PR author klopez4212, reviewer jedwards27.
  • Required mobile/native gates visible at final refresh were green: Mobile Checks, Mobile Tests 1/3–3/3, Mobile Android, Mobile aggregate, Mobile Swift Native, Mobile Swift Release, Mobile Swift Results, DCO, Semgrep, and zizmor. Codex Security Review was still in progress, so this review does not claim final security-bot clearance.
  • Focused local validation covered the touched mobile flows and the new pairing/onboarding delta. The lack of a physical iPhone Duo/native recording remains a verification gap, not an author-actionable change request by itself.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b9c3ada4c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 :bot: Jude’s code review agent — REQUEST CHANGES

Thanks for the follow-up fixes. The prior shared-pane module-boundary issue and duplicate Duo crop-cancel control look addressed at head 2b9c3ada4c1b049da8e70fa0af243fee0335d592, and the mobile/native gates I checked are green. One author-actionable Duo edit-state defect remains.

Blocking finding

P2 — Folding/rotation resets the user’s composed avatar crop

ProfileAvatarCropPage still reinitializes the crop transform every time the crop canvas size changes:

  • mobile/lib/features/profile/profile_avatar_crop_page.dart:223-231

That path compares initializedForSize.value to the current canvasSize and, on any change, replaces controller.value with a new centered identity matrix. A Duo fold/posture change or phone rotation changes the crop canvas after the user has already panned/zoomed, so the editor silently drops the composed crop and returns to a centered 1× image before save.

This violates the PR’s stated Duo photo-editing contract that the current edit is retained across folding. It is not just a missing-device-confidence gap; it is reachable from the source state transition and reproducible in a widget probe that pans/zooms, resizes the canvas, and observes the scale reset back to 1.0.

Author action: preserve the active crop selection across canvas/display/crop-geometry changes. Rebase the current transform or focal crop region onto the new geometry, clamp it to valid bounds, keep cropScale synchronized, and add a regression that pans + zooms, changes canvas size/posture, and proves both scale and selected crop area survive.

Verification owner: author for the fix and regression; reviewer/CI for an exact-head focused crop-resize test plus the mobile checks/tests.

Validation / freshness

  • Authenticated reviewer / PR author: jedwards27 / klopez4212.
  • Base/head reviewed: ff9eb8f4dc56c312983287321ea8748b93c62145 → 2b9c3ada4c1b049da8e70fa0af243fee0335d592.
  • Freshness check immediately before this review still showed PR head 2b9c3ada4c1b049da8e70fa0af243fee0335d592.
  • Prior blockers rechecked: shared conversation-pane imports now resolve through package:buzz/shared/widgets/adaptive_conversation_pane.dart; Duo crop cancel ownership now has the native rail cancel with no duplicate Flutter leading control; Swift SDK availability is fenced and native/release Swift checks are green.
  • Green at refresh: mobile checks/tests/Android aggregate, Mobile Swift Native/Release/Results, DCO, zizmor. Semgrep OSS and Codex Security were still pending at refresh, so I am not claiming security-bot completion.

I am not requesting changes for the lack of a physical iPhone Duo recording; that remains a confidence gap. The request changes verdict is for the concrete crop edit-loss defect above.

@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 27, 2026

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 :bot: Jude's code review agent review at exact head ff33cbf48841e2989359decbfb6376d7679f9097.

Verdict: REQUEST_CHANGES

I’m requesting changes for one author-actionable regression in the adaptive conversation pane route lifecycle.

Blocking finding

Active voice recording is not cancelled when a nested adaptive-detail route covers the composer

This PR moves the selected conversation detail into its own nested Navigator (mobile/lib/shared/widgets/adaptive_conversation_pane.dart:194-242), but that navigator is created without the voice-note/app route observer. The recorder cleanup path depends on that observer: voiceNoteRouteObserver is the shared appRouteObserver (mobile/lib/features/channels/voice_note_recording.dart:28-29), VoiceNoteComposerRecorder subscribes the current ModalRoute to it and cancels on didPushNext (mobile/lib/features/channels/voice_note_composer_recorder.dart:67-70), and the root observer is only attached to the root MaterialApp navigator (mobile/lib/app.dart:371-373). When the user opens channel details from an adaptive conversation detail, showChannelDetailsPage pushes with Navigator.of(context) (mobile/lib/features/channels/channel_details_page.dart:15-24), which resolves to the new nested detail navigator rather than the root one.

Failure mode: on a wide/adaptive layout, start a voice note in a channel conversation, then open channel details (or another detail-local covering route). The covering route hides the composer controls, but the root observer never receives the nested navigator’s push, so VoiceNoteComposerRecorder.onCancel is not called and the native recorder can continue running until a later cleanup path or the five-minute cap. I reproduced this at the exact head with a focused AdaptiveConversationPane widget probe: after pushing a nested covering route, the cancel callback remained 0 where the expected lifecycle contract is 1.

Author action: carry the voice-note/app route observer into the adaptive detail navigator, or add an equivalent nested-route coverage signal that cancels any active recording whenever a detail-local route covers the composer. Add a regression test through the production AdaptiveConversationPane seam that starts a voice-note recorder, pushes a nested covering route, and proves onCancel/recorder cleanup fires.

Verification owner: author for the fix and regression; reviewer/CI for the focused adaptive voice-note route test plus the relevant mobile checks/tests at the new exact head.

Rechecked evidence

  • The prior avatar crop resize blocker appears fixed at this head: the crop transform now preserves the selected source rect across resized canvases, and the focused crop resize tests are causal.
  • The prior duplicate crop-cancel and shared conversation-pane boundary concerns appear resolved in focused coverage.
  • GitHub checks for the mobile/iOS-relevant lanes were green at ff33cbf48841e2989359decbfb6376d7679f9097 when reviewed.
  • I did not personally record a physical iPhone Duo/native-mic run; that is a confidence gap, not the reason for this request-changes verdict.

@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Oct 27, 2026

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 :bot: Jude’s code review agent

Verdict: REQUEST_CHANGES

Reviewed: d4a07063c8b816124e27e00720e5b47f0a5ae1ce..51aa7451d84e9e9732ff64d39bc61bdfa6b6f213 (exact head 51aa7451d84e9e9732ff64d39bc61bdfa6b6f213)

Risk: high — this changes user-visible iPhone Duo layout/navigation, native iOS sheet behavior, and a voice-recording route lifecycle seam. The source-level nested-route fix looks sound, but the exact-head native iOS gate is red.

Blocking finding

  • Mobile Swift Domain / Mobile Swift (Native) failed at exact head 51aa7451d84e9e9732ff64d39bc61bdfa6b6f213: https://github.com/block/buzz/actions/runs/40585805357/job/122477274956
    • The job checked out PR merge commit a6dbac498ce066e2961f1dbd832ce93e670a5cb3 for this head, then failed RunnerTests.ProfileSetupRecoveryTests.testStartedEditorWithoutReadyRestoresProfileAndAllowsRetry at mobile/ios/RunnerTests/ProfileSetupRecoveryTests.swift:180 with Asynchronous wait failed: Exceeded timeout of 2 seconds while waiting for the avatar editor FlutterEngine to release after recovery.
    • The native job ended with Executed 110 tests, with 1 failure and exit code 65.
    • Consequence: the exact-head native RunnerTests gate for the changed iOS/native surface is not green, so this review cannot clear the native recovery contract yet. The dungeon did not even wait for a trapdoor this time; it helpfully painted one red.

Author action: restore a green exact-head Mobile Swift Domain / Mobile Swift (Native) result. If the timeout is a real lifecycle/test-isolation issue, fix or stabilize it; if it is independently proven to be CI-only/flaky, rerun/stabilize the gate and leave the evidence on the PR. Then request re-review at the new/green head.

Verification owner: author/CI for the failed native gate; reviewer to re-check the exact head and final CI state after it is green. No source-code author action is requested for the nested-route voice-recording fix itself.

Integrated source review notes

  • The prior hidden-recorder blocker appears fixed in source: AppRouteObserver.createNestedObserver() forwards nested navigator didPush/didPop, AdaptiveConversationPane installs that observer on the detail-local Navigator, and the route notifications reach VoiceNoteComposerRecorder's cancel/reveal subscriptions.
  • The new regression coverage for adaptive_conversation_recording_test.dart exercises the production nested AdaptiveConversationPane seam: fold/resize alone does not cancel recording, while a detail-local covering route does cancel and dispose the recorder. Mutation evidence from the review pass showed removing the nested observer makes the regression fail at the old cancellation assertion.
  • Re-checked prior fixes remain sound at source level: avatar crop geometry is rebased across resize/rotation/fold without losing selected crop, Duo crop cancel remains single-owner, production imports use the shared conversation pane, and iOS 27.1 Duo APIs remain behind compile-time and runtime availability fences.
  • Product/UI pass found no unresolved user-facing blocker in rail navigation, native sheets, duplicate controls, loading/error/empty states, large text, reduced motion, or accessibility behavior beyond the failed native gate above.

Validation / freshness

  • Local checkout: git rev-parse HEAD = 51aa7451d84e9e9732ff64d39bc61bdfa6b6f213; git status --short clean.
  • git diff --check d4a07063c8b816124e27e00720e5b47f0a5ae1ce...HEAD — PASS.
  • Focused Flutter/mobile review evidence at the exact head included passing just mobile-check, passing adaptive conversation/crop/home/settings/profile/modal/frosted-app-bar tests, and mutation proof for the nested observer cancellation regression.
  • Final GitHub refresh before this review: remote PR head still 51aa7451d84e9e9732ff64d39bc61bdfa6b6f213; required branch checks reported by GitHub were passing/skipped as configured, but Mobile Swift Domain / Mobile Swift (Native) was failing. Run Codex Security Review had no terminal conclusion in the status rollup at that refresh, so I am not claiming security-bot clearance.

Residual risk: no physical iPhone Duo/native microphone recording was captured. The source and Flutter regression cover the hidden-recorder lifecycle seam, but real-device/native microphone proof remains a confidence gap rather than an additional author-actionable finding.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 16565a5d94

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions github-actions Bot added the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 11, 2026

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 The Settings rail collision is fixed. Two remaining pane-navigation defects are detailed inline.

klopez4212 and others added 2 commits November 11, 2026 15:24
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>
…61108

Signed-off-by: kenny lopez <[email protected]>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>

# Conflicts:
#	mobile/ios/Runner/IosNavigationBar.swift
#	mobile/lib/features/channels/channel_detail_page.dart
#	mobile/lib/shared/widgets/frosted_app_bar.dart
#	mobile/test/features/channels/channel_detail_page_test.dart
@github-actions github-actions Bot removed the codex-security-review-current The posted Codex security review matches its recorded range. label Nov 11, 2026
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>
klopez4212 and others added 2 commits November 11, 2026 15:52
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65ea675949

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +411 to +415
openConversationPane(
context,
'draft:${draft.channelId}:${draft.threadHeadId}',
(_) => ChannelDetailPage(
channel: channel,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reopen the thread when reselecting an Activity draft

In a wide Activity workspace, open a thread draft, press Back to its channel, then select the same draft again. The selection ID is unchanged, so ConversationPaneController.open ignores the request, and the mounted message list's didOpenInitialThread flag prevents the thread from reopening. The fresh evidence is that openItem now passes reopen: true, but this separate openDraft path still omits it. Pass the reopen option here as well so selecting the draft consistently returns to its composer.

Useful? React with 👍 / 👎.

Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>

@brow brow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Our review recommends landing this with one small fix, #9395 pane fixes for 8568. Without it, on ordinary iPhones a channel action from channel details leaves an empty screen, every keyboard frame rebuilds Home and the open conversation, and Home Screen shortcuts do nothing over a conversation opened from Search or Activity.

Please merge the fix into your branch (it needs no approval there), and we then approve and merge this PR.

buzz://message?channel=e71f9a2a-ac46-473d-a24e-5e16fd8cb7b1&id=8e5522fb3fe36ee9d4757175cf3fb6bc52e2597f7750c0f77dc466be69a41c5a

)

Targets `kennylopez-iphone-duo-devicehub` ([#8568 iPhone Duo
layouts](#8568)), not `main`. Please
merge it into that branch. It needs no approval there.

Our review of #8568 found three problems. This PR has the three fixes.
Each fix is small and stays inside the code that #8568 adds or uses.

### 1. A channel action from channel details empties the screen

With #8568, a conversation opens in the conversation pane. The pane has
its own navigator, on all phones, on the Duo and on tablets. Channel
details now open in that navigator. But when Leave, Archive, Unarchive
or Delete completes, `_confirmAndRun` closes the top page of the
**root** navigator. That page is now Home, so the user sees an empty
screen.

The fix: before the dialog opens, keep the navigator and the route of
the channel details page. After the action completes, close that route
only if it is still the current route. The action waits for the signed
event and then for a channel refresh, so the user can go to a different
page during that time. The check makes sure that we do not close that
other page.

The same commit adds `reopen: true` when Activity opens a thread draft.
Without it, in a split layout, a second tap on the same thread draft
does nothing, because the pane ignores a selection that it already has.
The Activity item opener already sets `reopen: true`.

### 2. Each keyboard frame rebuilds Home, the channel list and the
conversation

Before #8568, a conversation was a root route above Home.
`CoveredRouteKeyboardInsets` kept old keyboard insets for the covered
Home route, so keyboard motion did not rebuild it. With #8568, Home
stays the current root route, so that hold never starts. Also, Home and
the pane read `MediaQuery.of` above the list and above the pane's
navigator. Thus each keyboard animation frame rebuilds Home, the list
and every detail route (20 of 20 frames on an ordinary phone; 0 of 20
before #8568).

The fix:
- `CoveredRouteKeyboardInsets` gets an optional `isCovered`. The compact
list uses it to say "the detail covers me", because its route stays
current. The list also gets its own `FocusScope`, so focus in a closing
detail does not count as focus in the list. With this, the list keeps
the existing behavior: it holds its insets until the keyboard goes down,
and it holds padding too.
- Home and the pane make their `MediaQuery` changes in a small leaf
widget (`MediaQueryOverride`), so the parent build does not depend on
the keyboard insets.

### 3. A Home Screen shortcut does nothing over a Search or Activity
conversation

On an ordinary iPhone, a conversation that opens from Search or Activity
is in the pane's nested navigator. While a conversation is selected, the
pane's `PopScope` makes the Search or Activity route report `doNotPop`.
The Home Screen shortcut host (New chat, New DM, Bestie) goes back to
Home with `popUntil`, which stops at a `doNotPop` route. Thus Home does
not become the current route and the shortcut tap is dropped. Before
#8568, that conversation was a root route, so the shortcut went back to
Home and ran.

The fix: only in the compact layout with a selected conversation, the
pane records its nested navigator for its route. The shortcut host
closes the pages in that navigator. It stops at a page that refuses to
close, as before. If all pages close, the host also closes the Search or
Activity route and runs the shortcut. The wide and Duo layouts and both
Back handlers do not change.

Not covered here: a Bestie shortcut when that Bestie is already
selected, and the Settings and Agents panes, which exist only in the new
wide and Duo layouts.

### Pareto

What gets better: a channel action no longer empties the screen, a
thread draft opens again in a split layout, keyboard motion in a
conversation no longer rebuilds Home, the list and the detail routes,
and Home Screen shortcuts work again over a Search or Activity
conversation. Nothing gets worse: the action closes the same page that
it closed before #8568, a page that refuses to close still stops a
shortcut, and the list's keyboard behavior is the one that
`CoveredRouteKeyboardInsets` already gives covered routes. No visible
change outside these fixes, so no screenshots.

### Validation

- Added tests:
- Leave from channel details in the conversation pane, on Android and
iOS at 402×874: the list stays, and the root route is not closed.
- Activity opens the same thread draft two times after Back, at
1100×800.
- Over 20 keyboard frames at 402×874: zero rebuilds of the covered list,
the channel, a thread above the channel, the covered channel, and Home.
- A detail with a focused text field closes while the keyboard is up:
the list keeps its held insets while the keyboard goes down.
- The Home Screen shortcut journey at 402×874 on iOS: from a channel
opened through Search, each shortcut (New chat, New DM, Bestie) returns
to Home and runs. A profile editor that refuses to close, under another
nested page, still stops the shortcut, and the shortcut runs after the
user leaves the editor.
- Each added test fails when this PR's production changes are removed
and passes with them.
- Full mobile suite: 4,767 Flutter tests passed (74 skipped), plus the
unconfigured-push and secp256k1 suites. `flutter analyze` is clean.
- Local pre-push checks were skipped: the stale-branch gate compares
with `main`, but this PR targets the #8568 branch. The full suite above
ran on this exact head.
- No simulator or device run: the fixes change navigation targets and
rebuild scope, which the widget journeys above cover.

Review discussion:
`buzz://message?channel=95213a25-483a-458b-9bc3-71891fa5aef6&id=56ce218299dab717220b492c460a5b331ad0c394e5e96ffe857bbfe7005edc98`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Tom Brow <[email protected]>
Co-authored-by: Tom Brow <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c5de880a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +446 to 450
(_) => ChannelDetailPage(
channel: channel,
initialMessageId: target.eventId,
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reapply the message target when reselecting a reminder

In a wide Activity workspace, open a reminder, scroll its conversation away from the linked message, then select the same reminder again. This path omits reopen: true, so ConversationPaneController.open returns immediately for the unchanged selection ID and the message list retains its one-shot didJumpToInitialMessage flag. The reminder consequently stops navigating to its represented message until another selection is made. Pass reopen: true here, as the updated inbox-item and draft handlers already do.

Useful? React with 👍 / 👎.

klopez4212 and others added 3 commits November 12, 2026 10:20
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>
Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz>
Signed-off-by: kenny lopez <[email protected]>
… into kennylopez-duo-ci-20261108

Signed-off-by: kenny lopez <[email protected]>
@brow
brow enabled auto-merge (squash) November 12, 2026 18:45
@brow
brow merged commit cb69ad9 into main Nov 12, 2026
107 of 108 checks passed
@brow
brow deleted the kennylopez-iphone-duo-devicehub branch November 12, 2026 19:01
ravarora2 added a commit that referenced this pull request Nov 12, 2026
…small

* origin/main:
  feat(workflow): add owner-only agent mentions for workflow messages (#9227)
  Adapt iPhone Duo layouts, rail navigation, and native sheets (#8568)
  End last-human agent Huddles and preserve mobile transcript access (#9375)
Signed-off-by: Ravneet Arora <[email protected]>

This branch was successfully deployed

No deployments
codex-review — e05a50c1 Deployed Nov 12, 2026 by klopez4212 via Run Codex Security Review #14636
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.

5 participants