diff --git a/RNSVG.podspec b/RNSVG.podspec index 0d0aafa06..6f3abc336 100644 --- a/RNSVG.podspec +++ b/RNSVG.podspec @@ -1,6 +1,8 @@ require 'json' +require_relative './scripts/rnsvg_utils' package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) +svgConfig = rnsvg_find_config() fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1' @@ -25,6 +27,9 @@ Pod::Spec.new do |s| s.tvos.resource_bundles = {'RNSVGFilters' => ['apple/**/*.appletvos.metallib']} s.visionos.resource_bundles = {'RNSVGFilters' => ['apple/**/*.xros.metallib']} + s.xcconfig = { + "OTHER_CFLAGS" => "$(inherited) -DREACT_NATIVE_MINOR_VERSION=#{svgConfig[:react_native_minor_version]}", + } if fabric_enabled install_modules_dependencies(s) diff --git a/android/build.gradle b/android/build.gradle index 330c2a82a..d6d618d75 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -52,13 +52,12 @@ def resolveReactNativeDirectory() { throw new GradleException("[react-native-svg] Unable to resolve react-native location in node_modules. Your app should define `REACT_NATIVE_NODE_MODULES_DIR` extension property in `app/build.gradle` with a path to react-native in node_modules.") } -def getReactNativeMinorVersion() { - def reactNativeRootDir = resolveReactNativeDirectory() - def reactNativeProperties = new Properties() - file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactNativeProperties.load(it) } - def reactNativeVersion = reactNativeProperties.getProperty("VERSION_NAME") - return reactNativeVersion.split("\\.")[1].toInteger() -} +def reactNativeRootDir = resolveReactNativeDirectory() +def reactNativeProperties = new Properties() +file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactNativeProperties.load(it) } + +def REACT_NATIVE_VERSION = reactNativeProperties.getProperty("VERSION_NAME") +def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger() def getFrescoVersion() { def reactNativeRootDir = resolveReactNativeDirectory() @@ -78,6 +77,7 @@ def getFrescoVersion() { } return frescoVersion } +def FRESCO_VERSION = getFrescoVersion() android { compileSdkVersion safeExtGet('compileSdkVersion', 28) @@ -106,6 +106,13 @@ android { buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() consumerProguardFiles 'proguard-rules.pro' + + buildConfigField("String", "REACT_NATIVE_MINOR_VERSION", "\"${REACT_NATIVE_MINOR_VERSION}\"") + externalNativeBuild { + cmake { + arguments "-DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}" + } + } } lintOptions { abortOnError false @@ -119,7 +126,7 @@ android { ] } - if (getReactNativeMinorVersion() >= 75) { // Use for react-native@0.75 and above + if (REACT_NATIVE_MINOR_VERSION >= 75) { // Use for react-native@0.75 and above // borderRadius fix https://github.com/software-mansion/react-native-svg/pull/2415 srcDirs += "src/SvgViewManager75/java" // processTransform replacement https://github.com/software-mansion/react-native-svg/pull/2554 @@ -129,7 +136,7 @@ android { srcDirs += "src/RenderableViewManager73/java" } - if (getReactNativeMinorVersion() >= 74) { // Use for react-native@0.74 and above + if (REACT_NATIVE_MINOR_VERSION >= 74) { // Use for react-native@0.74 and above // new API https://github.com/software-mansion/react-native-svg/pull/2541 srcDirs += "src/SvgPackage74/java" } else { @@ -152,14 +159,13 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' - if (getReactNativeMinorVersion() >= 76) { - def frescoVersion = getFrescoVersion() - implementation("com.facebook.fresco:fresco:${frescoVersion}") { + if (REACT_NATIVE_MINOR_VERSION >= 76) { + implementation("com.facebook.fresco:fresco:${FRESCO_VERSION}") { exclude group: 'com.facebook.soloader' } - implementation("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}") { + implementation("com.facebook.fresco:imagepipeline-okhttp3:${FRESCO_VERSION}") { exclude group: 'com.facebook.soloader' } - implementation("com.facebook.fresco:middleware:${frescoVersion}") + implementation("com.facebook.fresco:middleware:${FRESCO_VERSION}") } } diff --git a/android/src/main/jni/CMakeLists.txt b/android/src/main/jni/CMakeLists.txt index 741483e99..1966dd147 100644 --- a/android/src/main/jni/CMakeLists.txt +++ b/android/src/main/jni/CMakeLists.txt @@ -7,6 +7,11 @@ set(RNS_GENERATED_DIR ${RNS_ANDROID_DIR}/build/generated) set(RNS_GENERATED_JNI_DIR ${RNS_GENERATED_DIR}/source/codegen/jni) set(RNS_GENERATED_REACT_DIR ${RNS_GENERATED_JNI_DIR}/react/renderer/components/rnsvg) +string( + APPEND + CMAKE_CXX_FLAGS + " -DREACT_NATIVE_MINOR_VERSION=321${REACT_NATIVE_MINOR_VERSION}") + add_compile_options( -fexceptions -frtti diff --git a/apps/fabric-example/ios/Podfile.lock b/apps/fabric-example/ios/Podfile.lock index fccf4c7fd..0680ea471 100644 --- a/apps/fabric-example/ios/Podfile.lock +++ b/apps/fabric-example/ios/Podfile.lock @@ -1751,7 +1751,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNSVG (15.10.0): + - RNSVG (15.10.1): - DoubleConversion - glog - hermes-engine @@ -1771,9 +1771,9 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNSVG/common (= 15.10.0) + - RNSVG/common (= 15.10.1) - Yoga - - RNSVG/common (15.10.0): + - RNSVG/common (15.10.1): - DoubleConversion - glog - hermes-engine @@ -2087,7 +2087,7 @@ SPEC CHECKSUMS: RNGestureHandler: fc5ce5bf284640d3af6431c3a5c3bc121e98d045 RNReanimated: 77242c6d67416988a2fd9f5cf574bb3e60016362 RNScreens: e389d6a6a66a4f0d3662924ecae803073ccce8ec - RNSVG: 0ac7301275469a63da5178fad6930833012c5a7c + RNSVG: 39d6700bf81b883cf5049760bca48208b860f996 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: f8ec45ce98bba1bc93dd28f2ee37215180e6d2b6 diff --git a/apps/tests-example/ios/Podfile.lock b/apps/tests-example/ios/Podfile.lock index 60117f9c8..d84ee785b 100644 --- a/apps/tests-example/ios/Podfile.lock +++ b/apps/tests-example/ios/Podfile.lock @@ -1823,7 +1823,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: fc917756e3e18f7d1c8835f86f789ba6565e01f0 ReactCodegen: 31c5d427c89af11beaad701feb8adbbd1dd3ac48 ReactCommon: 4baee138fa471f1681dd507c2fe3ca3530d8526d - RNSVG: 08393d7acf082eb96635e3d026928d0503a94d95 + RNSVG: b744d9814d61a647810e9ce4c0217ac335b3bf6a SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 Yoga: d2b20c8f141d4d00e975ef4db8d8613399cf008f diff --git a/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp b/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp index ab45296e1..a42fde95c 100644 --- a/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp +++ b/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.cpp @@ -8,27 +8,29 @@ RNSVGLayoutableShadowNode::RNSVGLayoutableShadowNode( const ShadowNodeFamily::Shared &family, ShadowNodeTraits traits) : YogaLayoutableShadowNode(fragment, family, traits) { - // SVG handles its layout manually on the native side and does not depend on - // the Yoga layout. Setting the dimensions to 0 eliminates randomly positioned - // views in the layout inspector when Yoga attempts to interpret SVG - // properties like width when viewBox scale is set. - auto style = yogaNode_.style(); - style.setDimension(yoga::Dimension::Width, yoga::value::points(0)); - style.setDimension(yoga::Dimension::Height, yoga::value::points(0)); - yogaNode_.setStyle(style); + setZeroDimensions(); } RNSVGLayoutableShadowNode::RNSVGLayoutableShadowNode( const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment) : YogaLayoutableShadowNode(sourceShadowNode, fragment) { + setZeroDimensions(); +} + +void RNSVGLayoutableShadowNode::setZeroDimensions() { // SVG handles its layout manually on the native side and does not depend on // the Yoga layout. Setting the dimensions to 0 eliminates randomly positioned // views in the layout inspector when Yoga attempts to interpret SVG // properties like width when viewBox scale is set. auto style = yogaNode_.style(); +#if REACT_NATIVE_MINOR_VERSION >= 77 + style.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(0)); + style.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(0)); +#else style.setDimension(yoga::Dimension::Width, yoga::value::points(0)); style.setDimension(yoga::Dimension::Height, yoga::value::points(0)); +#endif yogaNode_.setStyle(style); } diff --git a/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.h b/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.h index 968b1bff1..c93c3c1eb 100644 --- a/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.h +++ b/common/cpp/react/renderer/components/rnsvg/RNSVGLayoutableShadowNode.h @@ -14,6 +14,9 @@ class RNSVGLayoutableShadowNode : public YogaLayoutableShadowNode { const ShadowNodeFragment &fragment); void layout(LayoutContext layoutContext) override; + + private: + void setZeroDimensions(); }; } // namespace facebook::react diff --git a/scripts/rnsvg_utils.rb b/scripts/rnsvg_utils.rb new file mode 100644 index 000000000..54ec0325c --- /dev/null +++ b/scripts/rnsvg_utils.rb @@ -0,0 +1,38 @@ +# Copied from Reanimated https://github.com/software-mansion/react-native-reanimated/blob/c6d68151644056476518241b0087b1ed900b39b6/packages/react-native-reanimated/scripts/reanimated_utils.rb +def rnsvg_try_to_parse_react_native_package_json(node_modules_dir) + react_native_package_json_path = File.join(node_modules_dir, 'react-native/package.json') + if !File.exist?(react_native_package_json_path) + return nil + end + return JSON.parse(File.read(react_native_package_json_path)) +end + +def rnsvg_find_config() + result = { + :react_native_version => nil, + :react_native_minor_version => nil, + :react_native_node_modules_dir => nil, + } + + react_native_node_modules_dir = File.join(File.dirname(`cd "#{Pod::Config.instance.installation_root.to_s}" && node --print "require.resolve('react-native/package.json')"`), '..') + react_native_json = rnsvg_try_to_parse_react_native_package_json(react_native_node_modules_dir) + + if react_native_json == nil + # user configuration, just in case + node_modules_dir = ENV["REACT_NATIVE_NODE_MODULES_DIR"] + react_native_json = rnsvg_try_to_parse_react_native_package_json(node_modules_dir) + end + + if react_native_json == nil + raise '[RNSVG] Unable to recognize your `react-native` version. Please set environmental variable with `react-native` location: `export REACT_NATIVE_NODE_MODULES_DIR="" && pod install`.' + end + + result[:react_native_version] = react_native_json['version'] + result[:react_native_minor_version] = react_native_json['version'].split('.')[1].to_i + if result[:react_native_minor_version] == 0 # nightly + result[:react_native_minor_version] = 1000 + end + result[:react_native_node_modules_dir] = File.expand_path(react_native_node_modules_dir) + + return result +end