feat(swift-ios): let readers dismiss the keyboard over a long draft - #7501
feat(swift-ios): let readers dismiss the keyboard over a long draft#7501saphid wants to merge 2 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds a localized Hide keyboard control to the production thread-detail composer and enables it by default for that flow. Although the implementation is small and preserves existing drafts and other composer call sites, it changes the product’s default user experience. You can add or adjust custom eligibility rules. Learn more. |
1e3b9bb to
a8b87f3
Compare
A grown composer plus the keyboard covered the whole transcript with no way back to reading it. Two iOS-conventional exits, both draft-preserving: - The transcript now uses `keyboardDismissMode = .interactive` and tracks the drag itself. The transcript is laid out above the keyboard, so `.interactive` alone never engages; a downward drag past 16pt — reaching back through a bottom-anchored thread — dismisses immediately wherever it starts. Upward nudges toward the latest turn keep the draft editable, replacing the previous dismiss-on-any-drag behaviour. - The composer footer gains a `keyboard.chevron.compact.down` control while focused. It only drops focus, so the draft and its caret survive, and it is opt-in per call site — the thread page passes a handler, other composers do not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
a8b87f3 to
4b90652
Compare
Observed problem and reproduction
Open a SwiftUI thread, type a draft long enough to reach the composer's line cap, and raise the keyboard. The composer and keyboard can cover most of the transcript. The reader needs an obvious way to put the keyboard away without losing or collapsing the draft.
Cause
Thread detail had keyboard-dismiss gestures but no visible, deterministic control in the composer footer. The target branch now supplies the gesture behavior itself: transcript dragging keeps its upstream
.onDragbehavior, and the UIKit-backed composer handles a downward drag without giving up normal long-draft scrolling.Change and boundary
This PR now adds only a 44-point Hide keyboard footer button to the thread-detail composer. The control appears while that composer is focused, calls the target branch's existing dismiss handler, and leaves the draft unchanged and expanded.
The branch was rebased onto
b67837984e5650888b1eed0e1cd7fff83625f696. During conflict resolution, the target'sThreadDetailViewwas accepted unchanged and the remaining button was re-expressed as an explicit opt-in. The target's transcript scrolling, composer drag recognizer, long-draft sizing, and New Thread integration are preserved.Non-goals
This PR no longer changes transcript drag direction or thresholds; the target branch superseded that part of the original patch. New-thread and workspace composers do not gain the footer button. There are no draft-persistence, server, provider, contract, or connection changes, and the composer line cap is unchanged.
Affected areas
Affected client: SwiftUI mobile thread detail only.
Platforms: iOS.
Providers, contracts, and connection modes: unchanged.
States: focused and unfocused thread composer, keyboard visible and hidden, and non-empty draft preservation.
Validation
Current local head:
4b90652c1fa3c686c20c82221928e04b3ce92df2.git diff --check upstream/t3code/rebuild-mobile-app-swift...HEADpassed. The target-relative diff is limited to the opt-in footer control, its thread-detail call site, and focused policy tests.The intended focused run is:
Both bounded attempts were safely deferred with exit
75before Xcode started because another XcodeBuildMCP session owns the native hygiene lane. CI shown before the force-push belongs to the superseded head and is not claimed for this commit.Risks, untested paths, and known gaps
a8b87f3e9026b26ad4617019b2a1782feebd330dand is historical only.Evidence
Historical evidence from the pre-rebase head (not valid as exact-head proof):
Owning issue and stack
Owning issue: saphid/t3code-personal#125. This PR targets
t3code/rebuild-mobile-app-swift. Maintainer edits are enabled.Note
Low Risk
Localized SwiftUI UI in thread detail with opt-in defaults; no auth, data, or server changes.
Overview
Adds an opt-in Hide keyboard icon button to the expanded composer footer so thread readers can dismiss the keyboard without losing a long draft.
The control is gated by
showsKeyboardDismissControl(defaults tofalse) andFeatureComposerKeyboardDismissPolicy, which requires focus, the flag, and anonDismissKeyboardhandler. Thread detail enables it and routes taps to the existingdismissKeyboardpath (clears composer focus and resigns first responder). Other composer call sites stay unchanged.Tests cover when the button should appear and that
FeatureComposerCollapsePolicykeeps a non-empty draft expanded after focus is lost.Reviewed by Cursor Bugbot for commit 7fa7bd1. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add keyboard dismiss button to
FeatureComposerViewshowsKeyboardDismissControlparameter toFeatureComposerView.initthat renders adismissKeyboardButtonin the composer footer when the composer is focused, the feature is enabled, and anonDismissKeyboardhandler is provided.FeatureComposerKeyboardDismissPolicy.showsDismissControl(isFocused:isEnabled:canDismiss:)helper.ThreadDetailViewand adds unit tests covering show/hide conditions and draft-collapse policy.ThreadDetailViewnow shows a "Hide keyboard" control in the composer footer; no change for other call sites that do not passshowsKeyboardDismissControl.Macroscope summarized 7fa7bd1.