mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Autofocus emoji search and send the first result with the return key on macOS. (#3644)
* Autofocus emoji search and send the first result with the return key on macOS. * Add an extra condition to make sure the user has entered a search string before sending.
This commit is contained in:
parent
888a61ace1
commit
365797c8b7
@ -5,6 +5,7 @@
|
|||||||
// Please see LICENSE in the repository root for full details.
|
// Please see LICENSE in the repository root for full details.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import GameController
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SwiftUIIntrospect
|
import SwiftUIIntrospect
|
||||||
|
|
||||||
@ -165,7 +166,18 @@ private struct SearchController: UIViewControllerRepresentable {
|
|||||||
|
|
||||||
// MARK: - Searchable Extensions
|
// MARK: - Searchable Extensions
|
||||||
|
|
||||||
struct IsSearchingModifier: ViewModifier {
|
extension View {
|
||||||
|
func isSearching(_ isSearching: Binding<Bool>) -> some View {
|
||||||
|
modifier(IsSearchingModifier(isSearching: isSearching))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Automatically focusses the view's search field if a hardware keyboard is connected.
|
||||||
|
func focusSearchIfHardwareKeyboardAvailable() -> some View {
|
||||||
|
modifier(FocusSearchIfHardwareKeyboardAvailableModifier())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct IsSearchingModifier: ViewModifier {
|
||||||
@Environment(\.isSearching) private var isSearchingEnv
|
@Environment(\.isSearching) private var isSearchingEnv
|
||||||
@Binding var isSearching: Bool
|
@Binding var isSearching: Bool
|
||||||
|
|
||||||
@ -175,8 +187,26 @@ struct IsSearchingModifier: ViewModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension View {
|
private struct FocusSearchIfHardwareKeyboardAvailableModifier: ViewModifier {
|
||||||
func isSearching(_ isSearching: Binding<Bool>) -> some View {
|
@FocusState private var isFocused
|
||||||
modifier(IsSearchingModifier(isSearching: isSearching))
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
if #available(iOS 18.0, *) {
|
||||||
|
content
|
||||||
|
.searchFocused($isFocused)
|
||||||
|
.onAppear(perform: focusIfHardwareKeyboardAvailable)
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func focusIfHardwareKeyboardAvailable() {
|
||||||
|
// The simulator always detects the hardware keyboard as connected
|
||||||
|
#if !targetEnvironment(simulator)
|
||||||
|
if GCKeyboard.coalesced != nil {
|
||||||
|
MXLog.info("Hardware keyboard is connected")
|
||||||
|
isFocused = true
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ struct EmojiPickerScreen: View {
|
|||||||
.toolbar { toolbar }
|
.toolbar { toolbar }
|
||||||
.isSearching($isSearching)
|
.isSearching($isSearching)
|
||||||
.searchable(text: $searchString, placement: .navigationBarDrawer(displayMode: .always))
|
.searchable(text: $searchString, placement: .navigationBarDrawer(displayMode: .always))
|
||||||
|
.focusSearchIfHardwareKeyboardAvailable()
|
||||||
|
.onSubmit(of: .search, sendFirstEmojiOnMac)
|
||||||
.compoundSearchField()
|
.compoundSearchField()
|
||||||
}
|
}
|
||||||
.presentationDetents([.medium, .large])
|
.presentationDetents([.medium, .large])
|
||||||
@ -76,6 +78,15 @@ struct EmojiPickerScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendFirstEmojiOnMac() {
|
||||||
|
// No sure-fire way to detect that the submit came from a h/w keyboard on iOS/iPadOS.
|
||||||
|
guard ProcessInfo.processInfo.isiOSAppOnMac else { return }
|
||||||
|
|
||||||
|
if !searchString.isBlank, let emoji = context.viewState.categories.first?.emojis.first {
|
||||||
|
context.send(viewAction: .emojiTapped(emoji: emoji))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
Loading…
x
Reference in New Issue
Block a user