Skip to content

Commit 93ba322

Browse files
feat(react-native-global-keyevent): add config plugin
https://github.com/mybigday/react-native-global-keyevent Co-Authored-By: Bill Spooner <b@twodoors.dev>
1 parent 4eb10b7 commit 93ba322

File tree

6 files changed

+207
-0
lines changed

6 files changed

+207
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// @generated by expo-module-scripts
2+
module.exports = require('expo-module-scripts/eslintrc.base.js');
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# @config-plugins/react-native-global-keyevent
2+
3+
Expo Config Plugin to auto-configure [`react-native-global-keyevent`](https://www.npmjs.com/package/react-native-global-keyevent) when the native code is generated (`npx expo prebuild`).
4+
5+
## Versioning
6+
7+
| `expo` | `react-native-global-keyevent` | `@config-plugins/react-native-global-keyevent` |
8+
|--------|--------------------------------|------------------------------------------------|
9+
| 51.0.0 | 0.1.4 | ^1.0.0 |
10+
11+
## Expo installation
12+
13+
> This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/).
14+
15+
First install the package with yarn, npm, or [`npx expo install`](https://docs.expo.io/workflow/expo-cli/#expo-install).
16+
17+
```sh
18+
npx expo install react-native-global-keyevent @config-plugins/react-native-global-keyevent
19+
```
20+
21+
After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`:
22+
23+
```json
24+
{
25+
"expo": {
26+
"plugins": ["@config-plugins/react-native-global-keyevent"]
27+
}
28+
}
29+
```
30+
31+
Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.
32+
33+
## API
34+
35+
The plugin does not provide any props for extra customization.
36+
37+
#### Example
38+
39+
```json
40+
{
41+
"expo": {
42+
"plugins": [
43+
"@config-plugins/react-native-global-keyevent"
44+
]
45+
}
46+
}
47+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("./build/withReactNativeGlobalKeyevent");
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "@config-plugins/react-native-global-keyevent",
3+
"version": "0.0.0",
4+
"description": "Config plugin for react-native-global-keyevent package",
5+
"main": "build/withReactNativeGlobalKeyevent.js",
6+
"types": "build/withReactNativeGlobalKeyevent.d.ts",
7+
"sideEffects": false,
8+
"homepage": "https://github.com/mybigday/react-native-global-keyevent",
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/expo/config-plugins.git",
12+
"directory": "packages/react-native-global-keyevent"
13+
},
14+
"scripts": {
15+
"build": "expo-module build",
16+
"clean": "expo-module clean",
17+
"lint": "expo-module lint",
18+
"test": "expo-module test",
19+
"prepare": "expo-module prepare",
20+
"prepublishOnly": "expo-module prepublishOnly",
21+
"expo-module": "expo-module"
22+
},
23+
"keywords": [
24+
"react",
25+
"expo",
26+
"config-plugins",
27+
"prebuild",
28+
"react-native-global-keyevent",
29+
"expo-51"
30+
],
31+
"peerDependencies": {
32+
"expo": "^51"
33+
},
34+
"devDependencies": {
35+
"expo-module-scripts": "^3.5.1"
36+
}
37+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import {
2+
ConfigPlugin,
3+
createRunOncePlugin,
4+
withMainActivity,
5+
} from "@expo/config-plugins";
6+
import { addImports } from "@expo/config-plugins/build/android/codeMod";
7+
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
8+
9+
const MAIN_ACTIVITY_LANGUAGES: Record<
10+
string,
11+
{ code: string; anchor: RegExp }
12+
> = {
13+
java: {
14+
code: `
15+
@Override
16+
public boolean onKeyDown(int keyCode, KeyEvent event) {
17+
GlobalKeyEventModule instance = GlobalKeyEventModule.getInstance();
18+
if (instance != null) instance.onKeyDownEvent(keyCode, event);
19+
return super.onKeyDown(keyCode, event);
20+
}
21+
22+
@Override
23+
public boolean onKeyUp(int keyCode, KeyEvent event) {
24+
GlobalKeyEventModule instance = GlobalKeyEventModule.getInstance();
25+
if (instance != null) instance.onKeyUpEvent(keyCode, event);
26+
return super.onKeyUp(keyCode, event);
27+
}
28+
`,
29+
anchor: /return "main";\n\s*};/,
30+
},
31+
kt: {
32+
code: `
33+
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
34+
val instance = GlobalKeyEventModule.getInstance();
35+
if (instance != null) instance.onKeyDownEvent(keyCode, event);
36+
return super.onKeyDown(keyCode, event);
37+
}
38+
39+
override fun onKeyUp(keyCode: Int , event: KeyEvent): Boolean {
40+
val instance = GlobalKeyEventModule.getInstance();
41+
if (instance != null) instance.onKeyUpEvent(keyCode, event);
42+
return super.onKeyUp(keyCode, event);
43+
}
44+
`,
45+
anchor: /override\sfun\sgetMainComponentName\(\).*/,
46+
},
47+
};
48+
49+
const addKeyBindings = (src: string, language: string) => {
50+
const mainActivity = MAIN_ACTIVITY_LANGUAGES[language];
51+
if (!mainActivity) {
52+
throw new Error(
53+
`react-native-global-keyevent config plugin does not support MainActivity.${language} yet`,
54+
);
55+
}
56+
57+
const newSrc = [];
58+
newSrc.push(` ${mainActivity.code}`);
59+
60+
return mergeContents({
61+
tag: "react-native-global-keyevent-onKey",
62+
src,
63+
newSrc: newSrc.join("\n"),
64+
anchor: mainActivity.anchor,
65+
offset: 1,
66+
comment: "//",
67+
});
68+
};
69+
70+
const withAndroidMainActivityKeyboardEvents: ConfigPlugin<void> = (config) => {
71+
return withMainActivity(config, async (config) => {
72+
const src = addImports(
73+
config.modResults.contents,
74+
["android.view.KeyEvent", "com.globalkeyevent.GlobalKeyEventModule"],
75+
config.modResults.language === "java",
76+
);
77+
78+
config.modResults.contents = addKeyBindings(
79+
src,
80+
config.modResults.language,
81+
).contents;
82+
83+
return config;
84+
});
85+
};
86+
87+
/**
88+
* Apply react-native-global-keyevent configuration for Expo SDK 51 projects.
89+
*/
90+
const withReactNativeGlobalKeyevent: ConfigPlugin<void> = (config) => {
91+
config = withAndroidMainActivityKeyboardEvents(config);
92+
93+
// Return the modified config.
94+
return config;
95+
};
96+
97+
const pkg = {
98+
// Prevent this plugin from being run more than once.
99+
// This pattern enables users to safely migrate off of this
100+
// out-of-tree `@config-plugins/react-native-global-keyevent` to a future
101+
// upstream plugin in `react-native-global-keyevent`
102+
name: "react-native-global-keyevent",
103+
// Indicates that this plugin is dangerously linked to a module,
104+
// and might not work with the latest version of that module.
105+
version: "UNVERSIONED",
106+
};
107+
108+
export default createRunOncePlugin(
109+
withReactNativeGlobalKeyevent,
110+
pkg.name,
111+
pkg.version,
112+
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "expo-module-scripts/tsconfig.plugin",
3+
"compilerOptions": {
4+
"outDir": "./build"
5+
},
6+
"include": ["./src"],
7+
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
8+
}

0 commit comments

Comments
 (0)