From 29833b9614b1b0957c44d7283be9bd42c4494bd9 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 17 Jan 2024 10:06:31 +0200 Subject: [PATCH] Fixes #1911 - Automatically focus the composer when a hardware keyboards is connected (#2343) --- .../ComposerToolbarViewModel.swift | 22 ++++++++++++++++++- .../View/ComposerToolbar.swift | 3 +++ .../View/MessageComposer.swift | 2 -- changelog.d/1911.feature | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 changelog.d/1911.feature diff --git a/ElementX/Sources/Screens/ComposerToolbar/ComposerToolbarViewModel.swift b/ElementX/Sources/Screens/ComposerToolbar/ComposerToolbarViewModel.swift index ac48b3043..6bf2e2e94 100644 --- a/ElementX/Sources/Screens/ComposerToolbar/ComposerToolbarViewModel.swift +++ b/ElementX/Sources/Screens/ComposerToolbar/ComposerToolbarViewModel.swift @@ -16,6 +16,7 @@ import Combine import Foundation +import GameKit import SwiftUI import WysiwygComposer @@ -100,8 +101,10 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool .store(in: &cancellables) setupMentionsHandling(mentionDisplayHelper: mentionDisplayHelper) + + focusComposerIfHardwareKeyboardConnected() } - + // MARK: - Public override func process(viewAction: ComposerToolbarViewAction) { @@ -361,6 +364,23 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool private func removeLinks() { wysiwygViewModel.applyLinkOperation(.removeLinks) } + + private func focusComposerIfHardwareKeyboardConnected() { + // The simulator always detects the hardware keyboard as connected + #if !targetEnvironment(simulator) + if GCKeyboard.coalesced != nil { + MXLog.info("Hardware keyboard is connected") + state.bindings.composerFocused = true + } + + NotificationCenter.default.addObserver(self, selector: #selector(hardwareKeyboardDidConnect), name: .GCKeyboardDidConnect, object: nil) + #endif + } + + @objc private func hardwareKeyboardDidConnect(_ notification: Notification) { + MXLog.info("Did connect hardware keyboard") + state.bindings.composerFocused = true + } } private extension LinkAction { diff --git a/ElementX/Sources/Screens/ComposerToolbar/View/ComposerToolbar.swift b/ElementX/Sources/Screens/ComposerToolbar/View/ComposerToolbar.swift index 24eba0bb7..569340dcf 100644 --- a/ElementX/Sources/Screens/ComposerToolbar/View/ComposerToolbar.swift +++ b/ElementX/Sources/Screens/ComposerToolbar/View/ComposerToolbar.swift @@ -190,6 +190,9 @@ struct ComposerToolbar: View { .onChange(of: composerFocused) { newValue in context.composerFocused = newValue } + .onAppear { + composerFocused = context.composerFocused + } } private var placeholder: String { diff --git a/ElementX/Sources/Screens/ComposerToolbar/View/MessageComposer.swift b/ElementX/Sources/Screens/ComposerToolbar/View/MessageComposer.swift index 829d7338b..2a4e97a07 100644 --- a/ElementX/Sources/Screens/ComposerToolbar/View/MessageComposer.swift +++ b/ElementX/Sources/Screens/ComposerToolbar/View/MessageComposer.swift @@ -31,7 +31,6 @@ struct MessageComposer: View { let replyCancellationAction: () -> Void let editCancellationAction: () -> Void let onAppearAction: () -> Void - @FocusState private var focused: Bool @State private var composerTranslation: CGFloat = 0 private let composerShape = RoundedRectangle(cornerRadius: 21, style: .circular) @@ -77,7 +76,6 @@ struct MessageComposer: View { alignment: .top) .tint(.compound.iconAccentTertiary) .padding(.vertical, 10) - .focused($focused) .onAppear { onAppearAction() } diff --git a/changelog.d/1911.feature b/changelog.d/1911.feature new file mode 100644 index 000000000..c4ad89cb0 --- /dev/null +++ b/changelog.d/1911.feature @@ -0,0 +1 @@ +Automatically focus the composer when a hardware keyboards is connected \ No newline at end of file