Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🎸 add listener, fix android window focus #8

Merged
merged 4 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.14.0
18.19.1
75 changes: 74 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,63 @@ Add the following to your project's AppDelegate.mm:

@end
```

### Android

Implement onConfigurationChanged method (in MainActivity.kt)

```kotlin

import android.content.Intent
import android.content.res.Configuration

// ...


class MainActivity : ReactActivity() {
//...
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
val intent = Intent("onConfigurationChanged")
intent.putExtra("newConfig", newConfig)
this.sendBroadcast(intent)
}
}
```

Add following to MainApplication.kt

```kotlin

import com.neoorientation.NeoOrientationActivityLifecycle
import com.neoorientation.NeoOrientationPackage
//...

class MainApplication : Application(), ReactApplication {

override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
add(NeoOrientationPackage())
}
//...
}

override fun onCreate() {
//...
registerActivityLifecycleCallbacks(NeoOrientationActivityLifecycle.instance)
}
}
```
## Usage

```typescript
import { Button, StyleSheet, Text, View } from 'react-native';
import React from 'react';
import NeoOrientation from 'react-native-neo-orientation';
import NeoOrientation, { useDeviceOrientationChange, useOrientationChange } from 'react-native-neo-orientation';

const Home = () => {
const handleLockTolandscape = () => {
Expand All @@ -63,6 +114,15 @@ const Home = () => {
const handleUnlockAllOrientations = () => {
NeoOrientation.unlockAllOrientations();
};

useDeviceOrientationChange((o) => {
// Handle device orientation change
});

useOrientationChange((o) => {
// Handle orientation change
});

return (
<View style={styles.container}>
<Text style={styles.text}>Home</Text>
Expand Down Expand Up @@ -105,6 +165,16 @@ const styles = StyleSheet.create({
});
```

## Events

- `addOrientationListener(function(orientation))`
- `removeOrientationListener(function(orientation))`
- `addDeviceOrientationListener(function(deviceOrientation))`
- `removeDeviceOrientationListener(function(deviceOrientation))`
- `addLockListener(function(orientation))`
- `removeLockListener(function(orientation))`
- `removeAllListeners()`

## Functions

- `lockToLandscape`
Expand All @@ -114,6 +184,9 @@ const styles = StyleSheet.create({
- `lockToLandscapeLeft`
- `lockToAllOrientationButUpsideDown`
- `unlockAllOrientations`
- `getOrientation`
- `getDeviceOrientation`
- `isLocked`

## Contributing

Expand Down
80 changes: 32 additions & 48 deletions android/src/main/java/com/neoorientation/NeoOrientationModule.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.neoorientation

import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ActivityInfo
import android.hardware.SensorManager
import android.os.Build
import android.provider.Settings
import android.view.OrientationEventListener
import android.view.Surface
Expand All @@ -20,9 +20,8 @@ import com.facebook.react.bridge.ReactMethod
import com.facebook.react.common.ReactConstants
import com.facebook.react.modules.core.DeviceEventManagerModule

class NeoOrientationModule(reactContext: ReactApplicationContext) :
class NeoOrientationModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext), NeoOrientationListeners {
private val reactContext: ReactApplicationContext
private val mReceiver: BroadcastReceiver
private val mOrientationListener: OrientationEventListener
private var isLocking = false
Expand All @@ -31,7 +30,6 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
private var lastDeviceOrientation = ""

init {
this.reactContext = reactContext
mOrientationListener =
object : OrientationEventListener(reactContext, SensorManager.SENSOR_DELAY_UI) {
override fun onOrientationChanged(p0: Int) {
Expand All @@ -54,8 +52,7 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
if (reactContext.hasActiveReactInstance()) {
reactContext.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
)
.emit("deviceOrientationDidChange", params)
).emit("deviceOrientationDidChange", params)
}
}
val orientation: String = currentOrientation
Expand All @@ -64,14 +61,11 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", orientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
)
.emit("orientationDidChange", params)
reactContext.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
).emit("orientationDidChange", params)
}
}
return
}
}
if (mOrientationListener.canDetectOrientation()) {
Expand All @@ -86,11 +80,9 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", orientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
)
.emit("orientationDidChange", params)
reactContext.getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
).emit("orientationDidChange", params)
}
}
}
Expand All @@ -99,15 +91,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :

private val currentOrientation: String
get() {
val display =
(reactApplicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
when (display.rotation) {
Surface.ROTATION_0 -> return "portrait"
Surface.ROTATION_90 -> return "landscapeLeft"
Surface.ROTATION_180 -> return "portraitUpsideDown"
Surface.ROTATION_270 -> return "landscapeRight"
val display = (reactApplicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
return when (display.rotation) {
Surface.ROTATION_0 -> "portrait"
Surface.ROTATION_90 -> "landscapeLeft"
Surface.ROTATION_180 -> "portraitUpsideDown"
Surface.ROTATION_270 -> "landscapeRight"
else -> "unknown"
}
return "unknown"
}

override fun getName(): String {
Expand Down Expand Up @@ -141,8 +132,7 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val lockParams = Arguments.createMap()
lockParams.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -157,16 +147,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("orientationDidChange", params)
}

val lockParams = Arguments.createMap()
lockParams.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -182,17 +170,15 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("orientationDidChange", params)
}

// send a locked event
val lockParams = Arguments.createMap()
lockParams.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -208,16 +194,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("orientationDidChange", params)
}

val lockParams = Arguments.createMap()
lockParams.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -232,16 +216,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("orientationDidChange", params)
}

val lockParams = Arguments.createMap()
lockParams.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -256,16 +238,14 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :
val params = Arguments.createMap()
params.putString("orientation", lastOrientation)
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("orientationDidChange", params)
}

val lockParams = Arguments.createMap()
lockParams.putString("orientation", "unknown")
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("lockDidChange", lockParams)
}
}
Expand All @@ -289,7 +269,11 @@ class NeoOrientationModule(reactContext: ReactApplicationContext) :

override fun start() {
mOrientationListener.enable()
reactContext.registerReceiver(mReceiver, IntentFilter("onConfigurationChanged"))
val intentFilter = IntentFilter("onConfigurationChanged").apply {
// addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
}

reactContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED)
isConfigurationChangeReceiverRegistered = true
}

Expand Down
6 changes: 3 additions & 3 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ PODS:
- React-jsinspector (0.72.1)
- React-logger (0.72.1):
- glog
- react-native-neo-orientation (1.1.0):
- react-native-neo-orientation (2.1.0):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- React-NativeModulesApple (0.72.1):
Expand Down Expand Up @@ -692,7 +692,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 184eae1ecdedc7a083194bd9ff809c93f08fd34c
React-jsinspector: d0b5bfd1085599265f4212034321e829bdf83cc0
React-logger: b8103c9b04e707b50cdd2b1aeb382483900cbb37
react-native-neo-orientation: 670ff290ae71ff09ee110d7fa557e5ed8da27908
react-native-neo-orientation: 5a340ffc64aac25e628cd57c2493abeb312d42b4
React-NativeModulesApple: 4f31a812364443cee6ef768d256c594ad3b20f53
React-perflogger: 3d501f34c8d4b10cb75f348e43591765788525ad
React-RCTActionSheet: f5335572c979198c0c3daff67b07bd1ad8370c1d
Expand All @@ -716,4 +716,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: e9e8830d1e35a8818e2f4789d9844d2ad7037dbf

COCOAPODS: 1.15.2
COCOAPODS: 1.16.2
3 changes: 3 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './useOrientationChange';
export * from './useDeviceOrientationChange';
export * from './useLockListener';
28 changes: 28 additions & 0 deletions src/hooks/useDeviceOrientationChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useRef, useEffect, type MutableRefObject } from 'react';
import Orientation, { type OrientationCallback } from '../orientation';

export const useDeviceOrientationChange = (
callback: OrientationCallback
): void => {
const savedCallback: MutableRefObject<OrientationCallback | undefined> =
useRef();

useEffect(() => {
savedCallback.current = callback;
}, [callback]);

useEffect(() => {
const listener = (ori: string): void => {
if (savedCallback.current) {
savedCallback.current(ori);
}
};
const initial = Orientation.getInitialOrientation();
listener(initial);
Orientation.addDeviceOrientationListener(listener);

return () => {
Orientation.removeDeviceOrientationListener(listener);
};
}, []);
};
Loading