From 3f07b79a75fc0d6c2f275b9eac9240bbde40c847 Mon Sep 17 00:00:00 2001 From: Tomasz Sapeta Date: Thu, 22 Jun 2023 16:05:42 +0200 Subject: [PATCH] Update react-native-screens to 3.22.0 (#23022) --- .../react-native-screens/android/build.gradle | 30 ++- .../swmansion/rnscreens/CustomSearchView.kt | 4 + .../com/swmansion/rnscreens/ScreenStack.kt | 21 +- .../rnscreens/ScreenStackHeaderConfig.kt | 16 +- .../ScreenStackHeaderConfigViewManager.kt | 16 +- .../swmansion/rnscreens/ScreenViewManager.kt | 10 + .../swmansion/rnscreens/SearchBarManager.kt | 40 +++- .../com/swmansion/rnscreens/SearchBarView.kt | 51 ++-- .../rnscreens/events/HeaderAttachedEvent.kt | 24 ++ .../rnscreens/events/HeaderDetachedEvent.kt | 24 ++ .../rnscreens/events/SearchBarBlurEvent.kt | 24 ++ .../events/SearchBarChangeTextEvent.kt | 29 +++ .../rnscreens/events/SearchBarCloseEvent.kt | 24 ++ .../rnscreens/events/SearchBarFocusEvent.kt | 24 ++ .../rnscreens/events/SearchBarOpenEvent.kt | 24 ++ .../events/SearchBarSearchButtonPressEvent.kt | 26 +++ .../{ => base}/anim/rns_default_enter_in.xml | 0 .../{ => base}/anim/rns_default_enter_out.xml | 0 .../{ => base}/anim/rns_default_exit_in.xml | 0 .../{ => base}/anim/rns_default_exit_out.xml | 0 .../{ => base}/anim/rns_fade_from_bottom.xml | 0 .../main/res/{ => base}/anim/rns_fade_in.xml | 0 .../main/res/{ => base}/anim/rns_fade_out.xml | 0 .../{ => base}/anim/rns_fade_to_bottom.xml | 0 .../{ => base}/anim/rns_no_animation_20.xml | 0 .../{ => base}/anim/rns_no_animation_250.xml | 0 .../{ => base}/anim/rns_no_animation_350.xml | 0 .../anim/rns_no_animation_medium.xml | 0 .../anim/rns_slide_in_from_bottom.xml | 0 .../anim/rns_slide_in_from_left.xml | 0 .../anim/rns_slide_in_from_right.xml | 0 .../anim/rns_slide_out_to_bottom.xml | 0 .../{ => base}/anim/rns_slide_out_to_left.xml | 0 .../anim/rns_slide_out_to_right.xml | 0 .../rns_standard_accelerate_interpolator.xml | 6 + .../res/v33/anim-v33/rns_default_enter_in.xml | 38 +++ .../v33/anim-v33/rns_default_enter_out.xml | 38 +++ .../res/v33/anim-v33/rns_default_exit_in.xml | 38 +++ .../res/v33/anim-v33/rns_default_exit_out.xml | 38 +++ .../RNSScreenManagerDelegate.java | 15 ++ .../RNSScreenManagerInterface.java | 5 + ...creenStackHeaderConfigManagerDelegate.java | 3 + ...reenStackHeaderConfigManagerInterface.java | 1 + apps/bare-expo/ios/Podfile.lock | 4 +- apps/bare-expo/package.json | 2 +- apps/native-component-list/package.json | 2 +- home/package.json | 2 +- ios/Podfile.lock | 4 +- .../RNScreens.podspec.json | 4 +- ...ComponentView+RNSScreenStackHeaderConfig.h | 11 + ...omponentView+RNSScreenStackHeaderConfig.mm | 14 ++ .../react-native-screens/ios/RNSConvert.h | 10 +- .../react-native-screens/ios/RNSConvert.mm | 30 ++- .../react-native-screens/ios/RNSEnums.h | 6 + .../ios/RNSFullWindowOverlay.h | 10 +- .../ios/RNSFullWindowOverlay.mm | 26 +-- .../react-native-screens/ios/RNSScreen.h | 20 +- .../react-native-screens/ios/RNSScreen.mm | 157 ++++++++++--- .../ios/RNSScreenContainer.h | 4 +- .../ios/RNSScreenContainer.mm | 10 +- .../ios/RNSScreenNavigationContainer.mm | 6 +- .../react-native-screens/ios/RNSScreenStack.h | 8 +- .../ios/RNSScreenStack.mm | 85 +++++-- .../ios/RNSScreenStackHeaderConfig.h | 13 +- .../ios/RNSScreenStackHeaderConfig.mm | 219 +++++++++++------- .../ios/RNSScreenStackHeaderSubview.h | 11 +- .../ios/RNSScreenStackHeaderSubview.mm | 31 ++- .../ios/RNSScreenWindowTraits.mm | 29 ++- .../react-native-screens/ios/RNSSearchBar.h | 9 +- .../react-native-screens/ios/RNSSearchBar.mm | 99 +++++++- packages/expo-stories/package.json | 2 +- packages/expo/bundledNativeModules.json | 2 +- yarn.lock | 8 +- 73 files changed, 1127 insertions(+), 280 deletions(-) create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_default_enter_in.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_default_enter_out.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_default_exit_in.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_default_exit_out.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_fade_from_bottom.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_fade_in.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_fade_out.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_fade_to_bottom.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_no_animation_20.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_no_animation_250.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_no_animation_350.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_no_animation_medium.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_in_from_bottom.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_in_from_left.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_in_from_right.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_out_to_bottom.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_out_to_left.xml (100%) rename android/vendored/unversioned/react-native-screens/android/src/main/res/{ => base}/anim/rns_slide_out_to_right.xml (100%) create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml create mode 100644 android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml create mode 100644 ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h create mode 100644 ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm diff --git a/android/vendored/unversioned/react-native-screens/android/build.gradle b/android/vendored/unversioned/react-native-screens/android/build.gradle index 482478b9f05ea7..056a698ede477d 100644 --- a/android/vendored/unversioned/react-native-screens/android/build.gradle +++ b/android/vendored/unversioned/react-native-screens/android/build.gradle @@ -1,4 +1,10 @@ buildscript { + ext { + rnsDefaultTargetSdkVersion = 31 + rnsDefaultCompileSdkVersion = 31 + rnsDefaultMinSdkVersion = 21 + rnsDefaultKotlinVersion = '1.6.21' + } ext.safeExtGet = {prop, fallback -> rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback } @@ -8,7 +14,7 @@ buildscript { } dependencies { classpath('com.android.tools.build:gradle:4.2.2') - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '1.6.21')}" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', rnsDefaultKotlinVersion)}" classpath "com.diffplug.spotless:spotless-plugin-gradle:5.15.0" } } @@ -38,7 +44,11 @@ def reactNativeArchitectures() { } android { - compileSdkVersion safeExtGet('compileSdkVersion', 28) + compileSdkVersion safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) + def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION + if (agpVersion.tokenize('.')[0].toInteger() >= 7) { + namespace "com.swmansion.rnscreens" + } // Used to override the NDK path/version on internal CI or by allowing // users to customize the NDK path/version from their root project (e.g. for M1 support) @@ -50,8 +60,8 @@ android { } defaultConfig { - minSdkVersion safeExtGet('minSdkVersion', 21) - targetSdkVersion safeExtGet('targetSdkVersion', 22) + minSdkVersion safeExtGet('minSdkVersion', rnsDefaultMinSdkVersion) + targetSdkVersion safeExtGet('targetSdkVersion', rnsDefaultTargetSdkVersion) versionCode 1 versionName "1.0" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() @@ -68,12 +78,13 @@ android { } packagingOptions { // For some reason gradle only complains about the duplicated version of libreact_render libraries - // while there are more libraries copied in intermediates folder of the lib build directory, we exlude + // while there are more libraries copied in intermediates folder of the lib build directory, we exclude // only the ones that make the build fail (ideally we should only include librnscreens_modules but we - // are only allowed to specify exlude patterns) + // are only allowed to specify exclude patterns) exclude "**/libreact_render*.so" } sourceSets.main { + ext.androidResDir = "src/main/res" java { if (isNewArchitectureEnabled()) { srcDirs += [ @@ -87,6 +98,13 @@ android { } } + res { + if (safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) >= 33) { + srcDirs = ["${androidResDir}/base", "${androidResDir}/v33"] + } else { + srcDirs = ["${androidResDir}/base"] + } + } } } diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt index b6961844b51b3a..6984b10d483e8a 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt @@ -36,6 +36,10 @@ class CustomSearchView(context: Context, fragment: Fragment) : SearchView(contex requestFocusFromTouch() } + fun clearText() = setQuery("", false) + + fun setText(text: String) = setQuery(text, false) + override fun setOnCloseListener(listener: OnCloseListener?) { mCustomOnCloseListener = listener } diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt index 34aed7959dc622..4d2c16f1c712c2 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt @@ -292,29 +292,30 @@ class ScreenStack(context: Context?) : ScreenContainer(cont } override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean { - drawingOps.add(obtainDrawingOp().set(canvas, child, drawingTime)) + drawingOps.add( + obtainDrawingOp().apply { + this.canvas = canvas + this.child = child + this.drawingTime = drawingTime + } + ) return true } private fun performDraw(op: DrawingOp) { - super.drawChild(op.canvas, op.child, op.drawingTime) + // Canvas parameter can not be null here https://developer.android.com/reference/android/view/ViewGroup#drawChild(android.graphics.Canvas,%20android.view.View,%20long) + // So if we are passing null here, we would crash anyway + super.drawChild(op.canvas!!, op.child, op.drawingTime) } private fun obtainDrawingOp(): DrawingOp = - if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeAt(drawingOpPool.size - 1) + if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeLast() private inner class DrawingOp { var canvas: Canvas? = null var child: View? = null var drawingTime: Long = 0 - operator fun set(canvas: Canvas?, child: View?, drawingTime: Long): DrawingOp { - this.canvas = canvas - this.child = child - this.drawingTime = drawingTime - return this - } - fun draw() { performDraw(this) canvas = null diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt index aa4c27c0c4dca4..477d50ed20e1eb 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt @@ -16,9 +16,10 @@ import androidx.fragment.app.Fragment import com.facebook.react.ReactApplication import com.facebook.react.bridge.JSApplicationIllegalArgumentException import com.facebook.react.bridge.ReactContext -import com.facebook.react.bridge.WritableMap -import com.facebook.react.uimanager.events.RCTEventEmitter +import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.views.text.ReactTypefaceUtils +import com.swmansion.rnscreens.events.HeaderAttachedEvent +import com.swmansion.rnscreens.events.HeaderDetachedEvent class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) { private val mConfigSubviews = ArrayList(3) @@ -64,11 +65,6 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) { } } - private fun sendEvent(eventName: String, eventContent: WritableMap?) { - (context as ReactContext).getJSModule(RCTEventEmitter::class.java) - ?.receiveEvent(id, eventName, eventContent) - } - override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { // no-op } @@ -80,7 +76,8 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) { override fun onAttachedToWindow() { super.onAttachedToWindow() mIsAttachedToWindow = true - sendEvent("onAttached", null) + UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id) + ?.dispatchEvent(HeaderAttachedEvent(id)) // we want to save the top inset before the status bar can be hidden, which would resolve in // inset being 0 if (headerTopInset == null) { @@ -96,7 +93,8 @@ class ScreenStackHeaderConfig(context: Context) : ViewGroup(context) { override fun onDetachedFromWindow() { super.onDetachedFromWindow() mIsAttachedToWindow = false - sendEvent("onDetached", null) + UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id) + ?.dispatchEvent(HeaderDetachedEvent(id)) } private val screen: Screen? diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt index f17630319fb0b3..15c63edcff29c7 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt @@ -11,6 +11,8 @@ import com.facebook.react.uimanager.ViewManagerDelegate import com.facebook.react.uimanager.annotations.ReactProp import com.facebook.react.viewmanagers.RNSScreenStackHeaderConfigManagerDelegate import com.facebook.react.viewmanagers.RNSScreenStackHeaderConfigManagerInterface +import com.swmansion.rnscreens.events.HeaderAttachedEvent +import com.swmansion.rnscreens.events.HeaderDetachedEvent import javax.annotation.Nonnull @ReactModule(name = ScreenStackHeaderConfigViewManager.REACT_CLASS) @@ -133,10 +135,12 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager? { - return MapBuilder.builder() - .put("onAttached", MapBuilder.of("registrationName", "onAttached")) - .put("onDetached", MapBuilder.of("registrationName", "onDetached")) - .build() + return MapBuilder.of( + HeaderAttachedEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onAttached"), + HeaderDetachedEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onDetached"), + ) } protected override fun getDelegate(): ViewManagerDelegate = mDelegate @@ -162,6 +166,10 @@ class ScreenStackHeaderConfigViewManager : ViewGroupManager(), RNSScreenManagerInterface< override fun setSwipeDirection(view: Screen?, value: String?) = Unit + override fun setSheetAllowedDetents(view: Screen, value: String?) = Unit + + override fun setSheetLargestUndimmedDetent(view: Screen, value: String?) = Unit + + override fun setSheetGrabberVisible(view: Screen?, value: Boolean) = Unit + + override fun setSheetCornerRadius(view: Screen?, value: Float) = Unit + + override fun setSheetExpandsWhenScrolledToEdge(view: Screen?, value: Boolean) = Unit + override fun getExportedCustomDirectEventTypeConstants(): MutableMap { return MapBuilder.of( ScreenDismissedEvent.EVENT_NAME, diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt index 79ef4991a6d4d9..f0e37f86fa278e 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt @@ -1,11 +1,18 @@ package com.swmansion.rnscreens import com.facebook.react.bridge.JSApplicationIllegalArgumentException +import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.MapBuilder import com.facebook.react.module.annotations.ReactModule import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.ViewGroupManager import com.facebook.react.uimanager.annotations.ReactProp +import com.swmansion.rnscreens.events.SearchBarBlurEvent +import com.swmansion.rnscreens.events.SearchBarChangeTextEvent +import com.swmansion.rnscreens.events.SearchBarCloseEvent +import com.swmansion.rnscreens.events.SearchBarFocusEvent +import com.swmansion.rnscreens.events.SearchBarOpenEvent +import com.swmansion.rnscreens.events.SearchBarSearchButtonPressEvent @ReactModule(name = SearchBarManager.REACT_CLASS) class SearchBarManager : ViewGroupManager() { @@ -90,15 +97,32 @@ class SearchBarManager : ViewGroupManager() { view.shouldShowHintSearchIcon = shouldShowHintSearchIcon ?: true } + override fun receiveCommand(root: SearchBarView, commandId: String?, args: ReadableArray?) { + when (commandId) { + "focus" -> root.handleFocusJsRequest() + "blur" -> root.handleBlurJsRequest() + "clearText" -> root.handleClearTextJsRequest() + "toggleCancelButton" -> root.handleToggleCancelButtonJsRequest(false) // just a dummy argument + "setText" -> root.handleSetTextJsRequest(args?.getString(0)) + else -> throw JSApplicationIllegalArgumentException("Unsupported native command received: $commandId") + } + } + override fun getExportedCustomDirectEventTypeConstants(): Map? { - return MapBuilder.builder() - .put("onChangeText", MapBuilder.of("registrationName", "onChangeText")) - .put("onSearchButtonPress", MapBuilder.of("registrationName", "onSearchButtonPress")) - .put("onFocus", MapBuilder.of("registrationName", "onFocus")) - .put("onBlur", MapBuilder.of("registrationName", "onBlur")) - .put("onClose", MapBuilder.of("registrationName", "onClose")) - .put("onOpen", MapBuilder.of("registrationName", "onOpen")) - .build() + return MapBuilder.of( + SearchBarBlurEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onBlur"), + SearchBarChangeTextEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onChangeText"), + SearchBarCloseEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onClose"), + SearchBarFocusEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onFocus"), + SearchBarOpenEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onOpen"), + SearchBarSearchButtonPressEvent.EVENT_NAME, + MapBuilder.of("registrationName", "onSearchButtonPress"), + ) } companion object { diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt index 46b8fd45eaf077..e91bbb4a9bac75 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt @@ -3,11 +3,17 @@ package com.swmansion.rnscreens import android.annotation.SuppressLint import android.text.InputType import androidx.appcompat.widget.SearchView -import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactContext -import com.facebook.react.bridge.WritableMap -import com.facebook.react.uimanager.events.RCTEventEmitter +import com.facebook.react.uimanager.UIManagerHelper +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.EventDispatcher import com.facebook.react.views.view.ReactViewGroup +import com.swmansion.rnscreens.events.SearchBarBlurEvent +import com.swmansion.rnscreens.events.SearchBarChangeTextEvent +import com.swmansion.rnscreens.events.SearchBarCloseEvent +import com.swmansion.rnscreens.events.SearchBarFocusEvent +import com.swmansion.rnscreens.events.SearchBarOpenEvent +import com.swmansion.rnscreens.events.SearchBarSearchButtonPressEvent @SuppressLint("ViewConstructor") class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext) { @@ -95,32 +101,47 @@ class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext) } private fun handleTextChange(newText: String?) { - val event = Arguments.createMap() - event.putString("text", newText) - sendEvent("onChangeText", event) + sendEvent(SearchBarChangeTextEvent(id, newText)) } private fun handleFocusChange(hasFocus: Boolean) { - sendEvent(if (hasFocus) "onFocus" else "onBlur", null) + sendEvent(if (hasFocus) SearchBarFocusEvent(id) else SearchBarBlurEvent(id)) } private fun handleClose() { - sendEvent("onClose", null) + sendEvent(SearchBarCloseEvent(id)) } private fun handleOpen() { - sendEvent("onOpen", null) + sendEvent(SearchBarOpenEvent(id)) } private fun handleTextSubmit(newText: String?) { - val event = Arguments.createMap() - event.putString("text", newText) - sendEvent("onSearchButtonPress", event) + sendEvent(SearchBarSearchButtonPressEvent(id, newText)) } - private fun sendEvent(eventName: String, eventContent: WritableMap?) { - (context as ReactContext).getJSModule(RCTEventEmitter::class.java) - ?.receiveEvent(id, eventName, eventContent) + private fun sendEvent(event: Event<*>) { + val eventDispatcher: EventDispatcher? = + UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id) + eventDispatcher?.dispatchEvent(event) + } + + fun handleClearTextJsRequest() { + screenStackFragment?.searchView?.clearText() + } + + fun handleFocusJsRequest() { + screenStackFragment?.searchView?.focus() + } + + fun handleBlurJsRequest() { + screenStackFragment?.searchView?.clearFocus() + } + + fun handleToggleCancelButtonJsRequest(flag: Boolean) = Unit + + fun handleSetTextJsRequest(text: String?) { + text?.let { screenStackFragment?.searchView?.setText(it) } } enum class SearchBarAutoCapitalize { diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt new file mode 100644 index 00000000000000..62f82bbb17e211 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class HeaderAttachedEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topAttached" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt new file mode 100644 index 00000000000000..85b507d3536354 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class HeaderDetachedEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topDetached" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt new file mode 100644 index 00000000000000..36cb28adc3ec04 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarBlurEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topBlur" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt new file mode 100644 index 00000000000000..0a1acff91d1acb --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt @@ -0,0 +1,29 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarChangeTextEvent( + viewId: Int, + private val text: String?, +) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + val map = Arguments.createMap() + map.putString("text", text) + rctEventEmitter.receiveEvent(viewTag, eventName, map) + } + + companion object { + const val EVENT_NAME = "topChangeText" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt new file mode 100644 index 00000000000000..bd12bc40ee6b9c --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarCloseEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topClose" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt new file mode 100644 index 00000000000000..eb95858fb23adb --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarFocusEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topFocus" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt new file mode 100644 index 00000000000000..a59e932e472114 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt @@ -0,0 +1,24 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarOpenEvent(viewId: Int) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + rctEventEmitter.receiveEvent(viewTag, eventName, Arguments.createMap()) + } + + companion object { + const val EVENT_NAME = "topOpen" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt new file mode 100644 index 00000000000000..1b336198f25b36 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt @@ -0,0 +1,26 @@ +package com.swmansion.rnscreens.events + +import com.facebook.react.bridge.Arguments +import com.facebook.react.uimanager.events.Event +import com.facebook.react.uimanager.events.RCTEventEmitter + +class SearchBarSearchButtonPressEvent(viewId: Int, private val text: String?) : Event(viewId) { + override fun getEventName(): String { + return EVENT_NAME + } + + override fun getCoalescingKey(): Short { + // All events for a given view can be coalesced. + return 0 + } + + override fun dispatch(rctEventEmitter: RCTEventEmitter) { + val map = Arguments.createMap() + map.putString("text", text) + rctEventEmitter.receiveEvent(viewTag, eventName, map) + } + + companion object { + const val EVENT_NAME = "topSearchButtonPress" + } +} diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_enter_in.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_enter_in.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_enter_in.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_enter_in.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_enter_out.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_enter_out.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_enter_out.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_enter_out.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_exit_in.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_exit_in.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_exit_in.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_exit_in.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_exit_out.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_exit_out.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_default_exit_out.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_default_exit_out.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_from_bottom.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_from_bottom.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_from_bottom.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_from_bottom.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_in.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_in.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_in.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_in.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_out.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_out.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_out.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_out.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_to_bottom.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_to_bottom.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_fade_to_bottom.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_fade_to_bottom.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_20.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_20.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_20.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_20.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_250.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_250.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_250.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_250.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_350.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_350.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_350.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_350.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_medium.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_medium.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_no_animation_medium.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_no_animation_medium.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_bottom.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_bottom.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_left.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_left.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_left.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_left.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_right.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_right.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_in_from_right.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_in_from_right.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_bottom.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_bottom.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_left.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_left.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_left.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_left.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_right.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_right.xml similarity index 100% rename from android/vendored/unversioned/react-native-screens/android/src/main/res/anim/rns_slide_out_to_right.xml rename to android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_slide_out_to_right.xml diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml new file mode 100644 index 00000000000000..60c57e59d6b2ec --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml @@ -0,0 +1,6 @@ + + diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml new file mode 100644 index 00000000000000..654c80bfbe663c --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml new file mode 100644 index 00000000000000..965d47f6c339a7 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml new file mode 100644 index 00000000000000..949ebb776d7c15 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml new file mode 100644 index 00000000000000..ba4d84d6cdfda8 --- /dev/null +++ b/android/vendored/unversioned/react-native-screens/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java index 4bf39f46049c7c..b2bda826306e2c 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +++ b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java @@ -23,6 +23,21 @@ public RNSScreenManagerDelegate(U viewManager) { @Override public void setProperty(T view, String propName, @Nullable Object value) { switch (propName) { + case "sheetAllowedDetents": + mViewManager.setSheetAllowedDetents(view, (String) value); + break; + case "sheetLargestUndimmedDetent": + mViewManager.setSheetLargestUndimmedDetent(view, (String) value); + break; + case "sheetGrabberVisible": + mViewManager.setSheetGrabberVisible(view, value == null ? false : (boolean) value); + break; + case "sheetCornerRadius": + mViewManager.setSheetCornerRadius(view, value == null ? -1f : ((Double) value).floatValue()); + break; + case "sheetExpandsWhenScrolledToEdge": + mViewManager.setSheetExpandsWhenScrolledToEdge(view, value == null ? false : (boolean) value); + break; case "customAnimationOnSwipe": mViewManager.setCustomAnimationOnSwipe(view, value == null ? false : (boolean) value); break; diff --git a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java index c1f80f08c7e1c6..49630c83673a5c 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +++ b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java @@ -14,6 +14,11 @@ import com.facebook.react.bridge.ReadableMap; public interface RNSScreenManagerInterface { + void setSheetAllowedDetents(T view, @Nullable String value); + void setSheetLargestUndimmedDetent(T view, @Nullable String value); + void setSheetGrabberVisible(T view, boolean value); + void setSheetCornerRadius(T view, float value); + void setSheetExpandsWhenScrolledToEdge(T view, boolean value); void setCustomAnimationOnSwipe(T view, boolean value); void setFullScreenSwipeEnabled(T view, boolean value); void setHomeIndicatorHidden(T view, boolean value); diff --git a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java index e02d6882d3d3d2..5f43ae1f0df446 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +++ b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java @@ -34,6 +34,9 @@ public void setProperty(T view, String propName, @Nullable Object value) { case "backTitleFontSize": mViewManager.setBackTitleFontSize(view, value == null ? 0 : ((Double) value).intValue()); break; + case "backTitleVisible": + mViewManager.setBackTitleVisible(view, value == null ? true : (boolean) value); + break; case "color": mViewManager.setColor(view, ColorPropConverter.getColor(value, view.getContext())); break; diff --git a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java index 2d31a4010812b1..21a79a0f90d6a1 100644 --- a/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +++ b/android/vendored/unversioned/react-native-screens/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java @@ -17,6 +17,7 @@ public interface RNSScreenStackHeaderConfigManagerInterface { void setBackTitle(T view, @Nullable String value); void setBackTitleFontFamily(T view, @Nullable String value); void setBackTitleFontSize(T view, int value); + void setBackTitleVisible(T view, boolean value); void setColor(T view, @Nullable Integer value); void setDirection(T view, @Nullable String value); void setHidden(T view, boolean value); diff --git a/apps/bare-expo/ios/Podfile.lock b/apps/bare-expo/ios/Podfile.lock index e819e39f04b5ce..f031996dc6d3e7 100644 --- a/apps/bare-expo/ios/Podfile.lock +++ b/apps/bare-expo/ios/Podfile.lock @@ -841,7 +841,7 @@ PODS: - React-RCTText - ReactCommon/turbomodule/core - Yoga - - RNScreens (3.20.0): + - RNScreens (3.22.0): - React-Core - React-RCTImage - RNSharedElement (0.8.8): @@ -1508,7 +1508,7 @@ SPEC CHECKSUMS: RNFlashList: ade81b4e928ebd585dd492014d40fb8d0e848aab RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5 RNReanimated: 11ef210bd11e80668ed3708f7a9dd846ae29e99c - RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f + RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789 RNSharedElement: 504fa28a235b12505b6daedbb452a9ec96809bd0 RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 SDWebImage: cb032eba469c54e0000e78bcb0a13cdde0a52798 diff --git a/apps/bare-expo/package.json b/apps/bare-expo/package.json index daf5258e4d5fba..4d5ce2263aebc8 100644 --- a/apps/bare-expo/package.json +++ b/apps/bare-expo/package.json @@ -85,7 +85,7 @@ "react-native-pager-view": "6.2.0", "react-native-reanimated": "~3.3.0", "react-native-safe-area-context": "4.6.3", - "react-native-screens": "~3.20.0", + "react-native-screens": "~3.22.0", "react-native-shared-element": "0.8.8", "react-native-svg": "13.9.0", "react-native-view-shot": "3.6.0", diff --git a/apps/native-component-list/package.json b/apps/native-component-list/package.json index 804214b27e9c1f..21f7f3746bb48c 100644 --- a/apps/native-component-list/package.json +++ b/apps/native-component-list/package.json @@ -149,7 +149,7 @@ "react-native-paper": "^4.0.1", "react-native-reanimated": "~3.3.0", "react-native-safe-area-context": "4.6.3", - "react-native-screens": "~3.20.0", + "react-native-screens": "~3.22.0", "react-native-shared-element": "0.8.8", "react-native-svg": "13.9.0", "react-native-view-shot": "3.6.0", diff --git a/home/package.json b/home/package.json index 7054d598c7ece0..9190ccc5191b9f 100644 --- a/home/package.json +++ b/home/package.json @@ -65,7 +65,7 @@ "react-native-paper": "^4.0.1", "react-native-reanimated": "~3.3.0", "react-native-safe-area-context": "4.6.3", - "react-native-screens": "~3.20.0", + "react-native-screens": "~3.22.0", "react-redux": "^7.2.0", "react-string-replace": "^0.4.4", "redux": "^4.0.5", diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0d9bb7a25d83b2..484ad29fa7f91b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2249,7 +2249,7 @@ PODS: - React-RCTText - ReactCommon/turbomodule/core - Yoga - - RNScreens (3.20.0): + - RNScreens (3.22.0): - React-Core - React-RCTImage - RNSVG (13.9.0): @@ -3787,7 +3787,7 @@ SPEC CHECKSUMS: RNFlashList: ade81b4e928ebd585dd492014d40fb8d0e848aab RNGestureHandler: dec4645026e7401a0899f2846d864403478ff6a5 RNReanimated: c540188fb085b7bf60678f5f5ca3ced906faaab7 - RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f + RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789 RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315 SDWebImage: cb032eba469c54e0000e78bcb0a13cdde0a52798 SDWebImageAVIFCoder: 4aeea8fdf65af5c18525ecb5bdd8b8ed9bb45019 diff --git a/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json b/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json index c3265235ef9e2f..8948d49b0f49c2 100644 --- a/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json +++ b/ios/vendored/unversioned/react-native-screens/RNScreens.podspec.json @@ -1,6 +1,6 @@ { "name": "RNScreens", - "version": "3.20.0", + "version": "3.22.0", "summary": "Native navigation primitives for your React Native app.", "description": "RNScreens - first incomplete navigation solution for your React Native app", "homepage": "https://github.com/software-mansion/react-native-screens", @@ -14,7 +14,7 @@ }, "source": { "git": "https://github.com/software-mansion/react-native-screens.git", - "tag": "3.20.0" + "tag": "3.22.0" }, "source_files": "ios/**/*.{h,m,mm}", "requires_arc": true, diff --git a/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h b/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h new file mode 100644 index 00000000000000..ca75f921ef6bc5 --- /dev/null +++ b/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h @@ -0,0 +1,11 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#include + +@interface RCTImageComponentView (RNSScreenStackHeaderConfig) + +- (UIImage *)image; + +@end + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm b/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm new file mode 100644 index 00000000000000..601095f88b6013 --- /dev/null +++ b/ios/vendored/unversioned/react-native-screens/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm @@ -0,0 +1,14 @@ +#ifdef RCT_NEW_ARCH_ENABLED + +#include "RCTImageComponentView+RNSScreenStackHeaderConfig.h" + +@implementation RCTImageComponentView (RNSScreenStackHeaderConfig) + +- (UIImage *)image +{ + return _imageView.image; +} + +@end + +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.h b/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.h index 228c53eb36cd2e..e7cf1ff983c978 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.h @@ -1,4 +1,4 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import "RNSEnums.h" @@ -19,6 +19,12 @@ + (RNSScreenSwipeDirection)RNSScreenSwipeDirectionFromCppEquivalent: (facebook::react::RNSScreenSwipeDirection)swipeDirection; ++ (RNSScreenDetentType)RNSScreenDetentTypeFromAllowedDetents: + (facebook::react::RNSScreenSheetAllowedDetents)allowedDetents; + ++ (RNSScreenDetentType)RNSScreenDetentTypeFromLargestUndimmedDetent: + (facebook::react::RNSScreenSheetLargestUndimmedDetent)detent; + + (NSDictionary *)gestureResponseDistanceDictFromCppStruct: (const facebook::react::RNSScreenGestureResponseDistanceStruct &)gestureResponseDistance; @@ -27,4 +33,4 @@ @end -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.mm index 79ed0c3a1b5ed9..d4aeb8327e2ee8 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSConvert.mm @@ -1,6 +1,6 @@ #import "RNSConvert.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED @implementation RNSConvert + (RNSScreenStackPresentation)RNSScreenStackPresentationFromCppEquivalent: @@ -89,6 +89,32 @@ + (RNSScreenSwipeDirection)RNSScreenSwipeDirectionFromCppEquivalent: } } ++ (RNSScreenDetentType)RNSScreenDetentTypeFromAllowedDetents: + (facebook::react::RNSScreenSheetAllowedDetents)allowedDetents +{ + switch (allowedDetents) { + case facebook::react::RNSScreenSheetAllowedDetents::All: + return RNSScreenDetentTypeAll; + case facebook::react::RNSScreenSheetAllowedDetents::Large: + return RNSScreenDetentTypeLarge; + case facebook::react::RNSScreenSheetAllowedDetents::Medium: + return RNSScreenDetentTypeMedium; + } +} + ++ (RNSScreenDetentType)RNSScreenDetentTypeFromLargestUndimmedDetent: + (facebook::react::RNSScreenSheetLargestUndimmedDetent)detent +{ + switch (detent) { + case facebook::react::RNSScreenSheetLargestUndimmedDetent::All: + return RNSScreenDetentTypeAll; + case facebook::react::RNSScreenSheetLargestUndimmedDetent::Large: + return RNSScreenDetentTypeLarge; + case facebook::react::RNSScreenSheetLargestUndimmedDetent::Medium: + return RNSScreenDetentTypeMedium; + } +} + + (NSDictionary *)gestureResponseDistanceDictFromCppStruct: (const facebook::react::RNSScreenGestureResponseDistanceStruct &)gestureResponseDistance { @@ -117,4 +143,4 @@ + (UITextAutocapitalizationType)UITextAutocapitalizationTypeFromCppEquivalent: @end -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSEnums.h b/ios/vendored/unversioned/react-native-screens/ios/RNSEnums.h index 84158c6004d929..de886edf1043e9 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSEnums.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSEnums.h @@ -57,3 +57,9 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { RNSScreenStackHeaderSubviewTypeCenter, RNSScreenStackHeaderSubviewTypeSearchBar, }; + +typedef NS_ENUM(NSInteger, RNSScreenDetentType) { + RNSScreenDetentTypeMedium, + RNSScreenDetentTypeLarge, + RNSScreenDetentTypeAll, +}; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.h b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.h index ce77c9eb9b51fe..3f756643a2c84f 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.h @@ -1,6 +1,6 @@ #import -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #else #import @@ -16,15 +16,15 @@ @end @interface RNSFullWindowOverlay : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else RCTView -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED @property (nonatomic) facebook::react::LayoutMetrics oldLayoutMetrics; @property (nonatomic) facebook::react::LayoutMetrics newLayoutMetrics; -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm index 17a8be48e8bdcf..5617af16a3912b 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSFullWindowOverlay.mm @@ -2,7 +2,7 @@ #import "RNSFullWindowOverlay.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -11,7 +11,7 @@ #import #else #import -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @implementation RNSFullWindowOverlayContainer @@ -63,14 +63,14 @@ @implementation RNSFullWindowOverlay { __weak RCTBridge *_bridge; RNSFullWindowOverlayContainer *_container; CGRect _reactFrame; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTSurfaceTouchHandler *_touchHandler; #else RCTTouchHandler *_touchHandler; -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (instancetype)init { if (self = [super init]) { @@ -80,7 +80,7 @@ - (instancetype)init } return self; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED - (instancetype)initWithBridge:(RCTBridge *)bridge { @@ -128,7 +128,7 @@ - (void)didMoveToWindow } } else { if (_touchHandler == nil) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED _touchHandler = [RCTSurfaceTouchHandler new]; #else _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; @@ -138,7 +138,7 @@ - (void)didMoveToWindow } } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #pragma mark - Fabric Specific // When the component unmounts we remove it from window's children, @@ -205,27 +205,27 @@ - (void)invalidate _container = nil; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSFullWindowOverlayCls(void) { return RNSFullWindowOverlay.class; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @implementation RNSFullWindowOverlayManager RCT_EXPORT_MODULE() -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else - (UIView *)view { return [[RNSFullWindowOverlay alloc] initWithBridge:self.bridge]; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h index 6bd374c70a5fb8..c0b00abf9a26ae 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.h @@ -4,7 +4,7 @@ #import "RNSEnums.h" #import "RNSScreenContainer.h" -#if RN_FABRIC_ENABLED +#if RCT_NEW_ARCH_ENABLED #import #else #import @@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals; - (void)notifyFinishTransitioning; - (RNSScreenView *)screenView; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (void)setViewToSnapshot:(UIView *)snapshot; - (void)resetViewToScreen; #endif @@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN @end @interface RNSScreenView : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else RCTView @@ -75,9 +75,16 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UIInterfaceOrientationMask screenOrientation; @property (nonatomic) BOOL statusBarHidden; @property (nonatomic) BOOL homeIndicatorHidden; + +// Props controlling UISheetPresentationController +@property (nonatomic) RNSScreenDetentType sheetAllowedDetents; +@property (nonatomic) RNSScreenDetentType sheetLargestUndimmedDetent; +@property (nonatomic) BOOL sheetGrabberVisible; +@property (nonatomic) CGFloat sheetCornerRadius; +@property (nonatomic) BOOL sheetExpandsWhenScrolledToEdge; #endif // !TARGET_OS_TV -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // we recreate the behavior of `reactSetFrame` on new architecture @property (nonatomic) facebook::react::LayoutMetrics oldLayoutMetrics; @property (nonatomic) facebook::react::LayoutMetrics newLayoutMetrics; @@ -90,11 +97,11 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy) RCTDirectEventBlock onWillDisappear; @property (nonatomic, copy) RCTDirectEventBlock onNativeDismissCancelled; @property (nonatomic, copy) RCTDirectEventBlock onTransitionProgress; -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED - (void)notifyFinishTransitioning; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (void)notifyWillAppear; - (void)notifyWillDisappear; - (void)notifyAppear; @@ -104,6 +111,7 @@ NS_ASSUME_NONNULL_BEGIN #endif - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward; +- (void)notifyDismissCancelledWithDismissCount:(int)dismissCount; - (BOOL)isModal; @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm index 4373c1afafeec8..d6975f785086be 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreen.mm @@ -4,7 +4,7 @@ #import "RNSScreenContainer.h" #import "RNSScreenWindowTraits.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -25,7 +25,7 @@ #import "RNSScreenStackHeaderConfig.h" @interface RNSScreenView () -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else @@ -34,7 +34,7 @@ @interface RNSScreenView () @implementation RNSScreenView { __weak RCTBridge *_bridge; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTSurfaceTouchHandler *_touchHandler; facebook::react::RNSScreenShadowNode::ConcreteState::Shared _state; // on fabric, they are not available by default so we need them exposed here too @@ -45,7 +45,7 @@ @implementation RNSScreenView { #endif } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { @@ -57,7 +57,7 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED - (instancetype)initWithBridge:(RCTBridge *)bridge { @@ -82,6 +82,9 @@ - (void)initCommonProps _hasStatusBarHiddenSet = NO; _hasOrientationSet = NO; _hasHomeIndicatorHiddenSet = NO; +#if !TARGET_OS_TV + _sheetExpandsWhenScrolledToEdge = YES; +#endif // !TARGET_OS_TV } - (UIViewController *)reactViewController @@ -89,7 +92,7 @@ - (UIViewController *)reactViewController return _controller; } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (NSArray *)reactSubviews { return _reactSubviews; @@ -98,7 +101,7 @@ - (UIViewController *)reactViewController - (void)updateBounds { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_state != nullptr) { auto newState = facebook::react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)}; _state->updateState(std::move(newState)); @@ -158,7 +161,7 @@ - (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation // https://developer.apple.com/documentation/uikit/uiviewcontroller/1621426-presentationcontroller?language=objc _controller.presentationController.delegate = self; } else if (_stackPresentation != RNSScreenStackPresentationPush) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // TODO: on Fabric, same controllers can be used as modals and then recycled and used a push which would result in // this error. It would be good to check if it doesn't leak in such case. #else @@ -277,7 +280,7 @@ - (void)addSubview:(UIView *)view - (void)notifyDismissedWithCount:(int)dismissCount { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -299,7 +302,7 @@ - (void)notifyDismissedWithCount:(int)dismissCount - (void)notifyDismissCancelledWithDismissCount:(int)dismissCount { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -316,7 +319,7 @@ - (void)notifyDismissCancelledWithDismissCount:(int)dismissCount - (void)notifyWillAppear { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -339,7 +342,7 @@ - (void)notifyWillDisappear if (_hideKeyboardOnSwipe) { [self endEditing:YES]; } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -355,7 +358,7 @@ - (void)notifyWillDisappear - (void)notifyAppear { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -375,7 +378,7 @@ - (void)notifyAppear - (void)notifyDisappear { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle if (_eventEmitter != nullptr) { @@ -391,7 +394,7 @@ - (void)notifyDisappear - (BOOL)isMountedUnderScreenOrReactRoot { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #define RNS_EXPECTED_VIEW RCTRootComponentView #else #define RNS_EXPECTED_VIEW RCTRootView @@ -412,7 +415,7 @@ - (void)didMoveToWindow // root application window. if (self.window != nil && ![self isMountedUnderScreenOrReactRoot]) { if (_touchHandler == nil) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED _touchHandler = [RCTSurfaceTouchHandler new]; #else _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; @@ -424,7 +427,7 @@ - (void)didMoveToWindow } } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (RCTSurfaceTouchHandler *)touchHandler #else - (RCTTouchHandler *)touchHandler @@ -449,7 +452,7 @@ - (void)notifyFinishTransitioning - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onTransitionProgress(facebook::react::RNSScreenEventEmitter::OnTransitionProgress{ @@ -484,7 +487,7 @@ - (void)presentationControllerWillDismiss:(UIPresentationController *)presentati // pulling down starting at some touchable item. Without "reset" the touchable // will never go back from highlighted state even when the modal start sliding // down. -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED [_touchHandler setEnabled:NO]; [_touchHandler setEnabled:YES]; #else @@ -514,8 +517,62 @@ - (BOOL)isModal return self.stackPresentation != RNSScreenStackPresentationPush; } +#if !TARGET_OS_TV +/** + * Updates settings for sheet presentation controller. + * Note that this method should not be called inside `stackPresentation` setter, because on Paper we don't have + * guarantee that values of all related props had been updated earlier. + */ +- (void)updatePresentationStyle +{ +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_15_0) && \ + __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0 + if (@available(iOS 15.0, *)) { + UISheetPresentationController *sheet = _controller.sheetPresentationController; + if (_stackPresentation == RNSScreenStackPresentationFormSheet && sheet != nil) { + sheet.prefersScrollingExpandsWhenScrolledToEdge = _sheetExpandsWhenScrolledToEdge; + sheet.prefersGrabberVisible = _sheetGrabberVisible; + sheet.preferredCornerRadius = + _sheetCornerRadius < 0 ? UISheetPresentationControllerAutomaticDimension : _sheetCornerRadius; + + if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeMedium) { + sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeLarge) { + sheet.largestUndimmedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + } else if (_sheetLargestUndimmedDetent == RNSScreenDetentTypeAll) { + sheet.largestUndimmedDetentIdentifier = nil; + } else { + RCTLogError(@"Unhandled value of sheetLargestUndimmedDetent passed"); + } + + if (_sheetAllowedDetents == RNSScreenDetentTypeMedium) { + sheet.detents = @[ UISheetPresentationControllerDetent.mediumDetent ]; + if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierMedium) { + [sheet animateChanges:^{ + sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierMedium; + }]; + } + } else if (_sheetAllowedDetents == RNSScreenDetentTypeLarge) { + sheet.detents = @[ UISheetPresentationControllerDetent.largeDetent ]; + if (sheet.selectedDetentIdentifier != UISheetPresentationControllerDetentIdentifierLarge) { + [sheet animateChanges:^{ + sheet.selectedDetentIdentifier = UISheetPresentationControllerDetentIdentifierLarge; + }]; + } + } else if (_sheetAllowedDetents == RNSScreenDetentTypeAll) { + sheet.detents = + @[ UISheetPresentationControllerDetent.mediumDetent, UISheetPresentationControllerDetent.largeDetent ]; + } else { + RCTLogError(@"Unhandled value of sheetAllowedDetents passed"); + } + } + } +#endif // Check for max allowed iOS version +} +#endif // !TARGET_OS_TV + #pragma mark - Fabric specific -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED + (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { @@ -613,6 +670,19 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props if (newScreenProps.homeIndicatorHidden != oldScreenProps.homeIndicatorHidden) { [self setHomeIndicatorHidden:newScreenProps.homeIndicatorHidden]; } + + [self setSheetGrabberVisible:newScreenProps.sheetGrabberVisible]; + [self setSheetCornerRadius:newScreenProps.sheetCornerRadius]; + [self setSheetExpandsWhenScrolledToEdge:newScreenProps.sheetExpandsWhenScrolledToEdge]; + + if (newScreenProps.sheetAllowedDetents != oldScreenProps.sheetAllowedDetents) { + [self setSheetAllowedDetents:[RNSConvert RNSScreenDetentTypeFromAllowedDetents:newScreenProps.sheetAllowedDetents]]; + } + + if (newScreenProps.sheetLargestUndimmedDetent != oldScreenProps.sheetLargestUndimmedDetent) { + [self setSheetLargestUndimmedDetent: + [RNSConvert RNSScreenDetentTypeFromLargestUndimmedDetent:newScreenProps.sheetLargestUndimmedDetent]]; + } #endif // !TARGET_OS_TV // Notice that we compare against _stackPresentation, not oldScreenProps.stackPresentation. @@ -658,9 +728,24 @@ - (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetric // Explanation taken from `reactSetFrame`, which is old arch equivalent of this code. } +- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask +{ +#if !TARGET_OS_TV + [self updatePresentationStyle]; +#endif // !TARGET_OS_TV +} + #pragma mark - Paper specific #else +- (void)didSetProps:(NSArray *)changedProps +{ + [super didSetProps:changedProps]; +#if !TARGET_OS_TV + [self updatePresentationStyle]; +#endif // !TARGET_OS_TV +} + - (void)setPointerEvents:(RCTPointerEvents)pointerEvents { // pointer events settings are managed by the parent screen container, we ignore @@ -690,7 +775,7 @@ - (void)invalidate @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenCls(void) { return RNSScreenView.class; @@ -721,7 +806,7 @@ - (instancetype)initWithView:(UIView *)view self.view = view; _fakeView = [UIView new]; _shouldNotify = YES; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED _initialView = (RNSScreenView *)view; #endif } @@ -810,7 +895,7 @@ - (void)viewDidAppear:(BOOL)animated - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED [self resetViewToScreen]; #endif if (self.parentViewController == nil && self.presentingViewController == nil) { @@ -832,7 +917,7 @@ - (void)viewDidDisappear:(BOOL)animated _isSwiping = NO; _shouldNotify = YES; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else [self traverseForScrollView:self.screenView]; #endif @@ -852,7 +937,7 @@ - (void)viewDidLayoutSubviews BOOL isPresentedAsNativeModal = self.parentViewController == nil && self.presentingViewController != nil; if (isDisplayedWithinUINavController || isPresentedAsNativeModal) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED [self.screenView updateBounds]; #else if (!CGRectEqualToRect(_lastViewFrame, self.screenView.frame)) { @@ -1074,7 +1159,7 @@ - (int)getIndexOfView:(UIView *)view // when we want to check props of ScreenView, we need to get them from _initialView - (RNSScreenView *)screenView { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED return _initialView; #else return (RNSScreenView *)self.view; @@ -1101,7 +1186,7 @@ - (void)hideHeaderIfNecessary BOOL wasSearchBarActive = prevNavigationItem.searchController.active; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED BOOL shouldHideHeader = !config.show; #else BOOL shouldHideHeader = config.hide; @@ -1118,7 +1203,7 @@ - (void)hideHeaderIfNecessary #endif } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #pragma mark - Fabric specific - (void)setViewToSnapshot:(UIView *)snapshot @@ -1197,6 +1282,12 @@ @implementation RNSScreenManager RCT_EXPORT_VIEW_PROPERTY(statusBarHidden, BOOL) RCT_EXPORT_VIEW_PROPERTY(statusBarStyle, RNSStatusBarStyle) RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL) + +RCT_EXPORT_VIEW_PROPERTY(sheetAllowedDetents, RNSScreenDetentType); +RCT_EXPORT_VIEW_PROPERTY(sheetLargestUndimmedDetent, RNSScreenDetentType); +RCT_EXPORT_VIEW_PROPERTY(sheetGrabberVisible, BOOL); +RCT_EXPORT_VIEW_PROPERTY(sheetCornerRadius, CGFloat); +RCT_EXPORT_VIEW_PROPERTY(sheetExpandsWhenScrolledToEdge, BOOL); #endif #if !TARGET_OS_TV @@ -1309,6 +1400,16 @@ @implementation RCTConvert (RNSScreen) RNSStatusBarStyleAuto, integerValue) +RCT_ENUM_CONVERTER( + RNSScreenDetentType, + (@{ + @"large" : @(RNSScreenDetentTypeLarge), + @"medium" : @(RNSScreenDetentTypeMedium), + @"all" : @(RNSScreenDetentTypeAll), + }), + RNSScreenDetentTypeAll, + integerValue) + + (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(id)json { json = [self NSString:json]; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.h index 4f4823324b37fc..9169a4f97ca83d 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.h @@ -1,4 +1,4 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #else #endif @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN @end @interface RNSScreenContainerView : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else UIView diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm index baea98c1a1f770..d32639ca1faeb8 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenContainer.mm @@ -1,7 +1,7 @@ #import "RNSScreenContainer.h" #import "RNSScreen.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -58,7 +58,7 @@ @implementation RNSScreenContainerView { - (instancetype)init { if (self = [super init]) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED static const auto defaultProps = std::make_shared(); _props = defaultProps; #endif @@ -234,7 +234,7 @@ - (void)layoutSubviews [super layoutSubviews]; _controller.view.frame = self.bounds; for (RNSScreenView *subview in _reactSubviews) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED facebook::react::LayoutMetrics screenLayoutMetrics = subview.newLayoutMetrics; screenLayoutMetrics.frame = RCTRectFromCGRect(CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)); [subview updateLayoutMetrics:screenLayoutMetrics oldLayoutMetrics:subview.oldLayoutMetrics]; @@ -246,7 +246,7 @@ - (void)layoutSubviews } #pragma mark-- Fabric specific -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { @@ -321,7 +321,7 @@ - (void)invalidate @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenContainerCls(void) { return RNSScreenContainerView.class; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm index b32546c9bb38f5..0a07fe2fe3f9bf 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenNavigationContainer.mm @@ -2,7 +2,7 @@ #import "RNSScreen.h" #import "RNSScreenContainer.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -36,7 +36,7 @@ - (void)updateContainer } #pragma mark-- Fabric specific -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED + (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { return facebook::react::concreteComponentDescriptorProvider< @@ -46,7 +46,7 @@ - (void)updateContainer @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenNavigationContainerCls(void) { return RNSScreenNavigationContainerView.class; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.h index efaf428c673135..14f375452c60ad 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.h @@ -1,4 +1,4 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #else #import @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @end @interface RNSScreenStackView : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else UIView @@ -23,10 +23,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)markChildUpdated; - (void)didUpdateChildren; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else @property (nonatomic, copy) RCTDirectEventBlock onFinishTransitioning; -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm index 8744a64f6a8114..e97011e70ee180 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStack.mm @@ -1,4 +1,4 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -16,7 +16,7 @@ #import #import #import -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED #import "RNSScreen.h" #import "RNSScreenStack.h" @@ -29,7 +29,7 @@ @interface RNSScreenStackView () < UIAdaptivePresentationControllerDelegate, UIGestureRecognizerDelegate, UIViewControllerTransitioningDelegate -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED , RCTMountingTransactionObserving #endif @@ -95,12 +95,12 @@ @implementation RNSScreenStackView { BOOL _hasLayout; __weak RNSScreenStackManager *_manager; BOOL _updateScheduled; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED UIView *_snapshot; #endif } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { @@ -111,7 +111,7 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED - (instancetype)initWithManager:(RNSScreenStackManager *)manager { @@ -140,11 +140,26 @@ - (void)initCommonProps [_controller setViewControllers:@[ [UIViewController new] ]]; } +#pragma mark - helper methods + +- (BOOL)shouldCancelDismissFromView:(RNSScreenView *)fromView toView:(RNSScreenView *)toView +{ + int fromIndex = (int)[_reactSubviews indexOfObject:fromView]; + int toIndex = (int)[_reactSubviews indexOfObject:toView]; + for (int i = fromIndex; i > toIndex; i--) { + if (_reactSubviews[i].preventNativeDismiss) { + return YES; + break; + } + } + return NO; +} + #pragma mark - Common - (void)emitOnFinishTransitioningEvent { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onFinishTransitioning(facebook::react::RNSScreenStackEventEmitter::OnFinishTransitioning{}); @@ -161,7 +176,7 @@ - (void)navigationController:(UINavigationController *)navigationController animated:(BOOL)animated { UIView *view = viewController.view; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (![view isKindOfClass:[RNSScreenView class]]) { // if the current view is a snapshot, config was already removed so we don't trigger the method return; @@ -188,7 +203,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio [_presentedModals removeObject:presentationController.presentedViewController]; _updatingModals = NO; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED [self emitOnFinishTransitioningEvent]; #else // we double check if there are no new controllers pending to be presented since someone could @@ -215,7 +230,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio - (void)didMoveToWindow { [super didMoveToWindow]; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED // for handling nested stacks [self maybeAddToParentAndUpdateContainer]; #else @@ -231,7 +246,7 @@ - (void)didMoveToWindow - (void)maybeAddToParentAndUpdateContainer { BOOL wasScreenMounted = _controller.parentViewController != nil; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED BOOL isScreenReadyForShowing = self.window; #else BOOL isScreenReadyForShowing = self.window && _hasLayout; @@ -452,7 +467,7 @@ - (void)setPushViewControllers:(NSArray *)controllers } UIViewController *top = controllers.lastObject; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED UIViewController *previousTop = _controller.topViewController; #else UIViewController *previousTop = _controller.viewControllers.lastObject; @@ -474,7 +489,7 @@ - (void)setPushViewControllers:(NSArray *)controllers if (![_controller.viewControllers containsObject:top] && ((RNSScreenView *)top.view).replaceAnimation == RNSScreenReplaceAnimationPush) { // setting new controllers with animation does `push` animation by default -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED auto screenController = (RNSScreen *)top; [screenController resetViewToScreen]; #endif @@ -495,7 +510,7 @@ - (void)setPushViewControllers:(NSArray *)controllers NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; [newControllers removeLastObject]; [_controller setViewControllers:newControllers animated:NO]; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED auto screenController = (RNSScreen *)top; [screenController resetViewToScreen]; #endif @@ -542,7 +557,7 @@ - (void)layoutSubviews - (void)dismissOnReload { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if ([_controller.visibleViewController isKindOfClass:[RNSScreen class]]) { [(RNSScreen *)_controller.visibleViewController resetViewToScreen]; } @@ -566,10 +581,14 @@ - (void)dismissOnReload } else if (operation == UINavigationControllerOperationPop) { screen = ((RNSScreen *)fromVC).screenView; } + BOOL shouldCancelDismiss = [self shouldCancelDismissFromView:(RNSScreenView *)fromVC.view + toView:(RNSScreenView *)toVC.view]; if (screen != nil && - // we need to return the animator when full width swiping even if the animation is not custom, + // when preventing the native dismiss with back button, we have to return the animator. + // Also, we need to return the animator when full width swiping even if the animation is not custom, // otherwise the screen will be just popped immediately due to no animation - (_isFullWidthSwiping || [RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation])) { + ((operation == UINavigationControllerOperationPop && shouldCancelDismiss) || _isFullWidthSwiping || + [RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation])) { return [[RNSScreenStackAnimator alloc] initWithOperation:operation]; } return nil; @@ -585,7 +604,7 @@ - (void)cancelTouchesInParent while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) parent = parent.superview; if (parent != nil) { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; #else RCTTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; @@ -727,6 +746,26 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer interactionControllerForAnimationController: (id)animationController { + RNSScreenView *fromView = [_controller.transitionCoordinator viewForKey:UITransitionContextFromViewKey]; + RNSScreenView *toView = [_controller.transitionCoordinator viewForKey:UITransitionContextToViewKey]; + // we can intercept clicking back button here, we check reactSuperview since this method also fires when + // navigating back from JS + if (_interactionController == nil && fromView.reactSuperview) { + BOOL shouldCancelDismiss = [self shouldCancelDismissFromView:fromView toView:toView]; + if (shouldCancelDismiss) { + _interactionController = [UIPercentDrivenInteractiveTransition new]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self->_interactionController cancelInteractiveTransition]; + self->_interactionController = nil; + int fromIndex = (int)[self->_reactSubviews indexOfObject:fromView]; + int toIndex = (int)[self->_reactSubviews indexOfObject:toView]; + int indexDiff = fromIndex - toIndex; + int dismissCount = indexDiff > 0 ? indexDiff : 1; + [self updateContainer]; + [fromView notifyDismissCancelledWithDismissCount:dismissCount]; + }); + } + } return _interactionController; } @@ -901,7 +940,7 @@ - (void)didUpdateReactSubviews }); } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #pragma mark - Fabric specific - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index @@ -1013,11 +1052,11 @@ - (void)invalidate [_controller removeFromParentViewController]; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenStackCls(void) { return RNSScreenStackView.class; @@ -1032,7 +1071,7 @@ @implementation RNSScreenStackManager { RCT_EXPORT_VIEW_PROPERTY(onFinishTransitioning, RCTDirectEventBlock); -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else - (UIView *)view { @@ -1043,7 +1082,7 @@ - (UIView *)view [_stacks addPointer:(__bridge void *)view]; return view; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED - (void)invalidate { diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.h index 600aa303850ed5..83d4b61afef462 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.h @@ -1,4 +1,4 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #else #import @@ -9,8 +9,14 @@ #import "RNSScreenStackHeaderSubview.h" #import "RNSSearchBar.h" +@interface NSString (RNSStringUtil) + ++ (BOOL)RNSisBlank:(NSString *)string; + +@end + @interface RNSScreenStackHeaderConfig : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else UIView @@ -18,7 +24,7 @@ @property (nonatomic, weak) RNSScreenView *screenView; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED @property (nonatomic) BOOL show; #else @property (nonatomic) UIBlurEffectStyle blurEffect; @@ -33,6 +39,7 @@ @property (nonatomic, retain) NSString *backTitle; @property (nonatomic, retain) NSString *backTitleFontFamily; @property (nonatomic, retain) NSNumber *backTitleFontSize; +@property (nonatomic, getter=isBackTitleVisible) BOOL backTitleVisible; @property (nonatomic, retain) UIColor *backgroundColor; @property (nonatomic, retain) UIColor *color; @property (nonatomic) BOOL largeTitle; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm index 5163c4906a49c3..a5eb013191b098 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderConfig.mm @@ -1,57 +1,74 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import +#import #import +#import #import #import #import #import +#import "RCTImageComponentView+RNSScreenStackHeaderConfig.h" #else -#import -#import -#import #import #import #import #import #endif +#import #import +#import +#import #import "RNSScreen.h" #import "RNSScreenStackHeaderConfig.h" #import "RNSSearchBar.h" #import "RNSUIBarButtonItem.h" -#ifdef RN_FABRIC_ENABLED -#else +#ifdef RCT_NEW_ARCH_ENABLED +namespace rct = facebook::react; +#endif // RCT_NEW_ARCH_ENABLED + +#ifndef RCT_NEW_ARCH_ENABLED // Some RN private method hacking below. Couldn't figure out better way to access image data // of a given RCTImageView. See more comments in the code section processing SubviewTypeBackButton @interface RCTImageView (Private) - (UIImage *)image; @end +#endif // !RCT_NEW_ARCH_ENABLED @interface RCTImageLoader (Private) - (id)imageCache; @end -#endif + +@implementation NSString (RNSStringUtil) + ++ (BOOL)RNSisBlank:(NSString *)string +{ + if (string == nil) { + return YES; + } + return [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0; +} + +@end @implementation RNSScreenStackHeaderConfig { NSMutableArray *_reactSubviews; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED BOOL _initialPropsSet; #else #endif } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); + static const auto defaultProps = std::make_shared(); _props = defaultProps; - self.hidden = YES; _show = YES; _translucent = NO; - _reactSubviews = [NSMutableArray new]; + [self initProps]; } return self; } @@ -59,14 +76,20 @@ - (instancetype)initWithFrame:(CGRect)frame - (instancetype)init { if (self = [super init]) { - self.hidden = YES; _translucent = YES; - _reactSubviews = [NSMutableArray new]; + [self initProps]; } return self; } #endif +- (void)initProps +{ + self.hidden = YES; + _reactSubviews = [NSMutableArray new]; + _backTitleVisible = YES; +} + - (UIView *)reactSuperview { return _screenView; @@ -243,14 +266,15 @@ + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)but + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { -#ifdef RN_FABRIC_ENABLED - @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]); -#else BOOL hasBackButtonImage = NO; for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { if (subview.type == RNSScreenStackHeaderSubviewTypeBackButton && subview.subviews.count > 0) { hasBackButtonImage = YES; +#ifdef RCT_NEW_ARCH_ENABLED + RCTImageComponentView *imageView = subview.subviews[0]; +#else RCTImageView *imageView = subview.subviews[0]; +#endif // RCT_NEW_ARCH_ENABLED if (imageView.image == nil) { // This is yet another workaround for loading custom back icon. It turns out that under // certain circumstances image attribute can be null despite the app running in production @@ -259,14 +283,16 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf // does not populate the frame of the image view before the loading start. The latter result // in the image attribute not being updated. We manually set frame to the size of an image // in order to trigger proper reload that'd update the image attribute. - RCTImageSource *source = imageView.imageSources[0]; + RCTImageSource *imageSource = [RNSScreenStackHeaderConfig imageSourceFromImageView:imageView]; [imageView reactSetFrame:CGRectMake( imageView.frame.origin.x, imageView.frame.origin.y, - source.size.width, - source.size.height)]; + imageSource.size.width, + imageSource.size.height)]; } + UIImage *image = imageView.image; + // IMPORTANT!!! // image can be nil in DEV MODE ONLY // @@ -280,12 +306,19 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf if (image == nil) { // in DEV MODE we try to load from cache (we use private API for that as it is not exposed // publically in headers). - RCTImageSource *source = imageView.imageSources[0]; - RCTImageLoader *imageloader = [subview.bridge moduleForClass:[RCTImageLoader class]]; - image = [imageloader.imageCache imageForUrl:source.request.URL.absoluteString - size:source.size - scale:source.scale - resizeMode:imageView.resizeMode]; + RCTImageSource *imageSource = [RNSScreenStackHeaderConfig imageSourceFromImageView:imageView]; + RCTImageLoader *imageLoader = [subview.bridge moduleForClass:[RCTImageLoader class]]; + + image = [imageLoader.imageCache + imageForUrl:imageSource.request.URL.absoluteString + size:imageSource.size + scale:imageSource.scale +#ifdef RCT_NEW_ARCH_ENABLED + resizeMode:resizeModeFromCppEquiv( + std::static_pointer_cast(imageView.props)->resizeMode)]; +#else + resizeMode:imageView.resizeMode]; +#endif // RCT_NEW_ARCH_ENABLED } if (image == nil) { // This will be triggered if the image is not in the cache yet. What we do is we wait until @@ -312,7 +345,6 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf } } } -#endif // RN_FABRIC_ENABLED return nil; } @@ -343,7 +375,7 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc } // TODO: implement blurEffect on Fabric -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else if (config.blurEffect) { appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect]; @@ -404,19 +436,15 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc appearance.largeTitleTextAttributes = largeAttrs; } -#ifdef RN_FABRIC_ENABLED - [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; -#else UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config]; if (backButtonImage) { [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage]; } else if (appearance.backIndicatorImage) { [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; } -#endif // RN_FABRIC_ENABLED return appearance; } -#endif +#endif // Check for >= iOS 13.0 + (void)updateViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config @@ -430,7 +458,7 @@ + (void)updateViewController:(UIViewController *)vc currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil; BOOL wasHidden = navctr.navigationBarHidden; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED BOOL shouldHide = config == nil || !config.show; #else BOOL shouldHide = config == nil || config.hide; @@ -460,32 +488,15 @@ + (void)updateViewController:(UIViewController *)vc } #if !TARGET_OS_TV - // Fix for github.com/react-navigation/react-navigation/issues/11015 - // It allows to hide back button title and use back button menu as normal. - // Back button display mode and back button menu are available since iOS 14. - if (@available(iOS 14.0, *)) { - // Make sure to set display mode to default. - // This line resets back button display mode - especially needed on the Fabric architecture. - navitem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeDefault; - - NSString *trimmedBackTitle = - [config.backTitle stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; - - // When an whitespace only back title is passed set back button mode to minimal. - if (config.backTitle != nil && [trimmedBackTitle length] == 0) { - navitem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeMinimal; - } - } else if ( - config.backTitle != nil || config.backTitleFontFamily || config.backTitleFontSize || - config.disableBackButtonMenu) { - RNSUIBarButtonItem *backBarButtonItem = [[RNSUIBarButtonItem alloc] initWithTitle:config.backTitle ?: prevItem.title - style:UIBarButtonItemStylePlain - target:nil - action:nil]; - - [backBarButtonItem setMenuHidden:config.disableBackButtonMenu]; - - prevItem.backBarButtonItem = backBarButtonItem; + const auto isBackTitleBlank = [NSString RNSisBlank:config.backTitle] == YES; + NSString *resolvedBackTitle = isBackTitleBlank ? prevItem.title : config.backTitle; + RNSUIBarButtonItem *backBarButtonItem = [[RNSUIBarButtonItem alloc] initWithTitle:resolvedBackTitle + style:UIBarButtonItemStylePlain + target:nil + action:nil]; + [backBarButtonItem setMenuHidden:config.disableBackButtonMenu]; + + if (config.isBackTitleVisible) { if (config.backTitleFontFamily || config.backTitleFontSize) { NSMutableDictionary *attrs = [NSMutableDictionary new]; NSNumber *size = config.backTitleFontSize ?: @17; @@ -500,11 +511,18 @@ + (void)updateViewController:(UIViewController *)vc } else { attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]]; } - [self setTitleAttibutes:attrs forButton:prevItem.backBarButtonItem]; + [self setTitleAttibutes:attrs forButton:backBarButtonItem]; } } else { - prevItem.backBarButtonItem = nil; + // back button title should be not visible next to back button, + // but it should still appear in back menu (if one is enabled) + + // When backBarButtonItem's title is null, back menu will use value + // of backButtonTitle + [backBarButtonItem setTitle:nil]; + prevItem.backButtonTitle = resolvedBackTitle; } + prevItem.backBarButtonItem = backBarButtonItem; if (@available(iOS 11.0, *)) { if (config.largeTitle) { @@ -594,9 +612,6 @@ + (void)updateViewController:(UIViewController *)vc break; } case RNSScreenStackHeaderSubviewTypeBackButton: { -#ifdef RN_FABRIC_ENABLED - RCTLogWarn(@"Back button subview is not yet Fabric compatible in react-native-screens"); -#endif break; } } @@ -654,7 +669,7 @@ - (void)didUpdateReactSubviews [self updateViewControllerIfNeeded]; } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #pragma mark - Fabric specific - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index @@ -683,6 +698,39 @@ - (void)unmountChildComponentView:(UIView *)childCompo [childComponentView removeFromSuperview]; } +static RCTResizeMode resizeModeFromCppEquiv(rct::ImageResizeMode resizeMode) +{ + switch (resizeMode) { + case rct::ImageResizeMode::Cover: + return RCTResizeModeCover; + case rct::ImageResizeMode::Contain: + return RCTResizeModeContain; + case rct::ImageResizeMode::Stretch: + return RCTResizeModeStretch; + case rct::ImageResizeMode::Center: + return RCTResizeModeCenter; + case rct::ImageResizeMode::Repeat: + return RCTResizeModeRepeat; + } +} + +/** + * Fabric implementation of helper method for +loadBackButtonImageInViewController:withConfig: + * There is corresponding Paper implementation (with different parameter type) in Paper specific section. + */ ++ (RCTImageSource *)imageSourceFromImageView:(RCTImageComponentView *)view +{ + auto const imageProps = *std::static_pointer_cast(view.props); + rct::ImageSource cppImageSource = imageProps.sources.at(0); + auto imageSize = CGSize{cppImageSource.size.width, cppImageSource.size.height}; + NSURLRequest *request = + [NSURLRequest requestWithURL:[NSURL URLWithString:RCTNSStringFromStringNilIfEmpty(cppImageSource.uri)]]; + RCTImageSource *imageSource = [[RCTImageSource alloc] initWithURLRequest:request + size:imageSize + scale:cppImageSource.scale]; + return imageSource; +} + #pragma mark - RCTComponentViewProtocol - (void)prepareForRecycle @@ -691,10 +739,9 @@ - (void)prepareForRecycle _initialPropsSet = NO; } -+ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider ++ (rct::ComponentDescriptorProvider)componentDescriptorProvider { - return facebook::react::concreteComponentDescriptorProvider< - facebook::react::RNSScreenStackHeaderConfigComponentDescriptor>(); + return rct::concreteComponentDescriptorProvider(); } - (NSNumber *)getFontSizePropValue:(int)value @@ -704,24 +751,20 @@ - (NSNumber *)getFontSizePropValue:(int)value return nil; } -- (UISemanticContentAttribute)getDirectionPropValue:(facebook::react::RNSScreenStackHeaderConfigDirection)direction +- (UISemanticContentAttribute)getDirectionPropValue:(rct::RNSScreenStackHeaderConfigDirection)direction { switch (direction) { - case facebook::react::RNSScreenStackHeaderConfigDirection::Rtl: + case rct::RNSScreenStackHeaderConfigDirection::Rtl: return UISemanticContentAttributeForceRightToLeft; - case facebook::react::RNSScreenStackHeaderConfigDirection::Ltr: + case rct::RNSScreenStackHeaderConfigDirection::Ltr: return UISemanticContentAttributeForceLeftToRight; } } -- (void)updateProps:(facebook::react::Props::Shared const &)props - oldProps:(facebook::react::Props::Shared const &)oldProps +- (void)updateProps:(rct::Props::Shared const &)props oldProps:(rct::Props::Shared const &)oldProps { - [super updateProps:props oldProps:oldProps]; - - const auto &oldScreenProps = - *std::static_pointer_cast(_props); - const auto &newScreenProps = *std::static_pointer_cast(props); + const auto &oldScreenProps = *std::static_pointer_cast(_props); + const auto &newScreenProps = *std::static_pointer_cast(props); BOOL needsNavigationControllerLayout = !_initialPropsSet; @@ -767,6 +810,8 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props _direction = [self getDirectionPropValue:newScreenProps.direction]; } + _backTitleVisible = newScreenProps.backTitleVisible; + // We cannot compare SharedColor because it is shared value. // We could compare color value, but it is more performant to just assign new value _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor); @@ -781,7 +826,9 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props } _initialPropsSet = YES; - _props = std::static_pointer_cast(props); + _props = std::static_pointer_cast(props); + + [super updateProps:props oldProps:oldProps]; } #else @@ -799,10 +846,19 @@ - (void)didSetProps:(NSArray *)changedProps } } +/** + * Paper implementation of helper method for +loadBackButtonImageInViewController:withConfig: + * There is corresponding Fabric implementation (with different parameter type) in Fabric specific section. + */ ++ (RCTImageSource *)imageSourceFromImageView:(RCTImageView *)view +{ + return view.imageSources[0]; +} + #endif @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenStackHeaderConfigCls(void) { return RNSScreenStackHeaderConfig.class; @@ -827,6 +883,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(backTitleFontFamily, NSString) RCT_EXPORT_VIEW_PROPERTY(backTitleFontSize, NSNumber) RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(backTitleVisible, BOOL) RCT_EXPORT_VIEW_PROPERTY(blurEffect, UIBlurEffectStyle) RCT_EXPORT_VIEW_PROPERTY(color, UIColor) RCT_EXPORT_VIEW_PROPERTY(direction, UISemanticContentAttribute) diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.h b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.h index 30bffb9670f509..6930491d7e34b1 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.h @@ -1,5 +1,5 @@ -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #endif @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @interface RNSScreenStackHeaderSubview : -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED RCTViewComponentView #else UIView @@ -20,13 +20,12 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, weak) UIView *reactSuperview; -#ifdef RN_FABRIC_ENABLED -#else @property (nonatomic, weak) RCTBridge *bridge; +#ifdef RCT_NEW_ARCH_ENABLED +#else - (instancetype)initWithBridge:(RCTBridge *)bridge; - -#endif +#endif // RCT_NEW_ARCH_ENABLED @end diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm index 70a430b04062de..c8b1c8f57204e6 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenStackHeaderSubview.mm @@ -1,7 +1,7 @@ #import "RNSScreenStackHeaderSubview.h" #import "RNSConvert.h" -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import @@ -10,11 +10,15 @@ #import #endif +@interface RCTBridge (Private) ++ (RCTBridge *)currentBridge; +@end + @implementation RNSScreenStackHeaderSubview #pragma mark - Common -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #pragma mark - Fabric specific @@ -40,13 +44,8 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props { const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); - const auto &oldHeaderSubviewProps = - *std::static_pointer_cast(_props); - - if (newHeaderSubviewProps.type != oldHeaderSubviewProps.type) { - _type = [RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]; - } + [self setType:[RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]]; [super updateProps:props oldProps:oldProps]; } @@ -93,7 +92,17 @@ - (void)reactSetFrame:(CGRect)frame [super reactSetFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; } -#endif // RN_FABRIC_ENABLED +#endif // RCT_NEW_ARCH_ENABLED + +- (RCTBridge *)bridge +{ +#ifdef RCT_NEW_ARCH_ENABLED + return [RCTBridge currentBridge]; +#else + return _bridge; +#endif // RCT_NEW_ARCH_ENABLED +} + @end @implementation RNSScreenStackHeaderSubviewManager @@ -102,7 +111,7 @@ @implementation RNSScreenStackHeaderSubviewManager RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType) -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else - (UIView *)view { @@ -112,7 +121,7 @@ - (UIView *)view @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSScreenStackHeaderSubviewCls(void) { return RNSScreenStackHeaderSubview.class; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenWindowTraits.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenWindowTraits.mm index 5b1bdc9b096218..358c0b15a1a129 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSScreenWindowTraits.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSScreenWindowTraits.mm @@ -174,11 +174,34 @@ + (void)enforceDesiredDeviceOrientation } } if (newOrientation != UIInterfaceOrientationUnknown) { - [[UIDevice currentDevice] setValue:@(newOrientation) forKey:@"orientation"]; - [UIViewController attemptRotationToDeviceOrientation]; +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_16_0) && \ + __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_16_0 + if (@available(iOS 16.0, *)) { + NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; + UIWindowScene *scene = (UIWindowScene *)array[0]; + UIWindowSceneGeometryPreferencesIOS *geometryPreferences = + [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:orientationMask]; + [scene requestGeometryUpdateWithPreferences:geometryPreferences + errorHandler:^(NSError *_Nonnull error){ + }]; + + // `attemptRotationToDeviceOrientation` is deprecated for modern OS versions + // so we need to use `setNeedsUpdateOfSupportedInterfaceOrientations` + UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; + while (topController.presentedViewController) { + topController = topController.presentedViewController; + } + + [topController setNeedsUpdateOfSupportedInterfaceOrientations]; + } else +#endif // Check for iOS 16 + { + [[UIDevice currentDevice] setValue:@(newOrientation) forKey:@"orientation"]; + [UIViewController attemptRotationToDeviceOrientation]; + } } }); -#endif +#endif // !TARGET_TV_OS } + (void)updateWindowTraits diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.h b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.h index 9c8a90c2f0c15a..43ded0ed5cc72f 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.h +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.h @@ -1,7 +1,8 @@ #import -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import +#import #endif #import @@ -9,8 +10,8 @@ #import @interface RNSSearchBar : -#ifdef RN_FABRIC_ENABLED - RCTViewComponentView +#ifdef RCT_NEW_ARCH_ENABLED + RCTViewComponentView #else UIView #endif @@ -19,7 +20,7 @@ @property (nonatomic, retain) UISearchController *controller; -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else @property (nonatomic, copy) RCTBubblingEventBlock onChangeText; @property (nonatomic, copy) RCTBubblingEventBlock onCancelButtonPress; diff --git a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm index ebd322406d6288..9919a2f21d9fb7 100644 --- a/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm +++ b/ios/vendored/unversioned/react-native-screens/ios/RNSSearchBar.mm @@ -6,13 +6,12 @@ #import #import -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #import #import #import #import #import -#import #import "RNSConvert.h" #endif @@ -33,7 +32,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (instancetype)init { if (self = [super init]) { @@ -54,7 +53,7 @@ - (void)initCommonProps - (void)emitOnFocusEvent { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onFocus(facebook::react::RNSSearchBarEventEmitter::OnFocus{}); @@ -68,7 +67,7 @@ - (void)emitOnFocusEvent - (void)emitOnBlurEvent { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onBlur(facebook::react::RNSSearchBarEventEmitter::OnBlur{}); @@ -82,7 +81,7 @@ - (void)emitOnBlurEvent - (void)emitOnSearchButtonPressEventWithText:(NSString *)text { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onSearchButtonPress( @@ -99,7 +98,7 @@ - (void)emitOnSearchButtonPressEventWithText:(NSString *)text - (void)emitOnCancelButtonPressEvent { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onCancelButtonPress(facebook::react::RNSSearchBarEventEmitter::OnCancelButtonPress{}); @@ -113,7 +112,7 @@ - (void)emitOnCancelButtonPressEvent - (void)emitOnChangeTextEventWithText:(NSString *)text { -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED if (_eventEmitter != nullptr) { std::dynamic_pointer_cast(_eventEmitter) ->onChangeText(facebook::react::RNSSearchBarEventEmitter::OnChangeText{.text = RCTStringFromNSString(text)}); @@ -257,9 +256,36 @@ - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar } #endif // !TARGET_OS_TV +- (void)blur +{ + [_controller.searchBar resignFirstResponder]; +} + +- (void)focus +{ + [_controller.searchBar becomeFirstResponder]; +} + +- (void)clearText +{ + [_controller.searchBar setText:@""]; +} + +- (void)toggleCancelButton:(BOOL)flag +{ +#if !TARGET_OS_TV + [_controller.searchBar setShowsCancelButton:flag animated:YES]; +#endif +} + +- (void)setText:(NSString *)text +{ + [_controller.searchBar setText:text]; +} + #pragma mark-- Fabric specific -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED - (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(facebook::react::Props::Shared const &)oldProps { @@ -308,12 +334,17 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props return facebook::react::concreteComponentDescriptorProvider(); } +- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args +{ + RCTRNSSearchBarHandleCommand(self, commandName, args); +} + #else -#endif +#endif // RCT_NEW_ARCH_ENABLED @end -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED Class RNSSearchBarCls(void) { return RNSSearchBar.class; @@ -324,7 +355,7 @@ @implementation RNSSearchBarManager RCT_EXPORT_MODULE() -#ifdef RN_FABRIC_ENABLED +#ifdef RCT_NEW_ARCH_ENABLED #else - (UIView *)view { @@ -348,4 +379,48 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onFocus, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onBlur, RCTBubblingEventBlock) +#ifndef RCT_NEW_ARCH_ENABLED + +RCT_EXPORT_METHOD(focus : (NSNumber *_Nonnull)reactTag) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNSSearchBar *searchBar = viewRegistry[reactTag]; + [searchBar focus]; + }]; +} + +RCT_EXPORT_METHOD(blur : (NSNumber *_Nonnull)reactTag) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNSSearchBar *searchBar = viewRegistry[reactTag]; + [searchBar blur]; + }]; +} + +RCT_EXPORT_METHOD(clearText : (NSNumber *_Nonnull)reactTag) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNSSearchBar *searchBar = viewRegistry[reactTag]; + [searchBar clearText]; + }]; +} + +RCT_EXPORT_METHOD(toggleCancelButton : (NSNumber *_Nonnull)reactTag flag : (BOOL *)flag) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNSSearchBar *searchBar = viewRegistry[reactTag]; + [searchBar toggleCancelButton:flag]; + }]; +} + +RCT_EXPORT_METHOD(setText : (NSNumber *_Nonnull)reactTag text : (NSString *)text) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + RNSSearchBar *searchBar = viewRegistry[reactTag]; + [searchBar setText:text]; + }]; +} + +#endif /* !RCT_NEW_ARCH_ENABLED */ + @end diff --git a/packages/expo-stories/package.json b/packages/expo-stories/package.json index 96a1972dcac687..64b593720ec4aa 100644 --- a/packages/expo-stories/package.json +++ b/packages/expo-stories/package.json @@ -32,7 +32,7 @@ "glob": "^7.1.7", "react-native-gesture-handler": "~2.12.0", "react-native-safe-area-context": "4.6.3", - "react-native-screens": "~3.20.0", + "react-native-screens": "~3.22.0", "react-native-svg": "13.9.0", "sane": "^5.0.1" } diff --git a/packages/expo/bundledNativeModules.json b/packages/expo/bundledNativeModules.json index fb6227ef385ea7..d8b666299fd9f2 100644 --- a/packages/expo/bundledNativeModules.json +++ b/packages/expo/bundledNativeModules.json @@ -90,7 +90,7 @@ "react-native-maps": "1.7.1", "react-native-pager-view": "6.2.0", "react-native-reanimated": "~3.3.0", - "react-native-screens": "~3.20.0", + "react-native-screens": "~3.22.0", "react-native-safe-area-context": "4.6.3", "react-native-shared-element": "0.8.8", "react-native-svg": "13.9.0", diff --git a/yarn.lock b/yarn.lock index 55d9b496ad3b4b..fdec071912ba58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15925,10 +15925,10 @@ react-native-safe-modules@^1.0.3: dependencies: dedent "^0.6.0" -react-native-screens@~3.20.0: - version "3.20.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.20.0.tgz#4d154177395e5541387d9a05bc2e12e54d2fb5b1" - integrity sha512-joWUKWAVHxymP3mL9gYApFHAsbd9L6ZcmpoZa6Sl3W/82bvvNVMqcfP7MeNqVCg73qZ8yL4fW+J/syusHleUgg== +react-native-screens@~3.22.0: + version "3.22.0" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.22.0.tgz#7d892baf964fddb642b5eec71a09e2aeb501e578" + integrity sha512-csLypBSXIt/egh37YJmokETptZJCtZdoZBsZNLR9n31GesDyVogprT+MM22dEPDuxPxt/mFWq+lSpVwk7khuTw== dependencies: react-freeze "^1.0.0" warn-once "^0.1.0"