react-native-earl-gamepad 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,9 +16,9 @@ WebView-based gamepad bridge for React Native. Polls `navigator.getGamepads()` i
16
16
  ## Install
17
17
 
18
18
  ```sh
19
- npm install react-native-earl-gamepad react-native-webview
19
+ npm install react-native-earl-gamepad
20
20
  # or
21
- yarn add react-native-earl-gamepad react-native-webview
21
+ yarn add react-native-earl-gamepad
22
22
  ```
23
23
 
24
24
  ## Usage
@@ -153,6 +153,11 @@ npm install
153
153
  npm run build
154
154
  ```
155
155
 
156
+ ## Troubleshooting
157
+
158
+ - **[Invariant Violation: Tried to register two views with the same name RNCWebView]**: Check your `package.json` for multiple instances of `react-native-webview` and uninstall any duplicates.
159
+ When you install `react-native-earl-gamepad`, `react-native-webview` is already included, so you should not install it separately. or you can check it by running `npm ls react-native-webview`.
160
+
156
161
  Build outputs to `dist/` with type declarations.
157
162
 
158
163
  ## License
@@ -100,7 +100,19 @@ const buildBridgeHtml = (axisThreshold) => `
100
100
  </script>
101
101
  </body></html>`;
102
102
  function GamepadBridge({ enabled = true, axisThreshold = 0.15, onDpad, onButton, onAxis, onStatus, style, }) {
103
+ const webviewRef = (0, react_1.useRef)(null);
103
104
  const html = (0, react_1.useMemo)(() => buildBridgeHtml(axisThreshold), [axisThreshold]);
105
+ const focusBridge = (0, react_1.useCallback)(() => {
106
+ var _a, _b;
107
+ // On Android controllers, ensure the WebView is focusable so DPAD events feed navigator.getGamepads
108
+ const node = webviewRef.current;
109
+ (_a = node === null || node === void 0 ? void 0 : node.setNativeProps) === null || _a === void 0 ? void 0 : _a.call(node, { focusable: true, focusableInTouchMode: true });
110
+ (_b = node === null || node === void 0 ? void 0 : node.requestFocus) === null || _b === void 0 ? void 0 : _b.call(node);
111
+ }, []);
112
+ (0, react_1.useEffect)(() => {
113
+ if (enabled)
114
+ focusBridge();
115
+ }, [enabled, focusBridge]);
104
116
  if (!enabled)
105
117
  return null;
106
118
  const handleMessage = (event) => {
@@ -123,5 +135,5 @@ function GamepadBridge({ enabled = true, axisThreshold = 0.15, onDpad, onButton,
123
135
  // ignore malformed messages
124
136
  }
125
137
  };
126
- return ((0, jsx_runtime_1.jsx)(react_native_webview_1.default, { source: { html }, originWhitelist: ['*'], onMessage: handleMessage, javaScriptEnabled: true, style: style !== null && style !== void 0 ? style : { width: 1, height: 1, position: 'absolute', opacity: 0 } }));
138
+ return ((0, jsx_runtime_1.jsx)(react_native_webview_1.default, { ref: webviewRef, source: { html }, originWhitelist: ['*'], onMessage: handleMessage, javaScriptEnabled: true, onLoad: focusBridge, onLayout: focusBridge, onTouchStart: focusBridge, style: style !== null && style !== void 0 ? style : { width: 1, height: 1, position: 'absolute', opacity: 0 } }));
127
139
  }
@@ -129,7 +129,8 @@ function ControllerVisual({ pressed, axis, value }) {
129
129
  ], children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
130
130
  styles.psRollInIn,
131
131
  { backgroundColor: stickInner(leftMag) },
132
- pressed("ls") && styles.psStickCenterPressed,
132
+ pressed("ls") &&
133
+ styles.psStickCenterPressed,
133
134
  ] }) }) }), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
134
135
  styles.psPsButton,
135
136
  pressed("home") && styles.psActiveButton,
@@ -149,7 +150,8 @@ function ControllerVisual({ pressed, axis, value }) {
149
150
  ], children: (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
150
151
  styles.psRollInIn,
151
152
  { backgroundColor: stickInner(rightMag) },
152
- pressed("rs") && styles.psStickCenterPressed,
153
+ pressed("rs") &&
154
+ styles.psStickCenterPressed,
153
155
  ] }) }) })] })] }) }));
154
156
  }
155
157
  function GamepadDebug({ enabled = true, axisThreshold = 0.15, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-earl-gamepad",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "React Native gamepad bridge via WebView (buttons, sticks, d-pad, status).",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",