Skip to content

Commit

Permalink
fix: dimensions using custom shadow node + refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
maciekstosio committed Oct 21, 2024
1 parent df7bcc1 commit 2bd05f4
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 93 deletions.
12 changes: 6 additions & 6 deletions Example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.32.0):
- RNScreens (4.0.0-beta.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1787,12 +1787,12 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
boost: 4cb898d0bf20404aab1850c656dcea009429d6c1
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
FBLazyVector: d08b51db67e61e1adaed7aefdb43b43f247ee46a
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
glog: 69ef571f3de08433d766d614c73a9838a06bf7eb
hermes-engine: b205fccb3c7b52031e5bdb458a40f85f806bb7e8
RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47
RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740
RCTDeprecation: 8c3d64b4ab77cf28adefa261e04fd205c2715607
RCTRequired: 70f9b55e176be07e234e2efe43b31de14d7cd5ba
RCTTypeSafety: 570d25d58d8795b1a146f5dee4965a05b6fdf8ac
Expand Down Expand Up @@ -1851,10 +1851,10 @@ SPEC CHECKSUMS:
ReactCommon: dcc6f8545034e6f3d82f9555b39a2c03c2ccd005
RNGestureHandler: 044a81d99e5ad7a67b4c23d9f8ea4c6c30fd4bca
RNReanimated: 7892f7ef3a5b9c941b3145aa3398effac3d7809d
RNScreens: ca47818a6197d1b14782f0aa3bb4157a512e96dd
RNScreens: 621d17b9b84520ea79865b7bb18b8a8bbc433bb9
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 1e170d028257c3ceb6e652dd62b2698dbc108a4b
Yoga: 132f64c229103548a5c95fe12e2ab492fbd5c793

PODFILE CHECKSUM: 7bffbf744a07be2a9e6cfb9359c3debcc9873875

Expand Down
14 changes: 7 additions & 7 deletions FabricExample/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1607,7 +1607,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.32.0):
- RNScreens (4.0.0-beta.0):
- DoubleConversion
- glog
- hermes-engine
Expand All @@ -1628,9 +1628,9 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNScreens/common (= 3.32.0)
- RNScreens/common (= 4.0.0-beta.0)
- Yoga
- RNScreens/common (3.32.0):
- RNScreens/common (4.0.0-beta.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1877,9 +1877,9 @@ SPEC CHECKSUMS:
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
FBLazyVector: d08b51db67e61e1adaed7aefdb43b43f247ee46a
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
glog: 69ef571f3de08433d766d614c73a9838a06bf7eb
hermes-engine: b205fccb3c7b52031e5bdb458a40f85f806bb7e8
RCT-Folly: 045d6ecaa59d826c5736dfba0b2f4083ff8d79df
RCT-Folly: 4464f4d875961fce86008d45f4ecf6cef6de0740
RCTDeprecation: 8c3d64b4ab77cf28adefa261e04fd205c2715607
RCTRequired: 70f9b55e176be07e234e2efe43b31de14d7cd5ba
RCTTypeSafety: 570d25d58d8795b1a146f5dee4965a05b6fdf8ac
Expand Down Expand Up @@ -1938,10 +1938,10 @@ SPEC CHECKSUMS:
ReactCommon: dcc6f8545034e6f3d82f9555b39a2c03c2ccd005
RNGestureHandler: f6a669a7d4ed470acebf8637d347eb52ae07d401
RNReanimated: bb5b1c59b5fc19a4e83c942cfe4ea49c5d959dd2
RNScreens: 83aa5357fbb09aa87130fbea02325b53b7260fd6
RNScreens: cecfc1861f155b68584a6aa7bd284ac5ca38eb3a
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 1e170d028257c3ceb6e652dd62b2698dbc108a4b
Yoga: 132f64c229103548a5c95fe12e2ab492fbd5c793

PODFILE CHECKSUM: c270e520a11547ef636f117b51709c3ed2b291f7

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.facebook.react.module.annotations.ReactModuleList
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.uimanager.ViewManager
import com.swmansion.rnscreens.fullwindowoverlay.FullWindowOverlayViewManager
import com.swmansion.rnscreens.utils.ScreenDummyLayoutHelper

@ReactModuleList(
Expand Down Expand Up @@ -39,7 +40,7 @@ class RNScreensPackage : TurboReactPackage() {
SearchBarManager(),
ScreenFooterManager(),
ScreenContentWrapperManager(),
FullWindowOverlayViewManager()
FullWindowOverlayViewManager(),
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.swmansion.rnscreens
package com.swmansion.rnscreens.fullwindowoverlay

import FullWindowOverlayRootViewGroup
import android.content.Context
import android.graphics.PixelFormat
import android.view.View
import android.view.ViewStructure
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.uimanager.PointerEvents
Expand All @@ -17,30 +17,36 @@ import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.view.ReactViewGroup
import com.swmansion.rnscreens.utils.WindowOverlayCompat

// TODO Podebugować ewenty - co gdzie trafia
class FullWindowOverlay(
context: ReactContext?,
) : ReactViewGroup(context),
ReactPointerEventsView {
ReactPointerEventsView,
LifecycleEventListener {
private var isCreated = false

private val mWindowManager: WindowManager =
context?.getSystemService(Context.WINDOW_SERVICE) as WindowManager

private var mainRootView: View? = null

private var hostView: FullWindowOverlayRootViewGroup = FullWindowOverlayRootViewGroup(context, this)

public var stateWrapper: StateWrapper?
var stateWrapper: StateWrapper?
get() = hostView.stateWrapper
public set(stateWrapper) {
set(stateWrapper) {
hostView.stateWrapper = stateWrapper
}

public var eventDispatcher: EventDispatcher?
var eventDispatcher: EventDispatcher?
get() = hostView.eventDispatcher
public set(eventDispatcher) {
set(eventDispatcher) {
hostView.eventDispatcher = eventDispatcher
}

fun updateState(width: Int, height: Int) {
hostView.updateState(width, height)
}

override fun getPointerEvents(): PointerEvents = PointerEvents.NONE

override fun onAttachedToWindow() {
Expand All @@ -58,15 +64,24 @@ class FullWindowOverlay(
}

init {
val params =
WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowOverlayCompat.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT,
)
mWindowManager.addView(hostView, params)
setupView()
context?.addLifecycleEventListener(this)
}

fun setupView() {
if (!isCreated) {
val params =
WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
// WindowManager.LayoutParams.LAST_APPLICATION_WINDOW,
WindowOverlayCompat.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT,
)
mWindowManager.addView(hostView, params)
isCreated = true
}
}

fun getCurrentRootView(): View? = mainRootView
Expand Down Expand Up @@ -109,12 +124,28 @@ class FullWindowOverlay(

public override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean = false


public fun onDropInstance() {
super.invalidate()
mWindowManager.removeView(hostView)
isCreated = false
}

public override fun dispatchProvideStructure(structure: ViewStructure) {
hostView.dispatchProvideStructure(structure)
}

override fun onHostResume() {
println("onHostResume")
setupView()
}

override fun onHostPause() {
println("onHostPause")
onDropInstance()
}

override fun onHostDestroy() {
onDropInstance()
println("onHostDestroy")
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package com.swmansion.rnscreens.fullwindowoverlay

import android.annotation.SuppressLint
import android.content.Context
import android.view.MotionEvent
Expand All @@ -13,7 +15,6 @@ import com.facebook.react.config.ReactFeatureFlags
import com.facebook.react.uimanager.JSPointerDispatcher
import com.facebook.react.uimanager.JSTouchDispatcher
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.PointerEvents
import com.facebook.react.uimanager.ReactPointerEventsView
import com.facebook.react.uimanager.RootView
import com.facebook.react.uimanager.StateWrapper
Expand All @@ -22,26 +23,8 @@ import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.modal.ReactModalHostView
import com.facebook.react.views.view.ReactViewGroup
import com.swmansion.rnscreens.BuildConfig
import com.swmansion.rnscreens.FullWindowOverlay
import kotlin.math.abs

/**
* DialogRootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all
* child information forwarded from [ReactModalHostView] and uses that to create children. It is
* also responsible for acting as a RootView and handling touch events. It does this the same way
* as ReactRootView.
*
* To get layout to work properly, we need to layout all the elements within the Modal as if they
* can fill the entire window. To do that, we need to explicitly set the styleWidth and
* styleHeight on the LayoutShadowNode to be the window size. This is done through the
* UIManagerModule, and will then cause the children to layout as if they can fill the window.
*/

// TODO: Zobaczyć post od hirbota
// TODO: Przesunięcie z offestem, popatrzyć do standardu webowego kim jest containing box dla dziecka z postiion absolute i czy tym rodzicem możę być inny absolute
// TODO: tool do inspectowania shadow node
// TODO: zobaczyć co robi facebook z width i height
class FullWindowOverlayRootViewGroup(
context: Context?,
private val parentViewGroup: FullWindowOverlay,
Expand All @@ -53,7 +36,7 @@ class FullWindowOverlayRootViewGroup(
private var hasAdjustedSize = false
private var viewWidth = 0
private var viewHeight = 0
private val jSTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
private val jsTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
internal var eventDispatcher: EventDispatcher? = null
private var jSPointerDispatcher: JSPointerDispatcher? = null

Expand All @@ -65,13 +48,9 @@ class FullWindowOverlayRootViewGroup(
jSPointerDispatcher = JSPointerDispatcher(parentViewGroup)
}
@SuppressLint("ResourceType")
id = 42 // TODO: Dodać ładny komentarz czemu - żeby wybrał się dobry UIManager Type, dać link do tego miejsca gdzie view.getId() < 0
// TODO: Test na paperze i ewentualnie używamy flagi: BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
id = 42
}

override fun getPointerEvents(): PointerEvents {
return PointerEvents.BOX_NONE
}
override fun onSizeChanged(
w: Int,
h: Int,
Expand Down Expand Up @@ -179,12 +158,11 @@ class FullWindowOverlayRootViewGroup(


eventDispatcher?.let { eventDispatcher ->
jSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
jSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
}

val returnValue = super.onInterceptTouchEvent(event)
return false
return super.onInterceptTouchEvent(event)
}

@SuppressLint("ClickableViewAccessibility")
Expand All @@ -197,14 +175,13 @@ class FullWindowOverlayRootViewGroup(


// eventDispatcher?.let { eventDispatcher ->
// jSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
// jsTouchDispatcher.handleTouchEvent(event, eventDispatcher)
// jSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
// }
//
// var result = super.onTouchEvent(event)

// In case when there is no children interested in handling touch event, we return true from
// the root view in order to receive subsequent events related to that gesture
return true
return super.onTouchEvent(event)
}

// TODO: Zapytaćw GH czy i jeśli tak to jak to robić
Expand All @@ -223,7 +200,7 @@ class FullWindowOverlayRootViewGroup(
ev: MotionEvent,
) {
eventDispatcher?.let { eventDispatcher ->
jSTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
jsTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
jSPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher)
}
}
Expand All @@ -232,7 +209,7 @@ class FullWindowOverlayRootViewGroup(
childView: View,
ev: MotionEvent,
) {
eventDispatcher?.let { jSTouchDispatcher.onChildEndedNativeGesture(ev, it) }
eventDispatcher?.let { jsTouchDispatcher.onChildEndedNativeGesture(ev, it) }
jSPointerDispatcher?.onChildEndedNativeGesture()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
package com.swmansion.rnscreens
package com.swmansion.rnscreens.fullwindowoverlay

import android.annotation.SuppressLint
import android.content.Context
import android.view.MotionEvent
import android.view.View
import androidx.annotation.UiThread
import com.facebook.react.bridge.GuardedRunnable
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.config.ReactFeatureFlags
import ModalHostHelper.getModalHostSize
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.JSPointerDispatcher
import com.facebook.react.uimanager.JSTouchDispatcher
import com.facebook.react.uimanager.LayoutShadowNode
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.ReactStylesDiffMap
import com.facebook.react.uimanager.RootView
import com.facebook.react.uimanager.StateWrapper
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.viewmanagers.RNSFullWindowOverlayManagerDelegate
import com.facebook.react.viewmanagers.RNSFullWindowOverlayManagerInterface
import com.facebook.react.views.modal.ModalHostShadowNode
import com.facebook.react.views.modal.ReactModalHostView
import com.facebook.react.views.view.ReactViewGroup
import kotlin.math.abs

@ReactModule(name = FullWindowOverlayViewManager.REACT_CLASS)
class FullWindowOverlayViewManager :
Expand Down Expand Up @@ -69,4 +50,18 @@ class FullWindowOverlayViewManager :
}
}

public override fun updateState(
view: FullWindowOverlay,
props: ReactStylesDiffMap,
stateWrapper: StateWrapper
): Any? {
view.stateWrapper = stateWrapper
val modalSize = getModalHostSize(view.context)
view.updateState(modalSize.x, modalSize.y)
return null
}

override fun invalidate() {
super.invalidate()
}
}
Loading

0 comments on commit 2bd05f4

Please sign in to comment.