Skip to content

Commit

Permalink
feat(react-native-global-keyevent): add config plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
hassankhan and sandyklark committed Jul 20, 2024
1 parent 4eb10b7 commit 93ba322
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/react-native-global-keyevent/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @generated by expo-module-scripts
module.exports = require('expo-module-scripts/eslintrc.base.js');
47 changes: 47 additions & 0 deletions packages/react-native-global-keyevent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# @config-plugins/react-native-global-keyevent

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`).

## Versioning

| `expo` | `react-native-global-keyevent` | `@config-plugins/react-native-global-keyevent` |
|--------|--------------------------------|------------------------------------------------|
| 51.0.0 | 0.1.4 | ^1.0.0 |

## Expo installation

> This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/).
First install the package with yarn, npm, or [`npx expo install`](https://docs.expo.io/workflow/expo-cli/#expo-install).

```sh
npx expo install react-native-global-keyevent @config-plugins/react-native-global-keyevent
```

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`:

```json
{
"expo": {
"plugins": ["@config-plugins/react-native-global-keyevent"]
}
}
```

Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.

## API

The plugin does not provide any props for extra customization.

#### Example

```json
{
"expo": {
"plugins": [
"@config-plugins/react-native-global-keyevent"
]
}
}
```
1 change: 1 addition & 0 deletions packages/react-native-global-keyevent/app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./build/withReactNativeGlobalKeyevent");
37 changes: 37 additions & 0 deletions packages/react-native-global-keyevent/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@config-plugins/react-native-global-keyevent",
"version": "0.0.0",
"description": "Config plugin for react-native-global-keyevent package",
"main": "build/withReactNativeGlobalKeyevent.js",
"types": "build/withReactNativeGlobalKeyevent.d.ts",
"sideEffects": false,
"homepage": "https://github.com/mybigday/react-native-global-keyevent",
"repository": {
"type": "git",
"url": "https://github.com/expo/config-plugins.git",
"directory": "packages/react-native-global-keyevent"
},
"scripts": {
"build": "expo-module build",
"clean": "expo-module clean",
"lint": "expo-module lint",
"test": "expo-module test",
"prepare": "expo-module prepare",
"prepublishOnly": "expo-module prepublishOnly",
"expo-module": "expo-module"
},
"keywords": [
"react",
"expo",
"config-plugins",
"prebuild",
"react-native-global-keyevent",
"expo-51"
],
"peerDependencies": {
"expo": "^51"
},
"devDependencies": {
"expo-module-scripts": "^3.5.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {
ConfigPlugin,
createRunOncePlugin,
withMainActivity,
} from "@expo/config-plugins";
import { addImports } from "@expo/config-plugins/build/android/codeMod";
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";

const MAIN_ACTIVITY_LANGUAGES: Record<
string,
{ code: string; anchor: RegExp }
> = {
java: {
code: `
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
GlobalKeyEventModule instance = GlobalKeyEventModule.getInstance();
if (instance != null) instance.onKeyDownEvent(keyCode, event);
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
GlobalKeyEventModule instance = GlobalKeyEventModule.getInstance();
if (instance != null) instance.onKeyUpEvent(keyCode, event);
return super.onKeyUp(keyCode, event);
}
`,
anchor: /return "main";\n\s*};/,
},
kt: {
code: `
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
val instance = GlobalKeyEventModule.getInstance();
if (instance != null) instance.onKeyDownEvent(keyCode, event);
return super.onKeyDown(keyCode, event);
}
override fun onKeyUp(keyCode: Int , event: KeyEvent): Boolean {
val instance = GlobalKeyEventModule.getInstance();
if (instance != null) instance.onKeyUpEvent(keyCode, event);
return super.onKeyUp(keyCode, event);
}
`,
anchor: /override\sfun\sgetMainComponentName\(\).*/,
},
};

const addKeyBindings = (src: string, language: string) => {
const mainActivity = MAIN_ACTIVITY_LANGUAGES[language];
if (!mainActivity) {
throw new Error(
`react-native-global-keyevent config plugin does not support MainActivity.${language} yet`,
);
}

const newSrc = [];
newSrc.push(` ${mainActivity.code}`);

return mergeContents({
tag: "react-native-global-keyevent-onKey",
src,
newSrc: newSrc.join("\n"),
anchor: mainActivity.anchor,
offset: 1,
comment: "//",
});
};

const withAndroidMainActivityKeyboardEvents: ConfigPlugin<void> = (config) => {
return withMainActivity(config, async (config) => {
const src = addImports(
config.modResults.contents,
["android.view.KeyEvent", "com.globalkeyevent.GlobalKeyEventModule"],
config.modResults.language === "java",
);

config.modResults.contents = addKeyBindings(
src,
config.modResults.language,
).contents;

return config;
});
};

/**
* Apply react-native-global-keyevent configuration for Expo SDK 51 projects.
*/
const withReactNativeGlobalKeyevent: ConfigPlugin<void> = (config) => {
config = withAndroidMainActivityKeyboardEvents(config);

// Return the modified config.
return config;
};

const pkg = {
// Prevent this plugin from being run more than once.
// This pattern enables users to safely migrate off of this
// out-of-tree `@config-plugins/react-native-global-keyevent` to a future
// upstream plugin in `react-native-global-keyevent`
name: "react-native-global-keyevent",
// Indicates that this plugin is dangerously linked to a module,
// and might not work with the latest version of that module.
version: "UNVERSIONED",
};

export default createRunOncePlugin(
withReactNativeGlobalKeyevent,
pkg.name,
pkg.version,
);
8 changes: 8 additions & 0 deletions packages/react-native-global-keyevent/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "expo-module-scripts/tsconfig.plugin",
"compilerOptions": {
"outDir": "./build"
},
"include": ["./src"],
"exclude": ["**/__mocks__/*", "**/__tests__/*"]
}

0 comments on commit 93ba322

Please sign in to comment.