Skip to content

Instantly share code, notes, and snippets.

@Fiser12
Created July 13, 2021 09:00
Show Gist options
  • Save Fiser12/b14c0a5006b26d33036298e389585c6d to your computer and use it in GitHub Desktop.
Save Fiser12/b14c0a5006b26d33036298e389585c6d to your computer and use it in GitHub Desktop.
import Combine
import ComposableArchitecture
import KeyboardShortcuts
public struct KeyboardShortcutManager {
public enum Action: Equatable {
case onKeyDown(UUID)
case onKeyUp(UUID)
}
var bind: ([UUID]) -> Effect<Action, Never> = { _ in _unimplemented("bind") }
public func bind(uuids: [UUID]) -> Effect<Action, Never> {
self.bind(uuids)
}
}
extension KeyboardShortcutManager {
public struct Properties: Equatable {
var uuid: UUID? = nil
public init(uuid: UUID? = nil) {
self.uuid = uuid
}
}
}
extension KeyboardShortcutManager {
private static var subscriber: Effect<KeyboardShortcutManager.Action, Never>.Subscriber? = nil
public static let live: () -> KeyboardShortcutManager = {
var manager = KeyboardShortcutManager()
manager.bind = { uuids in
Effect.run { subscriber in
KeyboardShortcutManager.subscriber = subscriber
uuids.forEach{ uuid in
KeyboardShortcuts.onKeyDown(for: KeyboardShortcuts.Name(uuid.uuidString)) {
subscriber.send(.onKeyDown(uuid))
}
KeyboardShortcuts.onKeyUp(for: KeyboardShortcuts.Name(uuid.uuidString)) {
subscriber.send(.onKeyUp(uuid))
}
}
return AnyCancellable {
KeyboardShortcutManager.subscriber = nil
}
}
}
return manager
}
}
public func _unimplemented(
_ function: StaticString, file: StaticString = #file, line: UInt = #line
) -> Never {
fatalError(
"""
`\(function)` was called but is not implemented. Be sure to provide an implementation for
this endpoint when creating the mock.
""",
file: file,
line: line
)
}
@Fiser12
Copy link
Author

Fiser12 commented Jul 13, 2021

Here an example of how to bind one UUID for listening when they are pressing buttons. I am using UUIDs as strings to avoid possible collisions. You should register the key previously with the library KeyboardShortcuts from SwiftUI allow the user to create customizable keys for custom elements.

        return environment.keyboardShortcutManager.bind(uuids: forms.map{$0.key})
            .map{
                switch $0 {
                case let .onKeyDown(uuid):
                    return AppEvent.ui(.keyboardShorcuts(.onKeyDown(uuid)))
                case let .onKeyUp(uuid):
                    return AppEvent.ui(.keyboardShorcuts(.onKeyUp(uuid)))
                }
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment