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
47 changes: 37 additions & 10 deletions android/src/main/java/io/ionic/portals/reactnative/PortalView.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package io.ionic.portals.reactnative

import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.Choreographer
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.widget.FrameLayout
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
Expand All @@ -19,7 +25,8 @@ import io.ionic.portals.WebVitals
private data class PortalViewState(
var fragment: PortalFragment?,
var portal: RNPortal?,
var initialContext: HashMap<String, Any?>?
var initialContext: HashMap<String, Any?>?,
var webContentsDebuggingEnabled: Boolean?
)

internal class PortalViewManager(private val context: ReactApplicationContext) :
Expand All @@ -35,13 +42,19 @@ internal class PortalViewManager(private val context: ReactApplicationContext) :
// Casting is safe and keeps old versions compatible
val initialContext = portal.getMap("initialContext")?.toHashMap() as HashMap<String, Any?>?

when (fragmentMap[viewGroup.id]) {
null -> fragmentMap[viewGroup.id] = PortalViewState(
fragment = null,
portal = RNPortalManager.createPortal(portal),
initialContext
)
val state = fragmentMap.getOrPut(viewGroup.id) {
PortalViewState(null, null, null, null)
}
state.portal = RNPortalManager.createPortal(portal)
state.initialContext = initialContext
}

@ReactProp(name = "webContentsDebuggingEnabled")
fun setWebContentsDebuggingEnabled(viewGroup: ViewGroup, webContentsDebuggingEnabled: Boolean) {
val state = fragmentMap.getOrPut(viewGroup.id) {
PortalViewState(null, null, null, null)
}
state.webContentsDebuggingEnabled = webContentsDebuggingEnabled
}

override fun getName() = "AndroidPortalView"
Expand Down Expand Up @@ -99,12 +112,26 @@ internal class PortalViewManager(private val context: ReactApplicationContext) :
}

val portalFragment = PortalFragment(portal)

viewState.initialContext?.let(portalFragment::setInitialContext)
viewState.fragment = portalFragment

val fragmentActivity = context.currentActivity as? FragmentActivity ?: return
fragmentActivity.supportFragmentManager
portalFragment.lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (event == Lifecycle.Event.ON_RESUME) {
source.lifecycle.removeObserver(this)

viewState.webContentsDebuggingEnabled?.let { enabled ->
// Post to the next main loop iteration to avoid racing with WebView initialization
Handler(Looper.getMainLooper()).post {
WebView.setWebContentsDebuggingEnabled(enabled)
}
}
}
}
})

val activity = context.currentActivity as? FragmentActivity ?: return
activity.supportFragmentManager
.beginTransaction()
.replace(viewId, portalFragment, "$viewId")
.commit()
Expand Down
1 change: 1 addition & 0 deletions ios/PortalView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@

@interface RCT_EXTERN_MODULE(IONPortalViewManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(portal, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(webContentsDebuggingEnabled, BOOL)
@end
16 changes: 15 additions & 1 deletion ios/PortalView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class PortalView: UIView {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.webView?.removeFromSuperview()
let webView = PortalUIView(portal: portal._portal)
let webView = PortalUIView(portal: portal._portal.configuring(\.isWebDebuggable, webContentsDebuggingEnabled))
webView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(webView)
NSLayoutConstraint.activate([
Expand All @@ -74,4 +74,18 @@ class PortalView: UIView {
}
}
}

@objc var webContentsDebuggingEnabled: Bool = {
#if DEBUG
true
#else
false
#endif
}() {
didSet {
if #available(iOS 16.4, *) {
self.webView?.bridge.webView?.isInspectable = webContentsDebuggingEnabled
}
}
}
}
6 changes: 5 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ export interface AssetMap {
/**
* Props needed for rendering a {@link Portal}
*/
export type PortalProps = { portal: Portal; webVitals?: WebVitals } & ViewProps;
export type PortalProps = {
portal: Portal;
webVitals?: WebVitals;
webContentsDebuggingEnabled?: boolean;
} & ViewProps;

export interface LiveUpdate {
/** The AppFlow application ID */
Expand Down