wip: Key Commands for Apple devices
This commit is contained in:
parent
7278b36763
commit
2a0bbdc16d
|
@ -0,0 +1,5 @@
|
|||
export interface IKeyCommand {
|
||||
input: string;
|
||||
modifierFlags: number;
|
||||
discoverableTitle: string;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { NativeModules, NativeEventEmitter } from 'react-native';
|
||||
|
||||
import { IKeyCommand } from '../../definitions/IKeyCommand';
|
||||
|
||||
const { KeyCommandsManager } = NativeModules;
|
||||
|
||||
const eventEmitter = new NativeEventEmitter(NativeModules.KeyCommandsManager);
|
||||
|
||||
class KeyCommands {
|
||||
registeredListeners: { [id: string]: (keyCommand: IKeyCommand) => void } = {};
|
||||
|
||||
constructor() {
|
||||
eventEmitter.addListener('onKeyCommand', this.onKeyCommand);
|
||||
}
|
||||
|
||||
onKeyCommand = (keyCommand: IKeyCommand) => {
|
||||
const key = this.makeKey(keyCommand);
|
||||
const listener = this.registeredListeners[key];
|
||||
|
||||
listener(keyCommand);
|
||||
};
|
||||
|
||||
addListener = (keyCommand: IKeyCommand, handler: (keyCommand: IKeyCommand) => void) => {
|
||||
const key = this.makeKey(keyCommand);
|
||||
this.registeredListeners[key] = handler;
|
||||
KeyCommandsManager.registerKeyCommand(keyCommand.input, keyCommand.modifierFlags, keyCommand.discoverableTitle);
|
||||
};
|
||||
|
||||
removeListener = (keyCommand: IKeyCommand) => {
|
||||
const key = this.makeKey(keyCommand);
|
||||
delete this.registeredListeners[key];
|
||||
};
|
||||
|
||||
makeKey = (keyCommand: IKeyCommand): string => keyCommand.input + keyCommand.modifierFlags;
|
||||
}
|
||||
|
||||
export default new KeyCommands();
|
||||
|
||||
// class SearchKeyCommand implements IKeyCommand {
|
||||
// input = "f";
|
||||
// modifierFlags: number = 0;
|
||||
// discoverableTitle: string = "any";
|
||||
// }
|
||||
|
||||
// new KeyCommands().addListener(new Command(), (command) => { console.log(command) })
|
|
@ -0,0 +1,7 @@
|
|||
#import "React/RCTBridgeModule.h"
|
||||
|
||||
@interface RCT_EXTERN_MODULE(KeyCommandsManager, NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(registerKeyCommand:(NSString)input modifierFlags:(nonnull NSNumber)modifierFlags discoverableTitle:(NSString)discoverableTitle)
|
||||
|
||||
@end
|
|
@ -0,0 +1,63 @@
|
|||
@objc protocol KeyCommandHandler {
|
||||
func onKeyCommand(_ command: UIKeyCommand)
|
||||
}
|
||||
|
||||
@objc(KeyCommandsManager)
|
||||
final class KeyCommandsManager: RCTEventEmitter {
|
||||
@objc
|
||||
private(set) static var shared: KeyCommandsManager?
|
||||
|
||||
@objc
|
||||
private(set) var commands: [UIKeyCommand] = []
|
||||
|
||||
@objc
|
||||
static var handler: KeyCommandHandler?
|
||||
|
||||
private struct Event {
|
||||
static let onKeyCommand = "onKeyCommand"
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
KeyCommandsManager.shared = self
|
||||
}
|
||||
|
||||
override func supportedEvents() -> [String] {
|
||||
[Event.onKeyCommand]
|
||||
}
|
||||
|
||||
@objc
|
||||
func registerKeyCommand(_ input: NSString, modifierFlags: NSNumber, discoverableTitle: NSString) {
|
||||
guard let handler = KeyCommandsManager.handler else {
|
||||
return
|
||||
}
|
||||
|
||||
let command = UIKeyCommand(
|
||||
input: String(input),
|
||||
modifierFlags: UIKeyModifierFlags(rawValue: modifierFlags.intValue),
|
||||
action: #selector(handler.onKeyCommand(_:)),
|
||||
discoverabilityTitle: String(discoverableTitle)
|
||||
)
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
command.wantsPriorityOverSystemBehavior = true
|
||||
}
|
||||
|
||||
commands.append(command)
|
||||
}
|
||||
|
||||
@objc
|
||||
func onKeyCommand(_ command: UIKeyCommand) {
|
||||
guard let input = command.input, let discoverabilityTitle = command.discoverabilityTitle else {
|
||||
return
|
||||
}
|
||||
|
||||
let body: [String: Any] = [
|
||||
"input": input,
|
||||
"modifierFlags": NSNumber(integerLiteral: command.modifierFlags.rawValue),
|
||||
"discoverableTitle": discoverabilityTitle
|
||||
]
|
||||
|
||||
sendEvent(withName: Event.onKeyCommand, body: body)
|
||||
}
|
||||
}
|
|
@ -33,12 +33,16 @@
|
|||
1E1EA8162326CD4500E22452 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8152326CD4500E22452 /* VideoToolbox.framework */; };
|
||||
1E1EA8182326CD4B00E22452 /* libc.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8172326CD4B00E22452 /* libc.tbd */; };
|
||||
1E1EA81A2326CD5100E22452 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8192326CD5100E22452 /* libsqlite3.tbd */; };
|
||||
1E2511352AC64A2100EFED30 /* KeyCommandsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2511342AC64A2100EFED30 /* KeyCommandsManager.swift */; };
|
||||
1E2511382AC64A5C00EFED30 /* KeyCommandsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E2511372AC64A5C00EFED30 /* KeyCommandsManager.m */; };
|
||||
1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7ACD4853222860DE00442C55 /* JavaScriptCore.framework */; };
|
||||
1E2F615B25128F9A00871711 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F615A25128F9A00871711 /* API.swift */; };
|
||||
1E2F615D25128FA300871711 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F615C25128FA300871711 /* Response.swift */; };
|
||||
1E2F61642512955D00871711 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F61632512955D00871711 /* HTTPMethod.swift */; };
|
||||
1E2F61662512958900871711 /* Push.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2F61652512958900871711 /* Push.swift */; };
|
||||
1E470E832513A71E00E3DD1D /* RocketChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E470E822513A71E00E3DD1D /* RocketChat.swift */; };
|
||||
1E51A3D32AC7126D00028137 /* KeyCommandsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E2511342AC64A2100EFED30 /* KeyCommandsManager.swift */; };
|
||||
1E51A3D42AC7127000028137 /* KeyCommandsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E2511372AC64A5C00EFED30 /* KeyCommandsManager.m */; };
|
||||
1E51D962251263CD00DC95DE /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D961251263CD00DC95DE /* MessageType.swift */; };
|
||||
1E51D965251263D600DC95DE /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D964251263D600DC95DE /* NotificationType.swift */; };
|
||||
1E598AE42515057D002BDFBD /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE32515057D002BDFBD /* Date+Extensions.swift */; };
|
||||
|
@ -239,6 +243,8 @@
|
|||
1E1EA8152326CD4500E22452 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
|
||||
1E1EA8172326CD4B00E22452 /* libc.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libc.tbd; path = usr/lib/libc.tbd; sourceTree = SDKROOT; };
|
||||
1E1EA8192326CD5100E22452 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||
1E2511342AC64A2100EFED30 /* KeyCommandsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyCommandsManager.swift; sourceTree = "<group>"; };
|
||||
1E2511372AC64A5C00EFED30 /* KeyCommandsManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeyCommandsManager.m; sourceTree = "<group>"; };
|
||||
1E2F615A25128F9A00871711 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = "<group>"; };
|
||||
1E2F615C25128FA300871711 /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
||||
1E2F61632512955D00871711 /* HTTPMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = "<group>"; };
|
||||
|
@ -396,6 +402,15 @@
|
|||
path = API;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1E2511302AC649B800EFED30 /* KeyCommands */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1E2511342AC64A2100EFED30 /* KeyCommandsManager.swift */,
|
||||
1E2511372AC64A5C00EFED30 /* KeyCommandsManager.m */,
|
||||
);
|
||||
path = KeyCommands;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1E2F61622512954500871711 /* Requests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -521,6 +536,7 @@
|
|||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1E2511302AC649B800EFED30 /* KeyCommands */,
|
||||
1E76CBC425152A7F0067298C /* Shared */,
|
||||
1E068CFB24FD2DAF00A0FFC1 /* AppGroup */,
|
||||
13B07FAE1A68108700A75B9A /* RocketChatRN */,
|
||||
|
@ -1347,10 +1363,12 @@
|
|||
1ED00BB12513E04400A1331F /* ReplyNotification.swift in Sources */,
|
||||
1E76CBC2251529560067298C /* Storage.swift in Sources */,
|
||||
1E76CBD925152C8C0067298C /* Push.swift in Sources */,
|
||||
1E2511382AC64A5C00EFED30 /* KeyCommandsManager.m in Sources */,
|
||||
1E0426E6251A5467008F022C /* RoomType.swift in Sources */,
|
||||
1E76CBCD25152C2C0067298C /* MessageType.swift in Sources */,
|
||||
1E76CBC925152C1F0067298C /* PushResponse.swift in Sources */,
|
||||
7A92554628777E0100EC3DA3 /* AppDelegate.mm in Sources */,
|
||||
1E2511352AC64A2100EFED30 /* KeyCommandsManager.swift in Sources */,
|
||||
1E76CBD325152C770067298C /* Encryption.swift in Sources */,
|
||||
1E76CBC825152C070067298C /* RocketChat.swift in Sources */,
|
||||
1E76CBD725152C840067298C /* HTTPMethod.swift in Sources */,
|
||||
|
@ -1428,6 +1446,7 @@
|
|||
7AAB3E19257E6A6E00707CF6 /* Push.swift in Sources */,
|
||||
7AAB3E1A257E6A6E00707CF6 /* RoomType.swift in Sources */,
|
||||
7AAB3E1B257E6A6E00707CF6 /* MessageType.swift in Sources */,
|
||||
1E51A3D32AC7126D00028137 /* KeyCommandsManager.swift in Sources */,
|
||||
7AAB3E1C257E6A6E00707CF6 /* PushResponse.swift in Sources */,
|
||||
7A92554728777E0100EC3DA3 /* AppDelegate.mm in Sources */,
|
||||
7AAB3E1E257E6A6E00707CF6 /* Encryption.swift in Sources */,
|
||||
|
@ -1437,6 +1456,7 @@
|
|||
7AAB3E23257E6A6E00707CF6 /* Data+Extensions.swift in Sources */,
|
||||
7AAB3E24257E6A6E00707CF6 /* Date+Extensions.swift in Sources */,
|
||||
7AAB3E25257E6A6E00707CF6 /* Database.swift in Sources */,
|
||||
1E51A3D42AC7127000028137 /* KeyCommandsManager.m in Sources */,
|
||||
7AAB3E26257E6A6E00707CF6 /* String+Extensions.swift in Sources */,
|
||||
7AAB3E27257E6A6E00707CF6 /* Notification.swift in Sources */,
|
||||
7AAB3E28257E6A6E00707CF6 /* API.swift in Sources */,
|
||||
|
@ -1499,6 +1519,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
|
@ -1555,6 +1576,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = RocketChatRN/RocketChatRN.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
|
@ -1646,7 +1668,7 @@
|
|||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
|
||||
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
|
||||
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
|
||||
);
|
||||
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
|
@ -1714,7 +1736,7 @@
|
|||
"$(inherited)",
|
||||
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
|
||||
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
|
||||
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
|
||||
);
|
||||
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#import "ExpoModulesCore-Swift.h"
|
||||
#import "RocketChatRN-Swift.h"
|
||||
|
||||
@interface AppDelegate : EXAppDelegateWrapper <UIApplicationDelegate, RCTBridgeDelegate>
|
||||
@interface AppDelegate : EXAppDelegateWrapper <UIApplicationDelegate, RCTBridgeDelegate, KeyCommandHandler>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
self.window.rootViewController = navigationController;
|
||||
[self.window makeKeyAndVisible];
|
||||
[RNNotifications startMonitorNotifications];
|
||||
[KeyCommandsManager setHandler:self];
|
||||
[ReplyNotification configure];
|
||||
|
||||
// AppGroup MMKV
|
||||
|
@ -73,6 +74,23 @@
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands {
|
||||
if ([KeyCommandsManager shared]) {
|
||||
return [[KeyCommandsManager shared] commands];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (void)onKeyCommand:(UIKeyCommand *)keyCommand {
|
||||
if ([KeyCommandsManager shared]) {
|
||||
[[KeyCommandsManager shared] onKeyCommand:keyCommand];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
|
|
Loading…
Reference in New Issue