Skip to content
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
43 changes: 20 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,26 @@ import { Button, SafeAreaView } from "react-native";
import parseUrl from "url-parse";

const App = () => {
const handleOnPress = useCallback(() => {
openBrowser("https://swan.io", {
onClose: (url) => {
if (url) {
const { protocol, host, query } = parseUrl(url, true);
const origin = `${protocol}//${host}`;

if (origin === "com.company.myapp://close") {
console.log(JSON.stringify(query, null, 2));
}
useEffect(() => {
const subscription = Linking.addListener(
"url",
({ url }: { url: string }) => {
const { protocol, host, query } = parseUrl(url, true);
const origin = `${protocol}//${host}`;

if (origin === "com.company.myapp://close") {
console.log(JSON.stringify(query, null, 2));
}
},
}).catch((error) => {
console.error(error);
});
);

return () => {
subscription.remove();
};
}, []);

const handleOnPress = useCallback(() => {
openBrowser("https://swan.io").catch((error) => console.error(error));
}, []);

return (
Expand All @@ -57,7 +62,7 @@ const App = () => {

## API

### openBrowser(url: string, options: Options)
### openBrowser(url: string, options?: Options)

```tsx
import { openBrowser } from "@swan-io/react-native-browser";
Expand All @@ -67,14 +72,6 @@ openBrowser("https://swan.io", {
dismissButtonStyle: "close", // "cancel" | "close" | "done" (default to "close")
barTintColor: "#FFF", // in-app browser UI background color
controlTintColor: "#000", // in-app browser buttons color
onOpen: () => {
// fired on browser opened
// useful to switch the StatusBar color, for example
},
onClose: (url) => {
// fired on browser closed
// url will be defined if the browser has been closed via deeplink
},
}).catch((error) => {
console.error(error);
});
Expand All @@ -85,7 +82,7 @@ openBrowser("https://swan.io", {

## Handle deeplinks

In order to receive deeplink on browser close event, you have to setup them first. We **highly** recommand defining a custom schema + url for this specific task. For example, `com.company.myapp://close`.
In order to receive deeplink on browser close, you have to setup them first. We **highly** recommand defining a custom schema + url for this specific task. For example, `com.company.myapp://close`.

### On iOS

Expand Down
2 changes: 1 addition & 1 deletion RNSwanBrowser.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.author = package["author"]
s.homepage = package["homepage"]

s.platforms = { :ios => "12.4", :tvos => "12.4" }
s.platforms = { :ios => "13.4", :tvos => "13.4" }
s.requires_arc = true

s.source = { :git => package["repository"]["url"], :tag => s.version }
Expand Down
19 changes: 6 additions & 13 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ buildscript {
gradlePluginPortal()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet("kotlinVersion", "1.8.0")}")
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet("kotlinVersion", "1.9.22")}")
classpath("com.android.tools.build:gradle:8.2.1")
}
}

Expand All @@ -24,20 +24,13 @@ if (isNewArchitectureEnabled()) {
}

android {
namespace "io.swan.rnbrowser"

buildToolsVersion safeExtGet("buildToolsVersion", "34.0.0")
compileSdkVersion safeExtGet("compileSdkVersion", 34)

if (project.android.hasProperty("namespace")) {
namespace "io.swan.rnbrowser"

buildFeatures {
buildConfig true
}
sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
}
}
buildFeatures {
buildConfig true
}
defaultConfig {
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString())
Expand Down
2 changes: 1 addition & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.swan.rnbrowser">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
Expand Down
8 changes: 0 additions & 8 deletions android/src/main/AndroidManifestNew.xml

This file was deleted.

25 changes: 2 additions & 23 deletions android/src/main/java/io/swan/rnbrowser/RNSwanBrowserModuleImpl.kt
Original file line number Diff line number Diff line change
@@ -1,56 +1,35 @@
package io.swan.rnbrowser

import android.content.Intent
import android.net.Uri

import androidx.annotation.ColorInt
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.net.toUri

import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter

import io.swan.rnbrowser.helpers.CustomTabActivityHelper

object RNSwanBrowserModuleImpl {
const val NAME = "RNSwanBrowser"
private var browserVisible = false

internal fun onHostResume(reactContext: ReactApplicationContext) {
if (browserVisible && reactContext.hasActiveReactInstance()) {
browserVisible = false

reactContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit("swanBrowserDidClose", null)
}
}

internal fun open(
reactContext: ReactApplicationContext,
url: String,
options: ReadableMap,
promise: Promise
) {
if (browserVisible) {
return promise.reject(
"swan_browser_visible",
"An instance of the swan browser is already visible"
)
}

val activity = reactContext.currentActivity
?: return promise.reject(
"no_current_activity",
"Couldn't call open() when the app is in background"
)

browserVisible = true

val intentBuilder = CustomTabsIntent.Builder().apply {
setBookmarksButtonEnabled(false)
setDownloadButtonEnabled(false)
Expand Down Expand Up @@ -95,7 +74,7 @@ object RNSwanBrowserModuleImpl {
}

CustomTabActivityHelper.openCustomTab(
activity, customTabsIntent, Uri.parse(url)
activity, customTabsIntent, url.toUri()
) { currentActivity, uri ->
currentActivity.startActivity(Intent(Intent.ACTION_VIEW, uri))
}
Expand Down
28 changes: 1 addition & 27 deletions android/src/newarch/io/swan/rnbrowser/RNSwanBrowserModule.kt
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
package io.swan.rnbrowser

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

@ReactModule(name = RNSwanBrowserModuleImpl.NAME)
class RNSwanBrowserModule(reactContext: ReactApplicationContext) :
NativeRNSwanBrowserSpec(reactContext),
LifecycleEventListener {

init {
reactApplicationContext.addLifecycleEventListener(this)
}

override fun invalidate() {
reactApplicationContext.removeLifecycleEventListener(this)
}
NativeRNSwanBrowserSpec(reactContext) {

override fun getName(): String {
return RNSwanBrowserModuleImpl.NAME
}

override fun onHostResume() {
RNSwanBrowserModuleImpl.onHostResume(reactApplicationContext)
}

override fun onHostPause() {}

override fun onHostDestroy() {}

override fun open(url: String, options: ReadableMap, promise: Promise) {
RNSwanBrowserModuleImpl.open(reactApplicationContext, url, options, promise)
}

override fun close() {
// noop on Android since the modal is closed by deep-link
}

override fun addListener(eventName: String) {
// iOS only
}

override fun removeListeners(count: Double) {
// iOS only
}
}
30 changes: 1 addition & 29 deletions android/src/oldarch/io/swan/rnbrowser/RNSwanBrowserModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.swan.rnbrowser

import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
Expand All @@ -10,29 +9,12 @@ import com.facebook.react.module.annotations.ReactModule

@ReactModule(name = RNSwanBrowserModuleImpl.NAME)
class RNSwanBrowserModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext),
LifecycleEventListener {

init {
reactApplicationContext.addLifecycleEventListener(this)
}

override fun invalidate() {
reactApplicationContext.removeLifecycleEventListener(this)
}
ReactContextBaseJavaModule(reactContext) {

override fun getName(): String {
return RNSwanBrowserModuleImpl.NAME
}

override fun onHostResume() {
RNSwanBrowserModuleImpl.onHostResume(reactApplicationContext)
}

override fun onHostPause() {}

override fun onHostDestroy() {}

@ReactMethod
fun open(url: String, options: ReadableMap, promise: Promise) {
RNSwanBrowserModuleImpl.open(reactApplicationContext, url, options, promise)
Expand All @@ -42,14 +24,4 @@ class RNSwanBrowserModule(reactContext: ReactApplicationContext) :
fun close() {
// noop on Android since the modal is closed by deep-link
}

@ReactMethod
fun addListener(eventName: String) {
// iOS only
}

@ReactMethod
fun removeListeners(count: Double) {
// iOS only
}
}
12 changes: 6 additions & 6 deletions example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ GEM
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
base64 (0.2.0)
benchmark (0.4.0)
bigdecimal (3.1.9)
base64 (0.3.0)
benchmark (0.4.1)
bigdecimal (3.2.2)
claide (1.1.0)
cocoapods (1.15.2)
addressable (~> 2.8)
Expand Down Expand Up @@ -67,7 +67,7 @@ GEM
colored2 (3.1.2)
concurrent-ruby (1.3.3)
connection_pool (2.5.3)
drb (2.2.1)
drb (2.2.3)
escape (0.0.4)
ethon (0.16.0)
ffi (>= 1.15.0)
Expand All @@ -79,7 +79,7 @@ GEM
mutex_m
i18n (1.14.7)
concurrent-ruby (~> 1.0)
json (2.11.3)
json (2.13.2)
logger (1.7.0)
minitest (5.25.5)
molinillo (0.8.0)
Expand Down Expand Up @@ -121,4 +121,4 @@ RUBY VERSION
ruby 3.3.4p94

BUNDLED WITH
2.6.8
2.6.9
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader

class MainApplication : Application(), ReactApplication {

Expand All @@ -35,10 +33,6 @@ class MainApplication : Application(), ReactApplication {

override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
load()
}
loadReactNative(this)
}
}
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
compileSdkVersion = 35
targetSdkVersion = 35
ndkVersion = "27.1.12297006"
kotlinVersion = "2.0.21"
kotlinVersion = "2.1.20"
}
repositories {
google()
Expand Down
Binary file modified example/android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Loading