Repository navigation
fix(mobile): start no threads in Solo chats - #9123
Conversation
Solo agents answer at the chat's top level, so a thread reply in a Solo chat gets its answer outside the thread. Desktop already shows existing Solo threads but starts none and takes no replies in them. Match that on mobile: hide the Reply quick action, swipe-to-reply and media reply in Solo chats, and open an existing Solo thread without a composer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tom Brow <tomb@squareup.com>
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 164b30c7c5
ℹ️ 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".
| (ref, channelId) => !(ref.watch( | ||
| channelByIdProvider( | ||
| channelId, | ||
| ).select((channel) => channel?.isSolo ?? false), |
There was a problem hiding this comment.
Preserve Solo identity while the channel list reloads
When a new Solo chat is created, createChannel(... waitForChannelList: false) invalidates channelsProvider and returns the confirmed Channel without adding it to _openedAheadProvider; the page can therefore render while this lookup is null. Defaulting null to non-Solo re-enables swipe, action, media replies, and the thread composer until the full list reload finishes, allowing the exact misplaced thread reply this change intends to prevent. Use the route's known channel metadata or remember the fast-opened channel rather than treating an unresolved lookup as thread-capable. The added tests miss this because _buildTestable always seeds the fake channel list with the Solo channel instead of exercising this production seam.
AGENTS.md reference: AGENTS.md:L242-L246
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
[P2] Preserve confirmed Solo metadata during fast creation
I verified this path: Solo creation uses waitForChannelList: false, invalidates the list without rememberOpened, then opens from the returned channel. While that lookup is missing, reply actions and submission remain available. Could we retain the confirmed channel before navigation or derive the restriction from the metadata the page already has?
Posted by Codex (gpt-6.1-sol) on behalf of kylez.
|
|
||
| final tiles = <Widget>[ | ||
| if (messages != null) | ||
| if (messages != null && startsThreads) |
There was a problem hiding this comment.
🤖 P2 · Existing Solo threads lose their normal entry points
Owned Solo chats build the main timeline with flat: personalChat, so buildMainTimelineEntries creates no reply summaries. The message bubble consequently has neither a summary link nor a tappable hasReplies target once optimistic local replies and typing indicators have cleared. Removing Reply here, alongside swipe and media reply, removes the remaining normal routes into those existing threads.
User/system effect: The promised read-only access to an existing Solo thread is unavailable from the conversation. A view-only entry point needs to remain for messages with replies.
Test: Open a Solo chat with persisted replies after a cold start, then open its existing thread through the conversation without composing.
| ], | ||
| ), | ||
| if (isMember && !isArchived) | ||
| if (canReply) |
There was a problem hiding this comment.
🤖 P2 · Read-only threads lose their bottom system inset
The composer dock supplies MediaQuery.viewPadding.bottom; hiding it leaves composerDockHeight at zero. With the keyboard closed, timelineBottomInset is then zero and _ThreadMessageList reserves only Grid.xs (16 logical pixels). Neither FrostedScaffold nor this thread body adds a bottom SafeArea.
User/system effect: On edge-to-edge Android devices with a navigation inset larger than 16 pixels, the last reply or footer cannot scroll fully clear of the system navigation controls. The read-only layout still needs that inset in its list and tail geometry.
Test: Open a populated Solo thread with a 48-pixel bottom system inset and scroll to its last reply; all text and footer controls should remain above the navigation area.
🔐 Codex Security Review
Review SummaryOverall Risk: MEDIUM
Findings[MEDIUM]
|
| .first; | ||
| final initial = tester.getTopLeft(row); | ||
| final gesture = await tester.startGesture(tester.getCenter(bubble)); | ||
| await gesture.moveBy(const Offset(25, 0)); |
There was a problem hiding this comment.
could you make this test drag left after #9127? rightward drags now leave replies closed in every channel, so these assertions also pass when the solo swipe guard is removed.
tlongwell-block
left a comment
There was a problem hiding this comment.
🤖 Meli, Tyler’s AI agent, posting on his explicit behalf.
Approved as directed by Tyler.
Follow-up test-quality finding: the new swipe test drags right although reply recognizes a left drag. Mutation checks showed the rightward test passes with the gate removed; reversing the drag catches it. Add media-reply assertions as well. This approval follows Tyler’s explicit decision; it does not claim those test gaps are fixed.
Reviewed head: 3c03ad74be3f14400d69e50dd5762309ae2bd1cd.
kazemek21
left a comment
There was a problem hiding this comment.
Kyle reviewed the PR and the Nexus review-tracker notes and directed this approval. C1 is non-blocking.
Posted by Codex (gpt-6.1-sol) on behalf of kylez.
| (ref, channelId) => !(ref.watch( | ||
| channelByIdProvider( | ||
| channelId, | ||
| ).select((channel) => channel?.isSolo ?? false), |
There was a problem hiding this comment.
[P2] Preserve confirmed Solo metadata during fast creation
I verified this path: Solo creation uses waitForChannelList: false, invalidates the list without rememberOpened, then opens from the returned channel. While that lookup is missing, reply actions and submission remain available. Could we retain the confirmed channel before navigation or derive the restriction from the metadata the page already has?
Posted by Codex (gpt-6.1-sol) on behalf of kylez.
…ction-p * origin/main: (111 commits) feat(mobile): tag the reacted-to message author on reactions (#9141) fix(mobile): steady New DM picker rows and animate picks (#9249) perf(mobile): keep remote images on disk and show small ones as thumbnails (#9158) fix(relay): deliver slow cross-node events late instead of closing their recipients (#9235) fix(mobile): read only shown events from filtered Activity rows (#9215) fix(mobile): show the channel name as the notification subtitle (#9173) fix(mobile): keep Home's header clean under sheets (#9152) fix(mobile): show already-loaded custom emoji in the iOS reactions sheet (#9150) mobile: add follow and remind actions to inbox row menu (#9142) fix(mobile): start no threads in Solo chats (#9123) mobile: persist user profiles so names and avatars render on launch (#9116) fix(mobile): keep a sent thread reply above the composer (#9026) [buzz] Recover database pool capacity after stalled connections (#9267) feat: send a User-Agent on relay WebSocket upgrades (#9246) Record why relay connections close and quiet close warnings (#9245) fix(relay): say "channel owner or admin" in the call_webhook save refusal (#9169) feat(mobile): consolidate Solo chat settings in one sheet (#9255) fix(cli): preserve attachments across successive edits (#9226) fix(mobile): swipe left to reply so swipe-back keeps rightward drags (#9127) mobile: long-press a message link for open, copy and share (#9135) ... Signed-off-by: Matthew Boston <mboston@squareup.com>
…-profile * origin/main: (307 commits) fix: inline ARM64 atomics in Sprig image build (#9291) fix(mobile): show observed thread replies in Activity (#9286) Enable mobile huddles with Codex agents (#9269) fix(mobile): read mentions taller than the screen (#9243) test(relay): give every media e2e upload its own blob hash (#9272) Add invite preview video and fallback poster (#9282) NEXUS-4336: Wait for desktop-provider socket ownership proof (#9270) fix: unblock image audit with patched MCP SDK (#9287) feat(ci): allow admin dispatch of desktop candidate validation (#9288) feat(mobile): tag the reacted-to message author on reactions (#9141) fix(mobile): steady New DM picker rows and animate picks (#9249) perf(mobile): keep remote images on disk and show small ones as thumbnails (#9158) fix(relay): deliver slow cross-node events late instead of closing their recipients (#9235) fix(mobile): read only shown events from filtered Activity rows (#9215) fix(mobile): show the channel name as the notification subtitle (#9173) fix(mobile): keep Home's header clean under sheets (#9152) fix(mobile): show already-loaded custom emoji in the iOS reactions sheet (#9150) mobile: add follow and remind actions to inbox row menu (#9142) fix(mobile): start no threads in Solo chats (#9123) mobile: persist user profiles so names and avatars render on launch (#9116) ... Signed-off-by: Franco Sola <fsola@squareup.com> # Conflicts: # docs/nips/NIP-FA.md # docs/nips/NIP-FI.md
…e-mode * origin/main: (36 commits) feat(relay): let an operator mint invites for a community owner or admin (#9265) fix: inline ARM64 atomics in Sprig image build (#9291) fix(mobile): show observed thread replies in Activity (#9286) Enable mobile huddles with Codex agents (#9269) fix(mobile): read mentions taller than the screen (#9243) test(relay): give every media e2e upload its own blob hash (#9272) Add invite preview video and fallback poster (#9282) NEXUS-4336: Wait for desktop-provider socket ownership proof (#9270) fix: unblock image audit with patched MCP SDK (#9287) feat(ci): allow admin dispatch of desktop candidate validation (#9288) feat(mobile): tag the reacted-to message author on reactions (#9141) fix(mobile): steady New DM picker rows and animate picks (#9249) perf(mobile): keep remote images on disk and show small ones as thumbnails (#9158) fix(relay): deliver slow cross-node events late instead of closing their recipients (#9235) fix(mobile): read only shown events from filtered Activity rows (#9215) fix(mobile): show the channel name as the notification subtitle (#9173) fix(mobile): keep Home's header clean under sheets (#9152) fix(mobile): show already-loaded custom emoji in the iOS reactions sheet (#9150) mobile: add follow and remind actions to inbox row menu (#9142) fix(mobile): start no threads in Solo chats (#9123) ... Signed-off-by: Will Pfleger <wpfleger@block.xyz>
Agents in a Solo chat always answer at the chat's top level. On mobile you can still start a thread in Solo (Reply action, swipe-to-reply, media reply) or reply inside an existing one, so the agent's answer lands outside the thread you wrote in. Desktop already avoids this: Solo shows existing threads but starts none and has no thread composer.
This matches desktop on mobile:
Demo
Synthetic Solo chat "QA demo", iPhone 17 Pro simulator. Each clip: right swipe on an agent message, then long-press for the actions.
Before (main): the swipe shows the reply circle and opens a thread with a composer; Reply is in the actions.
before.mp4
After (this branch): the swipe does nothing; the actions have no Reply.
after.mp4
Validation
Added tests: a Solo chat's message neither swipes to reply nor offers Reply in its actions, and a Solo thread opens without a composer. Existing swipe-reply and Solo channel tests pass, along with the full mobile suite and analyzer.
Simulator run on an iPhone 17 Pro, signed in to a real community: in an existing Solo chat, a right swipe on an agent message no longer moves or opens a thread, and the long-press actions show no Reply (Copy link, Remind me and the rest are unchanged). Team-channel Reply is covered by the existing swipe-reply tests, not this run.
A second simulator run on an iPhone 17 Pro, in a synthetic Solo chat, compared main and this branch: on main the swipe opens a thread with a composer and the actions list Reply; on this branch neither does (see Demo). The Demo's "Follow thread" action still appears in a Solo chat's actions on both builds; this PR does not change it.
🤖 Generated with Claude Code