From 98ced60887860410fcce1e087a88b7e10e7e49f1 Mon Sep 17 00:00:00 2001 From: CDFMLR Date: Thu, 27 Jun 2024 14:42:14 +0800 Subject: [PATCH] fix: make macOS input field scrollable Optimize the long text input experience for macOS users. The past implementation of the input field could not scroll (as the iMessage's input box does) after the input box grew to the maximum height, nor could it display the complete content in this case, which made it annoying to edit this long text with in the app. This commit solves this problem by makes the InputFieldsView scrollable after it's height increasing to a max. --- .../Chat/Components/InputFields_macOS.swift | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/Enchanted/UI/macOS/Chat/Components/InputFields_macOS.swift b/Enchanted/UI/macOS/Chat/Components/InputFields_macOS.swift index bca42bf1..8cad4547 100644 --- a/Enchanted/UI/macOS/Chat/Components/InputFields_macOS.swift +++ b/Enchanted/UI/macOS/Chat/Components/InputFields_macOS.swift @@ -20,6 +20,7 @@ struct InputFieldsView: View { @State private var selectedImage: Image? @State private var fileDropActive: Bool = false @State private var fileSelectingActive: Bool = false + @State private var textFieldHeight: CGFloat = 40 @FocusState private var isFocusedInput: Bool @MainActor private func sendMessage() { @@ -69,27 +70,45 @@ struct InputFieldsView: View { } ZStack(alignment: .trailing) { - TextField("Message", text: $message.animation(.easeOut(duration: 0.3)), axis: .vertical) - .focused($isFocusedInput) - .font(.system(size: 14)) - .frame(maxWidth:.infinity, minHeight: 40) - .clipped() - .textFieldStyle(.plain) + ScrollViewReader { scrollView in + ScrollView { + TextField("Message", + text: $message.animation(.easeOut(duration: 0.3)), + axis: .vertical) + .focused($isFocusedInput) + .font(.system(size: 14)) + .frame(maxWidth:.infinity, minHeight: 40) + .clipped() + .textFieldStyle(.plain) + .overlay { + GeometryReader { geo in + Color.clear.onChange(of: geo.size.height) { + withAnimation { + self.textFieldHeight = geo.size.height + } + } + } + } + #if os(macOS) - .onSubmit { - if NSApp.currentEvent?.modifierFlags.contains(.shift) == true { - message += "\n" - } else { - sendMessage() + .onSubmit { + if NSApp.currentEvent?.modifierFlags.contains(.shift) == true { + message += "\n" + } else { + sendMessage() + } } - } #endif - /// TextField bypasses drop area - .allowsHitTesting(!fileDropActive) + /// TextField bypasses drop area + .allowsHitTesting(!fileDropActive) #if os(macOS) - .addCustomHotkeys(hotkeys) + .addCustomHotkeys(hotkeys) #endif - .padding(.trailing, 80) + .padding(.trailing, 80) + } + .frame(maxHeight: min(textFieldHeight, 120+10)) + // plus 10 to indicate it's scrollable. + } HStack {