Skip to content

Commit c7569e5

Browse files
tconnsduguyihou
andauthored
feat: add listener, fix android window focus (#8)
* feat: 🎸 add listener, fix android window focus Mapping func like react-native-orientation-locker typescript, fix android error window focus, update document readme * build: node 18.19.1 * chore: fmt * chore: ts check --------- Co-authored-by: duguyihou <[email protected]>
1 parent 18993f0 commit c7569e5

File tree

10 files changed

+390
-82
lines changed

10 files changed

+390
-82
lines changed

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18.14.0
1+
18.19.1

README.md

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,63 @@ Add the following to your project's AppDelegate.mm:
3636

3737
@end
3838
```
39+
40+
### Android
41+
42+
Implement onConfigurationChanged method (in MainActivity.kt)
43+
44+
```kotlin
45+
46+
import android.content.Intent
47+
import android.content.res.Configuration
48+
49+
// ...
50+
51+
52+
class MainActivity : ReactActivity() {
53+
//...
54+
override fun onConfigurationChanged(newConfig: Configuration) {
55+
super.onConfigurationChanged(newConfig)
56+
val intent = Intent("onConfigurationChanged")
57+
intent.putExtra("newConfig", newConfig)
58+
this.sendBroadcast(intent)
59+
}
60+
}
61+
```
62+
63+
Add following to MainApplication.kt
64+
65+
```kotlin
66+
67+
import com.neoorientation.NeoOrientationActivityLifecycle
68+
import com.neoorientation.NeoOrientationPackage
69+
//...
70+
71+
class MainApplication : Application(), ReactApplication {
72+
73+
override val reactNativeHost: ReactNativeHost =
74+
object : DefaultReactNativeHost(this) {
75+
override fun getPackages(): List<ReactPackage> =
76+
PackageList(this).packages.apply {
77+
// Packages that cannot be autolinked yet can be added manually here, for example:
78+
// add(MyReactNativePackage())
79+
add(NeoOrientationPackage())
80+
}
81+
//...
82+
}
83+
84+
override fun onCreate() {
85+
//...
86+
registerActivityLifecycleCallbacks(NeoOrientationActivityLifecycle.instance)
87+
}
88+
}
89+
```
3990
## Usage
4091

4192
```typescript
4293
import { Button, StyleSheet, Text, View } from 'react-native';
4394
import React from 'react';
44-
import NeoOrientation from 'react-native-neo-orientation';
95+
import NeoOrientation, { useDeviceOrientationChange, useOrientationChange } from 'react-native-neo-orientation';
4596

4697
const Home = () => {
4798
const handleLockTolandscape = () => {
@@ -63,6 +114,15 @@ const Home = () => {
63114
const handleUnlockAllOrientations = () => {
64115
NeoOrientation.unlockAllOrientations();
65116
};
117+
118+
useDeviceOrientationChange((o) => {
119+
// Handle device orientation change
120+
});
121+
122+
useOrientationChange((o) => {
123+
// Handle orientation change
124+
});
125+
66126
return (
67127
<View style={styles.container}>
68128
<Text style={styles.text}>Home</Text>
@@ -105,6 +165,16 @@ const styles = StyleSheet.create({
105165
});
106166
```
107167

168+
## Events
169+
170+
- `addOrientationListener(function(orientation))`
171+
- `removeOrientationListener(function(orientation))`
172+
- `addDeviceOrientationListener(function(deviceOrientation))`
173+
- `removeDeviceOrientationListener(function(deviceOrientation))`
174+
- `addLockListener(function(orientation))`
175+
- `removeLockListener(function(orientation))`
176+
- `removeAllListeners()`
177+
108178
## Functions
109179

110180
- `lockToLandscape`
@@ -114,6 +184,9 @@ const styles = StyleSheet.create({
114184
- `lockToLandscapeLeft`
115185
- `lockToAllOrientationButUpsideDown`
116186
- `unlockAllOrientations`
187+
- `getOrientation`
188+
- `getDeviceOrientation`
189+
- `isLocked`
117190

118191
## Contributing
119192

android/src/main/java/com/neoorientation/NeoOrientationModule.kt

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package com.neoorientation
22

3+
import android.annotation.SuppressLint
34
import android.content.BroadcastReceiver
45
import android.content.Context
56
import android.content.Intent
67
import android.content.IntentFilter
78
import android.content.pm.ActivityInfo
89
import android.hardware.SensorManager
9-
import android.os.Build
1010
import android.provider.Settings
1111
import android.view.OrientationEventListener
1212
import android.view.Surface
@@ -20,9 +20,8 @@ import com.facebook.react.bridge.ReactMethod
2020
import com.facebook.react.common.ReactConstants
2121
import com.facebook.react.modules.core.DeviceEventManagerModule
2222

23-
class NeoOrientationModule(reactContext: ReactApplicationContext) :
23+
class NeoOrientationModule(private val reactContext: ReactApplicationContext) :
2424
ReactContextBaseJavaModule(reactContext), NeoOrientationListeners {
25-
private val reactContext: ReactApplicationContext
2625
private val mReceiver: BroadcastReceiver
2726
private val mOrientationListener: OrientationEventListener
2827
private var isLocking = false
@@ -31,7 +30,6 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
3130
private var lastDeviceOrientation = ""
3231

3332
init {
34-
this.reactContext = reactContext
3533
mOrientationListener =
3634
object : OrientationEventListener(reactContext, SensorManager.SENSOR_DELAY_UI) {
3735
override fun onOrientationChanged(p0: Int) {
@@ -54,8 +52,7 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
5452
if (reactContext.hasActiveReactInstance()) {
5553
reactContext.getJSModule(
5654
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
57-
)
58-
.emit("deviceOrientationDidChange", params)
55+
).emit("deviceOrientationDidChange", params)
5956
}
6057
}
6158
val orientation: String = currentOrientation
@@ -64,14 +61,11 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
6461
val params = Arguments.createMap()
6562
params.putString("orientation", orientation)
6663
if (reactContext.hasActiveReactInstance()) {
67-
reactContext
68-
.getJSModule(
69-
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
70-
)
71-
.emit("orientationDidChange", params)
64+
reactContext.getJSModule(
65+
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
66+
).emit("orientationDidChange", params)
7267
}
7368
}
74-
return
7569
}
7670
}
7771
if (mOrientationListener.canDetectOrientation()) {
@@ -86,11 +80,9 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
8680
val params = Arguments.createMap()
8781
params.putString("orientation", orientation)
8882
if (reactContext.hasActiveReactInstance()) {
89-
reactContext
90-
.getJSModule(
91-
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
92-
)
93-
.emit("orientationDidChange", params)
83+
reactContext.getJSModule(
84+
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
85+
).emit("orientationDidChange", params)
9486
}
9587
}
9688
}
@@ -99,15 +91,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
9991

10092
private val currentOrientation: String
10193
get() {
102-
val display =
103-
(reactApplicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
104-
when (display.rotation) {
105-
Surface.ROTATION_0 -> return "portrait"
106-
Surface.ROTATION_90 -> return "landscapeLeft"
107-
Surface.ROTATION_180 -> return "portraitUpsideDown"
108-
Surface.ROTATION_270 -> return "landscapeRight"
94+
val display = (reactApplicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
95+
return when (display.rotation) {
96+
Surface.ROTATION_0 -> "portrait"
97+
Surface.ROTATION_90 -> "landscapeLeft"
98+
Surface.ROTATION_180 -> "portraitUpsideDown"
99+
Surface.ROTATION_270 -> "landscapeRight"
100+
else -> "unknown"
109101
}
110-
return "unknown"
111102
}
112103

113104
override fun getName(): String {
@@ -141,8 +132,7 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
141132
val lockParams = Arguments.createMap()
142133
lockParams.putString("orientation", lastOrientation)
143134
if (reactContext.hasActiveReactInstance()) {
144-
reactContext
145-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
135+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
146136
.emit("lockDidChange", lockParams)
147137
}
148138
}
@@ -157,16 +147,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
157147
val params = Arguments.createMap()
158148
params.putString("orientation", lastOrientation)
159149
if (reactContext.hasActiveReactInstance()) {
160-
reactContext
161-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
150+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
162151
.emit("orientationDidChange", params)
163152
}
164153

165154
val lockParams = Arguments.createMap()
166155
lockParams.putString("orientation", lastOrientation)
167156
if (reactContext.hasActiveReactInstance()) {
168-
reactContext
169-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
157+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
170158
.emit("lockDidChange", lockParams)
171159
}
172160
}
@@ -182,17 +170,15 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
182170
val params = Arguments.createMap()
183171
params.putString("orientation", lastOrientation)
184172
if (reactContext.hasActiveReactInstance()) {
185-
reactContext
186-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
173+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
187174
.emit("orientationDidChange", params)
188175
}
189176

190177
// send a locked event
191178
val lockParams = Arguments.createMap()
192179
lockParams.putString("orientation", lastOrientation)
193180
if (reactContext.hasActiveReactInstance()) {
194-
reactContext
195-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
181+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
196182
.emit("lockDidChange", lockParams)
197183
}
198184
}
@@ -208,16 +194,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
208194
val params = Arguments.createMap()
209195
params.putString("orientation", lastOrientation)
210196
if (reactContext.hasActiveReactInstance()) {
211-
reactContext
212-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
197+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
213198
.emit("orientationDidChange", params)
214199
}
215200

216201
val lockParams = Arguments.createMap()
217202
lockParams.putString("orientation", lastOrientation)
218203
if (reactContext.hasActiveReactInstance()) {
219-
reactContext
220-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
204+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
221205
.emit("lockDidChange", lockParams)
222206
}
223207
}
@@ -232,16 +216,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
232216
val params = Arguments.createMap()
233217
params.putString("orientation", lastOrientation)
234218
if (reactContext.hasActiveReactInstance()) {
235-
reactContext
236-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
219+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
237220
.emit("orientationDidChange", params)
238221
}
239222

240223
val lockParams = Arguments.createMap()
241224
lockParams.putString("orientation", lastOrientation)
242225
if (reactContext.hasActiveReactInstance()) {
243-
reactContext
244-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
226+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
245227
.emit("lockDidChange", lockParams)
246228
}
247229
}
@@ -256,16 +238,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
256238
val params = Arguments.createMap()
257239
params.putString("orientation", lastOrientation)
258240
if (reactContext.hasActiveReactInstance()) {
259-
reactContext
260-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
241+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
261242
.emit("orientationDidChange", params)
262243
}
263244

264245
val lockParams = Arguments.createMap()
265246
lockParams.putString("orientation", "unknown")
266247
if (reactContext.hasActiveReactInstance()) {
267-
reactContext
268-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
248+
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
269249
.emit("lockDidChange", lockParams)
270250
}
271251
}
@@ -289,7 +269,11 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
289269

290270
override fun start() {
291271
mOrientationListener.enable()
292-
reactContext.registerReceiver(mReceiver, IntentFilter("onConfigurationChanged"))
272+
val intentFilter = IntentFilter("onConfigurationChanged").apply {
273+
// addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
274+
}
275+
276+
reactContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED)
293277
isConfigurationChangeReceiverRegistered = true
294278
}
295279

example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ PODS:
374374
- React-jsinspector (0.72.1)
375375
- React-logger (0.72.1):
376376
- glog
377-
- react-native-neo-orientation (1.1.0):
377+
- react-native-neo-orientation (2.1.0):
378378
- RCT-Folly (= 2021.07.22.00)
379379
- React-Core
380380
- React-NativeModulesApple (0.72.1):
@@ -692,7 +692,7 @@ SPEC CHECKSUMS:
692692
React-jsiexecutor: 184eae1ecdedc7a083194bd9ff809c93f08fd34c
693693
React-jsinspector: d0b5bfd1085599265f4212034321e829bdf83cc0
694694
React-logger: b8103c9b04e707b50cdd2b1aeb382483900cbb37
695-
react-native-neo-orientation: 670ff290ae71ff09ee110d7fa557e5ed8da27908
695+
react-native-neo-orientation: 5a340ffc64aac25e628cd57c2493abeb312d42b4
696696
React-NativeModulesApple: 4f31a812364443cee6ef768d256c594ad3b20f53
697697
React-perflogger: 3d501f34c8d4b10cb75f348e43591765788525ad
698698
React-RCTActionSheet: f5335572c979198c0c3daff67b07bd1ad8370c1d
@@ -716,4 +716,4 @@ SPEC CHECKSUMS:
716716

717717
PODFILE CHECKSUM: e9e8830d1e35a8818e2f4789d9844d2ad7037dbf
718718

719-
COCOAPODS: 1.15.2
719+
COCOAPODS: 1.16.2

src/hooks/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './useOrientationChange';
2+
export * from './useDeviceOrientationChange';
3+
export * from './useLockListener';
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useRef, useEffect, type MutableRefObject } from 'react';
2+
import Orientation, { type OrientationCallback } from '../orientation';
3+
4+
export const useDeviceOrientationChange = (
5+
callback: OrientationCallback
6+
): void => {
7+
const savedCallback: MutableRefObject<OrientationCallback | undefined> =
8+
useRef();
9+
10+
useEffect(() => {
11+
savedCallback.current = callback;
12+
}, [callback]);
13+
14+
useEffect(() => {
15+
const listener = (ori: string): void => {
16+
if (savedCallback.current) {
17+
savedCallback.current(ori);
18+
}
19+
};
20+
const initial = Orientation.getInitialOrientation();
21+
listener(initial);
22+
Orientation.addDeviceOrientationListener(listener);
23+
24+
return () => {
25+
Orientation.removeDeviceOrientationListener(listener);
26+
};
27+
}, []);
28+
};

0 commit comments

Comments
 (0)