Skip to content

Commit

Permalink
RFC: FullWindowOverlay on android
Browse files Browse the repository at this point in the history
  • Loading branch information
mfazekas committed Oct 20, 2024
1 parent 791cb10 commit aff56dc
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.swmansion.rnscreens

import android.content.Context
import android.graphics.PixelFormat
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.RootView
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.views.view.ReactViewGroup


class FullWindowOverlayRootViewGroup(val reactContext: ThemedReactContext): ReactViewGroup(reactContext), RootView {
override fun onChildStartedNativeGesture(p0: View?, p1: MotionEvent?) {
TODO("Not yet implemented")
}

override fun onChildEndedNativeGesture(p0: View?, p1: MotionEvent?) {
TODO("Not yet implemented")
}

override fun handleException(t: Throwable) {
reactContext.reactApplicationContext.handleException(RuntimeException(t))
}

fun addToViewHierarchy() {
val windowManager = reactContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val windowParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN),
PixelFormat.TRANSLUCENT
)
windowManager.addView(this, windowParams)
}
}

class FullWindowOverlay(val reactContext: ThemedReactContext): ReactViewGroup(reactContext), RootView {

private val fullWindowOverlayRootViewGroup = FullWindowOverlayRootViewGroup(reactContext)

init {
fullWindowOverlayRootViewGroup.addToViewHierarchy()
}

override fun onChildStartedNativeGesture(p0: View?, p1: MotionEvent?) {
TODO("Not yet implemented")
}

override fun onChildEndedNativeGesture(p0: View?, p1: MotionEvent?) {
TODO("Not yet implemented")
}

override fun handleException(throwable: Throwable?) {
TODO("Not yet implemented")
// reactContext.handleException(throwable)
}

override fun addView(child: View?, index: Int) {
UiThreadUtil.assertOnUiThread()
fullWindowOverlayRootViewGroup.addView(child, index)
}

}

@ReactModule(name = FullWindowOverlayViewManager.REACT_CLASS)
class FullWindowOverlayViewManager: ViewGroupManager<FullWindowOverlay>() {
companion object {
const val REACT_CLASS = "RNSFullWindowOverlay"
}

override fun getName() = FullWindowOverlayViewManager.REACT_CLASS

override fun createViewInstance(reactContext: ThemedReactContext) = FullWindowOverlay(reactContext)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class RNScreensPackage : TurboReactPackage() {
SearchBarManager(),
ScreenFooterManager(),
ScreenContentWrapperManager(),
FullWindowOverlayViewManager()
)
}

Expand Down
30 changes: 30 additions & 0 deletions apps/src/tests/TestFullWindowOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import { View, Modal, Text } from "react-native";
import { FullWindowOverlay } from "react-native-screens";

export default function TestFullScreenOverlay() {
return (
<View style={{flex:1}}>
<View style={{position:'absolute', top:0,left:0,right:0,bottom:0}}>
<View style={{ flex: 1, borderColor: 'black', borderWidth: 1, borderRadius: 20, backgroundColor: 'lightcyan', position: 'absolute', top: 200, padding: 40, marginHorizontal: 20 }}>
<Text>RNView</Text>
</View>
</View>
<Modal visible={true} transparent>
<View style={{ flex: 1, borderColor: 'black', borderWidth: 1, borderRadius: 20, backgroundColor: 'gainsboro', position: 'absolute', top: 200, left: 100, padding: 40, marginHorizontal: 20 }}>
<Text>Modal</Text>
</View>
</Modal>
<FullWindowOverlay>
<View style={{ position: 'absolute', top: 160, padding: 20, marginHorizontal: 50, backgroundColor: 'wheat', borderRadius: 10, shadowOffset: { width: 4, height: 4}, shadowOpacity: 0.2, shadowRadius: 10}}>
<Text>FullWindowOverlay #1</Text>
</View>
</FullWindowOverlay>
<FullWindowOverlay>
<View style={{ position: 'absolute', top: 280, padding: 20, marginHorizontal: 50, backgroundColor: 'wheat', borderRadius: 10, shadowOffset: { width: 4, height: 4}, shadowOpacity: 0.2, shadowRadius: 10}}>
<Text>FullWindowOverlay #2</Text>
</View>
</FullWindowOverlay>
</View>
)
}
1 change: 1 addition & 0 deletions apps/src/tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,4 @@ export { default as TestActivityStateProgression } from './TestActivityStateProg
export { default as TestHeaderTitle } from './TestHeaderTitle';
export { default as TestModalNavigation } from './TestModalNavigation';
export { default as TestMemoryLeak } from './TestMemoryLeak';
export { default as TestFullWindowOverlay } from './TestFullWindowOverlay';
2 changes: 1 addition & 1 deletion guides/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ To begin with, let install all dependencies:

1. `yarn`
2. `yarn submodules`
3. `(cd react-navigation && yarn prepare)`
3. `(cd react-navigation && yarn build)`
4. `cd Example`
5. `yarn`
6. `yarn start` &ndash; make sure to start metro bundler before building the app in Android Studio
Expand Down
6 changes: 1 addition & 5 deletions src/components/FullWindowOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropsWithChildren, ReactNode } from 'react';
import { Platform, StyleProp, View, ViewStyle } from 'react-native';
import { StyleProp, ViewStyle } from 'react-native';

// Native components
import FullWindowOverlayNativeComponent from '../fabric/FullWindowOverlayNativeComponent';
Expand All @@ -10,10 +10,6 @@ const NativeFullWindowOverlay: React.ComponentType<
> = FullWindowOverlayNativeComponent as any;

Check warning on line 10 in src/components/FullWindowOverlay.tsx

View workflow job for this annotation

GitHub Actions / install-and-lint

Unexpected any. Specify a different type

function FullWindowOverlay(props: { children: ReactNode }) {
if (Platform.OS !== 'ios') {
console.warn('Using FullWindowOverlay is only valid on iOS devices.');
return <View {...props} />;
}
return (
<NativeFullWindowOverlay
style={{ position: 'absolute', width: '100%', height: '100%' }}>
Expand Down

0 comments on commit aff56dc

Please sign in to comment.