Fix Enter key semantics and add expandable model descriptions
- Replace TextEditor with NativeTextEditor (NSViewRepresentable) so plain Enter sends the message and Shift/Cmd+Enter inserts a newline. The old TextEditor passed bare Return directly to NSTextView before SwiftUI's onKeyPress could intercept it, accidentally making Cmd+Enter send instead. - Add More…/Less toggle in ModelInfoView for descriptions longer than 250 characters, with smooth expand/collapse animation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,7 @@ struct InputBar: View {
|
||||
|
||||
@State private var showCommandDropdown = false
|
||||
@State private var selectedSuggestionIndex: Int = 0
|
||||
@FocusState private var isInputFocused: Bool
|
||||
@State private var isInputFocused: Bool = false
|
||||
|
||||
private static let minInputHeight: CGFloat = 56
|
||||
private static let maxInputHeight: CGFloat = 320
|
||||
@@ -95,55 +95,50 @@ struct InputBar: View {
|
||||
}
|
||||
|
||||
// Editor — fills the fixed-height box, bottom area reserved for globe
|
||||
TextEditor(text: $text)
|
||||
.font(.system(size: settings.inputTextSize))
|
||||
.foregroundColor(.oaiPrimary)
|
||||
.scrollContentBackground(.hidden)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.top, 6)
|
||||
.padding(.bottom, 30)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.focused($isInputFocused)
|
||||
.onChange(of: text) {
|
||||
showCommandDropdown = text.hasPrefix("/")
|
||||
selectedSuggestionIndex = 0
|
||||
}
|
||||
#if os(macOS)
|
||||
.onKeyPress(.upArrow) {
|
||||
if showCommandDropdown && selectedSuggestionIndex > 0 {
|
||||
selectedSuggestionIndex -= 1
|
||||
return .handled
|
||||
}
|
||||
return .ignored
|
||||
}
|
||||
.onKeyPress(.downArrow) {
|
||||
if showCommandDropdown {
|
||||
let count = CommandSuggestionsView.filteredCommands(for: text).count
|
||||
if selectedSuggestionIndex < count - 1 {
|
||||
selectedSuggestionIndex += 1
|
||||
return .handled
|
||||
}
|
||||
}
|
||||
return .ignored
|
||||
}
|
||||
.onKeyPress(.escape) {
|
||||
if showCommandDropdown { showCommandDropdown = false; return .handled }
|
||||
if isGenerating { onCancel(); return .handled }
|
||||
return .ignored
|
||||
}
|
||||
.onKeyPress(.return, phases: .down) { press in
|
||||
if press.modifiers.contains(.shift) { return .ignored }
|
||||
NativeTextEditor(
|
||||
text: $text,
|
||||
font: .systemFont(ofSize: settings.inputTextSize),
|
||||
textColor: NSColor(Color.oaiPrimary),
|
||||
isFocused: isInputFocused,
|
||||
onReturn: {
|
||||
if showCommandDropdown {
|
||||
let suggestions = CommandSuggestionsView.filteredCommands(for: text)
|
||||
if !suggestions.isEmpty && selectedSuggestionIndex < suggestions.count {
|
||||
selectCommand(suggestions[selectedSuggestionIndex].command)
|
||||
return .handled
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !text.isEmpty { onSend(); return .handled }
|
||||
return .handled
|
||||
}
|
||||
#endif
|
||||
if !text.isEmpty { onSend(); return true }
|
||||
return true
|
||||
},
|
||||
onEscape: {
|
||||
if showCommandDropdown { showCommandDropdown = false; return true }
|
||||
if isGenerating { onCancel(); return true }
|
||||
return false
|
||||
},
|
||||
onUpArrow: {
|
||||
if showCommandDropdown && selectedSuggestionIndex > 0 {
|
||||
selectedSuggestionIndex -= 1; return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
onDownArrow: {
|
||||
if showCommandDropdown {
|
||||
let count = CommandSuggestionsView.filteredCommands(for: text).count
|
||||
if selectedSuggestionIndex < count - 1 {
|
||||
selectedSuggestionIndex += 1; return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
onFocusChange: { focused in isInputFocused = focused }
|
||||
)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onChange(of: text) {
|
||||
showCommandDropdown = text.hasPrefix("/")
|
||||
selectedSuggestionIndex = 0
|
||||
}
|
||||
.padding(.bottom, 30)
|
||||
|
||||
// Online / offline toggle — bottom-left of the text box
|
||||
VStack {
|
||||
|
||||
Reference in New Issue
Block a user