Skip to content

New arch support #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ DerivedData
*.hmap
*.ipa
*.xcuserstate
.xcode.env.local
**/.xcode.env.local

# Android/IntelliJ
#
Expand Down Expand Up @@ -48,11 +48,22 @@ yarn-error.log
*.jsbundle

# Ruby / CocoaPods
example/ios/Pods/
example/vendor/bundle/
**/Pods/
**/vendor/bundle/

# Bob
dist/

# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

# testing
/coverage

# Yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
10 changes: 8 additions & 2 deletions RNSwanBrowser.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
s.name = "RNSwanBrowser"
s.dependency "React-Core"

s.version = package["version"]
s.license = package["license"]
Expand All @@ -16,5 +15,12 @@ Pod::Spec.new do |s|
s.requires_arc = true

s.source = { :git => package["repository"]["url"], :tag => s.version }
s.source_files = "ios/*.{h,m}"
s.source_files = "ios/**/*.{h,m,mm}"
s.frameworks = "SafariServices"

if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
install_modules_dependencies(s)
else
s.dependency "React-Core"
end
end
18 changes: 18 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ buildscript {
}
}

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

apply plugin: "com.android.library"

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

android {
buildToolsVersion safeExtGet("buildToolsVersion", "33.0.0")
compileSdkVersion safeExtGet("compileSdkVersion", 33)
Expand All @@ -30,12 +38,22 @@ android {
}
}
defaultConfig {
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString())
minSdkVersion safeExtGet("minSdkVersion", 21)
targetSdkVersion safeExtGet("targetSdkVersion", 33)
}
lintOptions {
abortOnError false
}
sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += ["src/newarch"]
} else {
java.srcDirs += ["src/oldarch"]
}
}
}
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,32 @@
import android.net.Uri;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.browser.customtabs.CustomTabColorSchemeParams;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.graphics.ColorUtils;

import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;

import io.swan.rnbrowser.helpers.CustomTabActivityHelper;

@ReactModule(name = RNSwanBrowserModule.NAME)
public class RNSwanBrowserModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
public class RNSwanBrowserModuleImpl {

static final String NAME = "RNSwanBrowser";
private boolean mBrowserVisible = false;

public RNSwanBrowserModule(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addLifecycleEventListener(this);
}

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

@Override
public void onHostResume() {
ReactApplicationContext reactContext = getReactApplicationContext();

if (mBrowserVisible && reactContext.hasActiveReactInstance()) {
protected static void onHostResume(final ReactApplicationContext reactContext) {
if (reactContext.hasActiveReactInstance()) {
reactContext
.getJSModule(RCTDeviceEventEmitter.class)
.emit("swanBrowserDidClose", null);
}

mBrowserVisible = false;
}

@Override
public void onHostPause() {}

@Override
public void onHostDestroy() {}

@ReactMethod
public void open(final String url, final ReadableMap options, final Promise promise) {
if (mBrowserVisible) {
promise.reject("swan_browser_visible",
"An instance of the swan browser is already visible");
}

final Activity activity = getCurrentActivity();

if (activity == null) {
promise.reject("no_current_activity",
"Couldn't call open() when the app is in background");
return;
}

mBrowserVisible = true;

protected static void open(final Activity activity,
final String url,
final Double barTintColor,
final Promise promise) {
CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder();
intentBuilder.setShowTitle(false);
intentBuilder.setInstantAppsEnabled(false);
Expand All @@ -87,13 +44,13 @@ public void open(final String url, final ReadableMap options, final Promise prom
CustomTabColorSchemeParams.Builder paramsBuilder = new CustomTabColorSchemeParams.Builder();
paramsBuilder.setNavigationBarColor(blackColor);

if (options.hasKey("barTintColor")) {
@ColorInt int barTintColor = options.getInt("barTintColor");
if (barTintColor != null) {
@ColorInt int intValue = barTintColor.intValue();

paramsBuilder.setToolbarColor(barTintColor);
paramsBuilder.setSecondaryToolbarColor(barTintColor);
paramsBuilder.setToolbarColor(intValue);
paramsBuilder.setSecondaryToolbarColor(intValue);

intentBuilder.setColorScheme(ColorUtils.calculateLuminance(barTintColor) > 0.5
intentBuilder.setColorScheme(ColorUtils.calculateLuminance(intValue) > 0.5
? CustomTabsIntent.COLOR_SCHEME_LIGHT
: CustomTabsIntent.COLOR_SCHEME_DARK);
}
Expand All @@ -114,19 +71,4 @@ public void openUri(Activity activity, Uri uri) {

promise.resolve(null);
}

@ReactMethod
public void close() {
// noop on Android since the modal is closed by deep-link
}

@ReactMethod
public void addListener(String eventName) {
// Set up any upstream listeners or background tasks as necessary
}

@ReactMethod
public void removeListeners(Integer count) {
// Remove upstream listeners, stop unnecessary background tasks
}
}
41 changes: 30 additions & 11 deletions android/src/main/java/io/swan/rnbrowser/RNSwanBrowserPackage.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
package io.swan.rnbrowser;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

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

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

public class RNSwanBrowserPackage implements ReactPackage {
public class RNSwanBrowserPackage extends TurboReactPackage {

@NonNull
@Nullable
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
return Collections.singletonList(new RNSwanBrowserModule(reactContext));
public NativeModule getModule(String name, @NonNull ReactApplicationContext reactContext) {
if (name.equals(RNSwanBrowserModuleImpl.NAME)) {
return new RNSwanBrowserModule(reactContext);
} else {
return null;
}
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return () -> {
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();

ReactModuleInfo moduleInfo = new ReactModuleInfo(
RNSwanBrowserModuleImpl.NAME,
RNSwanBrowserModuleImpl.NAME,
false,
false,
false,
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
);

moduleInfos.put(RNSwanBrowserModuleImpl.NAME, moduleInfo);
return moduleInfos;
};
}
}
87 changes: 87 additions & 0 deletions android/src/newarch/io/swan/rnbrowser/RNSwanBrowserModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.swan.rnbrowser;

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.annotations.ReactModule;

@ReactModule(name = RNSwanBrowserModuleImpl.NAME)
public class RNSwanBrowserModule extends NativeRNSwanBrowserSpec implements LifecycleEventListener {

private boolean mBrowserVisible = false;

public RNSwanBrowserModule(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addLifecycleEventListener(this);
}

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

@Override
public void onHostResume() {
if (mBrowserVisible) {
RNSwanBrowserModuleImpl.onHostResume(getReactApplicationContext());
mBrowserVisible = false;
}
}

@Override
public void onHostPause() {}

@Override
public void onHostDestroy() {}

@Override
public void open(String url,
@Nullable String dismissButtonStyle,
@Nullable Double barTintColor,
@Nullable Double controlTintColor,
Promise promise) {
if (mBrowserVisible) {
promise.reject("swan_browser_visible",
"An instance of the swan browser is already visible");
return;
}

final Activity activity = getReactApplicationContext().getCurrentActivity();

if (activity == null) {
promise.reject("no_current_activity",
"Couldn't call open() when the app is in background");
return;
}

mBrowserVisible = true;
RNSwanBrowserModuleImpl.open(activity, url, barTintColor, promise);
}

@Override
public void close() {
// noop on Android since the modal is closed by deep-link
}

@Override
public void addListener(String eventName) {
// iOS only
}

@Override
public void removeListeners(double count) {
// iOS only
}

@Override
public void invalidate() {
super.invalidate();
getReactApplicationContext().removeLifecycleEventListener(this);
}
}
Loading