Skip to content

Commit

Permalink
feat: 🎸 add listener, fix android window focus
Browse files Browse the repository at this point in the history
Mapping func like react-native-orientation-locker typescript, fix
android error window focus, update document readme
  • Loading branch information
tconns committed Nov 28, 2024
1 parent 18993f0 commit 9b19803
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 78 deletions.
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
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'
25 changes: 25 additions & 0 deletions src/hooks/useDeviceOrientationChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useRef, useEffect, MutableRefObject } from 'react'
import Orientation, { 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)
}
}, [])
}
23 changes: 23 additions & 0 deletions src/hooks/useLockListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useRef, useEffect, MutableRefObject } from 'react'
import Orientation, { OrientationCallback } from '../orientation'

export const useLockListener = (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)
}
}
Orientation.addLockListener(listener)

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

0 comments on commit 9b19803

Please sign in to comment.