mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 18:44:45 +00:00
fix(chat): stop placeholder ghosting in chat composer (#65)
`TextEditor`'s NSTextView surfaces a typed glyph one frame before the SwiftUI binding propagates, so the bare `if text.isEmpty` overlay rendered the translucent placeholder text directly on top of the just-typed character — the "behind or around" ghost the reporter described. Two mitigations: - Pin an opaque `ScarfColor.backgroundSecondary` rect behind the placeholder Text. During any single-frame binding lag the user now sees a clean placeholder rather than layered glyphs. - Switch the conditional to `.opacity(text.isEmpty ? 1 : 0)` so the view tree stays stable per keystroke. Pairs with the composer perf fix from #67. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -108,16 +108,33 @@ struct RichChatInputBar: View {
|
||||
)
|
||||
)
|
||||
.overlay(alignment: .topLeading) {
|
||||
if text.isEmpty {
|
||||
Text(supportsImagePrompts
|
||||
? "Message Hermes… / for commands · drag images to attach"
|
||||
: "Message Hermes… / for commands")
|
||||
.scarfStyle(.body)
|
||||
.foregroundStyle(ScarfColor.foregroundFaint)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 10)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
// Placeholder ghosting (#65): TextEditor's
|
||||
// NSTextView updates the visible glyphs a frame
|
||||
// before the SwiftUI binding propagates, so a
|
||||
// bare `if text.isEmpty` overlay renders the
|
||||
// translucent placeholder text on top of the
|
||||
// just-typed character — visible as a "behind
|
||||
// or around" ghost. Two mitigations:
|
||||
//
|
||||
// 1. Pin an opaque rectangle behind the
|
||||
// placeholder text. During any single-
|
||||
// frame lag the user sees a clean
|
||||
// placeholder, never layered glyphs.
|
||||
// 2. Use `.opacity(...)` instead of an `if`.
|
||||
// Keeps the view tree stable per
|
||||
// keystroke (removes the per-keystroke
|
||||
// view-mutation churn the composer was
|
||||
// already paying for).
|
||||
Text(supportsImagePrompts
|
||||
? "Message Hermes… / for commands · drag images to attach"
|
||||
: "Message Hermes… / for commands")
|
||||
.scarfStyle(.body)
|
||||
.foregroundStyle(ScarfColor.foregroundFaint)
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 10)
|
||||
.background(ScarfColor.backgroundSecondary)
|
||||
.opacity(text.isEmpty ? 1 : 0)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
// Drag-drop image attachments. Receives both file URLs
|
||||
// (from Finder) and raw image bitmap data (from
|
||||
|
||||
Reference in New Issue
Block a user