Skip to content

Commit

Permalink
Merge branch 'main' into @aleqsio/upgrade-react-native-webview-to-11.…
Browse files Browse the repository at this point in the history
…26.0
  • Loading branch information
aleqsio committed Jan 25, 2023
2 parents d1c7eb9 + b83210f commit 2ce5517
Show file tree
Hide file tree
Showing 69 changed files with 1,553 additions and 1,187 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,11 +8,13 @@ Package-specific changes not released in any SDK will be added here just before
### 📚 3rd party library updates

- Updated `react-native-webview` from `11.23.1` to `11.26.0`. ([#20933](https://github.com/expo/expo/pull/20933) by [@aleqsio](https://github.com/aleqsio))
- Updated `react-native-gesture-handler` from `2.8.0` to `2.9.0`. ([#20930](https://github.com/expo/expo/pull/20930) by [@tsapeta](https://github.com/tsapeta))
- Updated `react-native-shared-element` from `0.8.4` to `0.8.7`. ([#20593](https://github.com/expo/expo/pull/20593) by [@ijzerenhein](https://github.com/ijzerenhein))
- Updated `@react-native-async-storage/async-storage` from `1.17.3' to `1.17.11`. ([#20780](https://github.com/expo/expo/pull/20780) by [@kudo](https://github.com/kudo))
- Updated `react-native-reanimated` from `2.12.0` to `2.14.0`. ([#20798](https://github.com/expo/expo/pull/20798) by [@kudo](https://github.com/kudo))
- Updated `@shopify/react-native-skia` from `0.1.157` to `0.1.171`. ([#20857](https://github.com/expo/expo/pull/20857) by [@kudo](https://github.com/kudo))
- Updated `react-native-safe-area-context` from `4.4.1` to `4.5.0`. ([#20899](https://github.com/expo/expo/pull/20899) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Updated `react-native-screens` from `3.18.0` to `3.19.0`. ([#20938](https://github.com/expo/expo/pull/20938) by [@lukmccall](https://github.com/lukmccall))

### 🛠 Breaking changes

Expand Down Expand Up @@ -206,7 +208,7 @@ Package-specific changes not released in any SDK will be added here just before
- Added `bounds` property to the `BarCodeScanningResult`. ([#19519](https://github.com/expo/expo/pull/19519) by [@lukmccall](https://github.com/lukmccall))
- **`expo-constants`**
- Deprecated the unreliable `source-login-scripts.sh` and sourcing the Node.js binary path from `.xcode.env` and `.xcode.env.local`. ([#18330](https://github.com/expo/expo/pull/18330) by [@kudo](https://github.com/kudo))
- Fixed *with-node.sh* doesn't keep quotes when passing arguments to Node.js and caused build errors when there are spaces in target name. ([#18741](https://github.com/expo/expo/pull/18741) by [@kudo](https://github.com/kudo))
- Fixed _with-node.sh_ doesn't keep quotes when passing arguments to Node.js and caused build errors when there are spaces in target name. ([#18741](https://github.com/expo/expo/pull/18741) by [@kudo](https://github.com/kudo))
- **`expo-cellular`**
- Added missing permissions requester. ([#19633](https://github.com/expo/expo/pull/19633) by [@lukmccall](https://github.com/lukmccall))
- **`expo-device`**
Expand Down
Expand Up @@ -27,25 +27,33 @@ def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

static def findNodeModulePath(baseDir, packageName) {
def basePath = baseDir.toPath().normalize()
// Node's module resolution algorithm searches up to the root directory,
// after which the base path will be null
while (basePath) {
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
if (candidatePath.toFile().exists()) {
return candidatePath.toString()
}
basePath = basePath.getParent()
}
return null
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

def findNodeModulePath(packageName) {
// Don't start in the project dir, as its path ends with node_modules/react-native-gesture-handler/android
// we want to go two levels up, so we end up in the first_node modules and eventually
// search upwards if the package is not found there
return findNodeModulePath(projectDir.toPath().parent.parent.toFile(), packageName)
def resolveReactNativeDirectory() {
def reactNativeLocation = safeExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
if (reactNativeLocation != null) {
return file(reactNativeLocation)
}

// monorepo workaround
// react-native can be hoisted or in project's own node_modules
def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native")
if (reactNativeFromProjectNodeModules.exists()) {
return reactNativeFromProjectNodeModules
}

def reactNativeFromNodeModulesWithReanimated = file("${projectDir}/../../react-native")
if (reactNativeFromNodeModulesWithReanimated.exists()) {
return reactNativeFromNodeModulesWithReanimated
}

throw new Exception(
"[react-native-gesture-handler] Unable to resolve react-native location in " +
"node_modules. You should add project extension property (in app/build.gradle) " +
"`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
)
}

if (isNewArchitectureEnabled()) {
Expand All @@ -58,10 +66,6 @@ if (project == rootProject) {
apply from: "spotless.gradle"
}

def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

// Check whether Reanimated 2.3 or higher is installed alongside Gesture Handler
def shouldUseCommonInterfaceFromReanimated() {
return true
Expand Down Expand Up @@ -95,6 +99,7 @@ def noMultipleInstancesAssertion() {
Set<File> files = fileTree(rootDir.parent) {
include "node_modules/**/react-native-gesture-handler/package.json"
exclude "**/.yarn/**"
exclude "**/.pnpm/**"
}.files

if (files.size() > 1) {
Expand All @@ -104,7 +109,13 @@ def noMultipleInstancesAssertion() {
}
}

def REACT_NATIVE_DIR = findNodeModulePath("react-native")
def REACT_NATIVE_DIR = resolveReactNativeDirectory()

def reactProperties = new Properties()
file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }

def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger()

def assertionTask = task assertNoMultipleInstances {
onlyIf { shouldAssertNoMultipleInstances() }
Expand Down Expand Up @@ -133,17 +144,25 @@ android {
ndkVersion rootProject.ext.ndkVersion
}

if (REACT_NATIVE_MINOR_VERSION >= 71) {
buildFeatures {
prefab true
}
}

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
versionCode 1
versionName "1.0"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
buildConfigField "int", "REACT_NATIVE_MINOR_VERSION", REACT_NATIVE_MINOR_VERSION.toString()

if (isNewArchitectureEnabled()) {
var appProject = rootProject.allprojects.find {it.plugins.hasPlugin('com.android.application')}
externalNativeBuild {
cmake {
cppFlags "-O2 -frtti -fexceptions -Wall -Wno-unused-variable -fstack-protector-all"
cppFlags "-O2", "-frtti", "-fexceptions", "-Wall", "-Werror", "-std=c++17"
arguments "-DAPP_BUILD_DIR=${appProject.buildDir}",
"-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
"-DANDROID_STL=c++_shared"
Expand Down Expand Up @@ -200,10 +219,10 @@ def kotlin_version = safeExtGet('kotlinVersion', project.properties['RNGH_kotlin

dependencies {
//noinspection GradleDynamicVersion
if (isNewArchitectureEnabled()) {
implementation project(':ReactAndroid')
if (REACT_NATIVE_MINOR_VERSION >= 71) {
implementation "com.facebook.react:react-android" // version substituted by RNGP
} else {
implementation 'com.facebook.react:react-native:+'
implementation 'com.facebook.react:react-native:+' // from node_modules
}

if (shouldUseCommonInterfaceFromReanimated()) {
Expand All @@ -217,20 +236,3 @@ dependencies {
implementation "androidx.core:core-ktx:1.6.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

if (isNewArchitectureEnabled()) {
// Resolves "LOCAL_SRC_FILES points to a missing file, Check that libfb.so exists or that its path is correct".
tasks.whenTaskAdded { task ->
if (task.name.contains("configureCMakeDebug")) {
rootProject.getTasksByName("packageReactNdkDebugLibs", true).forEach {
task.dependsOn(it)
}
}
// We want to add a dependency for both configureCMakeRelease and configureCMakeRelWithDebInfo
if (task.name.contains("configureCMakeRel")) {
rootProject.getTasksByName("packageReactNdkReleaseLibs", true).forEach {
task.dependsOn(it)
}
}
}
}
Expand Up @@ -331,6 +331,7 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager<ButtonViewGroup>(), R
// don't preform click when a child button is pressed (mainly to prevent sound effect of
// a parent button from playing)
return if (!isChildTouched() && soundResponder == this) {
tryFreeingResponder()
soundResponder = null
super.performClick()
} else {
Expand Down
Expand Up @@ -16,21 +16,31 @@ import com.swmansion.gesturehandler.core.GestureHandler
class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>() {
private var extraData: WritableMap? = null
private var coalescingKey: Short = 0

// On the new architecture, native animated expects event names prefixed with `top` instead of `on`,
// since we know when the native animated node is the target of the event we can use the different
// event name where appropriate.
// TODO: This is a workaround not as solution, but doing this properly would require a total overhaul of
// how GH sends events (which needs to be done, but maybe wait until the RN's apis stop changing)
private var useTopPrefixedName: Boolean = false

private fun <T : GestureHandler<T>> init(
handler: T,
dataExtractor: RNGestureHandlerEventDataExtractor<T>?,
useNativeAnimatedName: Boolean
) {
super.init(handler.view!!.id)
extraData = createEventData(handler, dataExtractor)
coalescingKey = handler.eventCoalescingKey
this.useTopPrefixedName = useNativeAnimatedName
}

override fun onDispose() {
extraData = null
EVENTS_POOL.release(this)
}

override fun getEventName() = EVENT_NAME
override fun getEventName() = if (useTopPrefixedName) NATIVE_ANIMATED_EVENT_NAME else EVENT_NAME

override fun canCoalesce() = true

Expand All @@ -42,15 +52,17 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>

companion object {
const val EVENT_NAME = "onGestureHandlerEvent"
const val NATIVE_ANIMATED_EVENT_NAME = "topGestureHandlerEvent"
private const val TOUCH_EVENTS_POOL_SIZE = 7 // magic
private val EVENTS_POOL = Pools.SynchronizedPool<RNGestureHandlerEvent>(TOUCH_EVENTS_POOL_SIZE)

fun <T : GestureHandler<T>> obtain(
handler: T,
dataExtractor: RNGestureHandlerEventDataExtractor<T>?,
useTopPrefixedName: Boolean = false
): RNGestureHandlerEvent =
(EVENTS_POOL.acquire() ?: RNGestureHandlerEvent()).apply {
init(handler, dataExtractor)
init(handler, dataExtractor, useTopPrefixedName)
}

fun <T : GestureHandler<T>> createEventData(
Expand Down
Expand Up @@ -538,7 +538,11 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
sendEventForReanimated(event)
} else if (handler.actionType == GestureHandler.ACTION_TYPE_NATIVE_ANIMATED_EVENT) {
// Animated with useNativeDriver: true
val event = RNGestureHandlerEvent.obtain(handler, handlerFactory)
val event = RNGestureHandlerEvent.obtain(
handler,
handlerFactory,
useTopPrefixedName = BuildConfig.REACT_NATIVE_MINOR_VERSION >= 71
)
sendEventForNativeAnimatedEvent(event)
} else if (handler.actionType == GestureHandler.ACTION_TYPE_JS_FUNCTION_OLD_API) {
// JS function, Animated.event with useNativeDriver: false using old API
Expand Down
Expand Up @@ -3,57 +3,23 @@ cmake_minimum_required(VERSION 3.9.0)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DFOLLY_HAVE_RECVMMSG=1 -DFOLLY_HAVE_PTHREAD=1")

set(REACT_ANDROID_DIR "${REACT_NATIVE_DIR}/ReactAndroid")

include(${REACT_ANDROID_DIR}/cmake-utils/folly-flags.cmake)
add_compile_options(${folly_FLAGS})

add_library(gesturehandler
SHARED
cpp-adapter.cpp
)

set(REACT_ANDROID_DIR "${REACT_NATIVE_DIR}/ReactAndroid")
set(REACT_COMMON_DIR "${REACT_NATIVE_DIR}/ReactCommon")
set(REACT_NDK_EXPORT_DIR "${APP_BUILD_DIR}/react-ndk/exported")

# copied from react-native/ReactAndroid/cmake-utils/Android-prebuilt.cmake

## jsi
add_library(jsi SHARED IMPORTED GLOBAL)
set_target_properties(jsi
PROPERTIES
IMPORTED_LOCATION
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libjsi.so)
target_include_directories(jsi INTERFACE ${REACT_COMMON_DIR}/jsi)

## react_render_core
add_library(react_render_core SHARED IMPORTED GLOBAL)
set_target_properties(react_render_core
PROPERTIES
IMPORTED_LOCATION
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_render_core.so)
target_include_directories(react_render_core
INTERFACE
${REACT_COMMON_DIR}
${REACT_COMMON_DIR}/react/renderer/core)

## react_render_uimanager
add_library(react_render_uimanager SHARED IMPORTED GLOBAL)
set_target_properties(react_render_uimanager
PROPERTIES
IMPORTED_LOCATION
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_render_uimanager.so)
target_include_directories(react_render_uimanager INTERFACE ${REACT_COMMON_DIR}/react/renderer/uimanager)

target_include_directories(
gesturehandler
PRIVATE
"${REACT_ANDROID_DIR}/build/third-party-ndk/boost/boost_1_76_0"
"${REACT_ANDROID_DIR}/build/third-party-ndk/double-conversion"
"${REACT_ANDROID_DIR}/build/third-party-ndk/folly"
)
find_package(ReactAndroid REQUIRED CONFIG)

target_link_libraries(
gesturehandler
jsi
react_render_uimanager
react_render_core
ReactAndroid::react_render_core
ReactAndroid::react_render_uimanager
ReactAndroid::jsi
ReactAndroid::react_nativemodule_core
)
Expand Up @@ -6,36 +6,39 @@
using namespace facebook;
using namespace react;

void decorateRuntime(jsi::Runtime &runtime)
{
void decorateRuntime(jsi::Runtime &runtime) {
auto isFormsStackingContext = jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "isFormsStackingContext"),
1,
[](jsi::Runtime &runtime,
const jsi::Value &thisValue,
const jsi::Value *arguments,
size_t count) -> jsi::Value
{
if (!arguments[0].isObject())
{
size_t count) -> jsi::Value {
if (!arguments[0].isObject()) {
return jsi::Value::null();
}

auto shadowNode = arguments[0].asObject(runtime).getHostObject<ShadowNodeWrapper>(runtime)->shadowNode;
bool isFormsStackingContext = shadowNode->getTraits().check(ShadowNodeTraits::FormsStackingContext);
auto shadowNode = arguments[0]
.asObject(runtime)
.getHostObject<ShadowNodeWrapper>(runtime)
->shadowNode;
bool isFormsStackingContext = shadowNode->getTraits().check(
ShadowNodeTraits::FormsStackingContext);

return jsi::Value(isFormsStackingContext);
});
runtime.global().setProperty(runtime, "isFormsStackingContext", std::move(isFormsStackingContext));
runtime.global().setProperty(
runtime, "isFormsStackingContext", std::move(isFormsStackingContext));
}

extern "C" JNIEXPORT void JNICALL
Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime(JNIEnv *env, jobject clazz, jlong jsiPtr)
{
Java_com_swmansion_gesturehandler_react_RNGestureHandlerModule_decorateRuntime(
JNIEnv *env,
jobject clazz,
jlong jsiPtr) {
jsi::Runtime *runtime = reinterpret_cast<jsi::Runtime *>(jsiPtr);
if (runtime)
{
if (runtime) {
decorateRuntime(*runtime);
}
}
Expand Up @@ -103,11 +103,7 @@ repositories {
}

dependencies {
if (isNewArchitectureEnabled()) {
implementation project(":ReactAndroid")
} else {
implementation 'com.facebook.react:react-native:+'
}
implementation 'com.facebook.react:react-native:+'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.fragment:fragment:1.2.1'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
Expand Down
Expand Up @@ -156,6 +156,16 @@ class ScreenViewManager : ViewGroupManager<Screen>(), 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<String, Any> {
return MapBuilder.of(
ScreenDismissedEvent.EVENT_NAME,
Expand Down

0 comments on commit 2ce5517

Please sign in to comment.