Skip to content

Commit

Permalink
feat(#162): fabric support (#221)
Browse files Browse the repository at this point in the history
* feat(#162): fabric support

- add JS Flow spec
- make android viewmanager to conform to codegen-ed specs
- make android viewmanager extend ReactViewManager instead of ViewGroupManager
- add codegen-ed spec to make viewmanager work also in old arch
- use install_module_dependencies in the podspec to install deps on both new and old architectures
- add subclass of RCTViewComponentView
- use fabric implementation when RCT_NEW_ARCH_ENABLED flag is true
- set RN peerDependency to be version >= 0.71

* feat(#162): bump RNTA to v3, bump RN to v0.73, add pointerEvents example
  • Loading branch information
mateusz1913 authored Apr 1, 2024
1 parent 40ff01d commit b5dc9d0
Show file tree
Hide file tree
Showing 33 changed files with 3,770 additions and 2,359 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
extends: ['@react-native-community'],
extends: '@react-native',
};
4 changes: 2 additions & 2 deletions RNCMaskedView.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.platforms = { :ios => "9.0", :tvos => "9.0" }

s.source = { :git => "https://github.com/react-native-masked-view/masked-view.git", :tag => "v#{s.version}" }
s.source_files = "ios/**/*.{h,m}"
s.source_files = "ios/**/*.{h,m,mm}"

s.dependency 'React-Core'
install_modules_dependencies(s)
end
20 changes: 16 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ buildscript {
}
}

def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

apply plugin: 'com.android.library'
if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}

def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
def shouldUseNameSpace = agpVersion >= 7
Expand All @@ -39,20 +46,25 @@ manifestContent.replaceAll(" ", " ")
manifestOutFile.write(manifestContent)

android {
compileSdkVersion safeExtGet('compileSdkVersion', 28)
compileSdkVersion safeExtGet('compileSdkVersion', 33)

if(shouldUseNameSpace){
namespace = "org.reactnative.maskedview"
}

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
minSdkVersion safeExtGet('minSdkVersion', 21)
targetSdkVersion safeExtGet('targetSdkVersion', 33)
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}

sourceSets {
main {
java.srcDirs = ['src/main/java']
if (isNewArchitectureEnabled()) {
java.srcDirs += ['src/newarch/java', "${project.buildDir}/generated/source/codegen/java"]
} else {
java.srcDirs += ['src/oldarch/java']
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@
import android.graphics.PorterDuffXfermode;
import android.view.View;

import androidx.annotation.NonNull;

import com.facebook.react.views.view.ReactViewGroup;

public class RNCMaskedView extends ReactViewGroup {
private static final String TAG = "RNCMaskedView";

private Bitmap mBitmapMask = null;
private boolean mBitmapMaskInvalidated = false;
private Paint mPaint;
private PorterDuffXfermode mPorterDuffXferMode;
private final Paint mPaint;
private final PorterDuffXfermode mPorterDuffXferMode;

public RNCMaskedView(Context context) {
super(context);
Expand Down Expand Up @@ -48,7 +50,7 @@ protected void dispatchDraw(Canvas canvas) {
}

@Override
public void onDescendantInvalidated(View child, View target) {
public void onDescendantInvalidated(@NonNull View child, @NonNull View target) {
super.onDescendantInvalidated(child, target);

if (!mBitmapMaskInvalidated) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
package org.reactnative.maskedview;

import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.viewmanagers.RNCMaskedViewManagerInterface;
import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.views.view.ReactViewManager;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class RNCMaskedViewManager extends ViewGroupManager<RNCMaskedView> {
public class RNCMaskedViewManager extends ReactViewManager implements RNCMaskedViewManagerInterface<RNCMaskedView> {
private static final String REACT_CLASS = "RNCMaskedView";

@NonNull
@Override
public String getName() {
return REACT_CLASS;
}

@Override
protected RNCMaskedView createViewInstance(ThemedReactContext themedReactContext) {
public ViewManagerDelegate<ReactViewGroup> getDelegate() {
// ReactViewManager is not generic, so it doesn't let to pass any view, that extends ReactViewGroup
// However, ReactViewManager does not use any delegate, so we can skip it and handle props here
return null;
}

@NonNull
@Override
public RNCMaskedView createViewInstance(ThemedReactContext themedReactContext) {
return new RNCMaskedView(themedReactContext);
}

@Override
@ReactProp(name = "androidRenderingMode")
public void setAndroidRenderingMode(RNCMaskedView view, @Nullable String renderingMode) {
if (renderingMode != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
package org.reactnative.maskedview;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import androidx.annotation.Nullable;

import com.facebook.react.TurboReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.uimanager.ViewManager;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RNCMaskedViewPackage extends TurboReactPackage {
@Override
@Nullable
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
return null;
}

public class RNCMaskedViewPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
return Collections.emptyList();
public ReactModuleInfoProvider getReactModuleInfoProvider() {
final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
return new ReactModuleInfoProvider() {
@Override
public Map<String, ReactModuleInfo> getReactModuleInfos() {
return reactModuleInfoMap;
}
};
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
return Arrays.<ViewManager>asList(
new RNCMaskedViewManager()
);
return Arrays.<ViewManager>asList(
new RNCMaskedViewManager()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;

public class RNCMaskedViewManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & RNCMaskedViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public RNCMaskedViewManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case "androidRenderingMode":
mViewManager.setAndroidRenderingMode(view, (String) value);
break;
default:
super.setProperty(view, propName, value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;
import androidx.annotation.Nullable;

public interface RNCMaskedViewManagerInterface<T extends View> {
void setAndroidRenderingMode(T view, @Nullable String value);
}
3 changes: 2 additions & 1 deletion example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
.xcode.env
Pods/
build/
dist/
dist/*
!dist/.gitignore
local.properties
msbuild.binlog
node_modules/
23 changes: 20 additions & 3 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
buildscript {
def androidTestAppDir = "../node_modules/react-native-test-app/android"
apply(from: "${androidTestAppDir}/dependencies.gradle")
apply(from: {
def searchDir = rootDir.toPath()
do {
def p = searchDir.resolve("node_modules/react-native-test-app/android/dependencies.gradle")
if (p.toFile().exists()) {
return p.toRealPath().toString()
}
} while (searchDir = searchDir.getParent())
throw new GradleException("Could not find `react-native-test-app`");
}())

repositories {
mavenCentral()
Expand All @@ -18,7 +26,16 @@ allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("${rootDir}/../node_modules/react-native/android")
url({
def searchDir = rootDir.toPath()
do {
def p = searchDir.resolve("node_modules/react-native/android")
if (p.toFile().exists()) {
return p.toRealPath().toString()
}
} while (searchDir = searchDir.getParent())
throw new GradleException("Could not find `react-native`");
}())
}
mavenCentral()
google()
Expand Down
31 changes: 19 additions & 12 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,27 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryEr
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true

# Version of Flipper to use with React Native. Default value is whatever React
# Native defaults to. To disable Flipper, set it to `false`.
#FLIPPER_VERSION=0.182.0

# Enable Fabric at runtime.
#USE_FABRIC=1

# Enable new architecture, i.e. Fabric + TurboModule - implies USE_FABRIC=1.
# Jetifier randomly fails on these libraries
android.jetifier.ignorelist=hermes-android

# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64

# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
# Note that this is incompatible with web debugging.
#newArchEnabled=true

# Uncomment the line below if building react-native from source
#ANDROID_NDK_VERSION=23.1.7779620
# Uncomment the line below to build React Native from source.
#react.buildFromSource=true

# Version of Android NDK to build against.
#ANDROID_NDK_VERSION=26.1.10909125

# Version of Kotlin to build against.
#KOTLIN_VERSION=1.7.22
#KOTLIN_VERSION=1.8.22
Binary file modified example/android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
3 changes: 2 additions & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit b5dc9d0

Please sign in to comment.