Skip to content

Commit

Permalink
feat: match the implementation on android, fix ios
Browse files Browse the repository at this point in the history
  • Loading branch information
pklatka committed Apr 23, 2024
1 parent 7e64af7 commit bc743ed
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.reactnativeturbowebview

import android.view.MotionEvent
import android.view.View.OnTouchListener
import android.webkit.JavascriptInterface
import android.webkit.WebSettings
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
Expand All @@ -27,7 +24,6 @@ import org.json.JSONObject
class RNSession(
private val reactContext: ReactApplicationContext,
private val sessionHandle: String,
private val webViewConfiguration: RNWebViewConfiguration
) : SessionCallbackAdapter {

var visitableView: SessionSubscriber? = null
Expand All @@ -40,9 +36,7 @@ class RNSession(
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)
webView.settings.setJavaScriptEnabled(true)
webView.addJavascriptInterface(JavaScriptInterface(), "AndroidInterface")
setUserAgentString(webView, webViewConfiguration.applicationNameForUserAgent)
webView.webChromeClient = RNWebChromeClient(reactContext, this@RNSession)
updateWebViewConfiguration(webView, webViewConfiguration)
session.isRunningInAndroidNavigation = false
session
}
Expand All @@ -53,30 +47,6 @@ class RNSession(
visitableView = newView
}

private fun setUserAgentString(webView: TurboWebView, applicationNameForUserAgent: String?) {
var userAgentString = WebSettings.getDefaultUserAgent(webView.context)
if (applicationNameForUserAgent != null) {
userAgentString = "$userAgentString $applicationNameForUserAgent"
}
webView.settings.userAgentString = userAgentString
}

private fun setOnTouchListener(webView: TurboWebView, scrollEnabled: Boolean) {
if (!scrollEnabled) {
webView.setOnTouchListener(OnTouchListener { _, event -> event.action == MotionEvent.ACTION_MOVE })
} else {
webView.setOnTouchListener(null)
}
}

private fun updateWebViewConfiguration(webView: TurboWebView, configuration: RNWebViewConfiguration) {
setOnTouchListener(webView, configuration.scrollEnabled)
}

fun updateWebViewConfiguration(configuration: RNWebViewConfiguration) {
updateWebViewConfiguration(webView, configuration)
}

fun visit(url: String, restoreWithCachedSnapshot: Boolean, reload: Boolean, viewTreeLifecycleOwner: LifecycleOwner?, visitOptions: TurboVisitOptions?){
val restore = restoreWithCachedSnapshot && !reload

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ class RNSessionManager(reactContext: ReactApplicationContext) :
fun findOrCreateSession(
reactContext: ReactApplicationContext,
sessionHandle: String,
webViewConfiguration: RNWebViewConfiguration
): RNSession = sessions.getOrPut(sessionHandle) {
RNSession(reactContext, sessionHandle, webViewConfiguration)
RNSession(reactContext, sessionHandle)
}

fun clearSnapshotCaches() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.reactnativeturbowebview

import android.content.Context
import android.graphics.Bitmap
import android.view.MotionEvent
import android.view.ViewGroup
import android.webkit.CookieManager
import android.webkit.WebSettings
import android.widget.LinearLayout
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.view.isVisible
Expand All @@ -16,12 +18,7 @@ import dev.hotwire.turbo.views.TurboView
import dev.hotwire.turbo.views.TurboWebView
import dev.hotwire.turbo.visit.TurboVisitOptions
import dev.hotwire.turbo.R
import dev.hotwire.turbo.errors.HttpError
import dev.hotwire.turbo.errors.LoadError
import dev.hotwire.turbo.errors.TurboVisitError
import dev.hotwire.turbo.errors.WebError
import dev.hotwire.turbo.errors.WebSslError
import dev.hotwire.turbo.visit.TurboVisitAction

const val REFRESH_SCRIPT = "typeof Turbo.session.refresh === 'function'" +
"? Turbo.session.refresh(document.baseURI)" + // Turbo 8+
Expand All @@ -48,12 +45,11 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
var applicationNameForUserAgent: String? = null
set(value) {
field = value
webViewConfiguration.applicationNameForUserAgent = value
updateWebViewConfiguration()
}
var scrollEnabled: Boolean = true
set(value) {
field = value
webViewConfiguration.scrollEnabled = value
updateWebViewConfiguration()
}
var pullToRefreshEnabled: Boolean = true
Expand All @@ -63,16 +59,22 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
}

// Session
private val canInitializeSession: Boolean get() = ::sessionHandle.isInitialized
private val session: RNSession by lazy {
RNSessionManager.findOrCreateSession(
reactContext,
sessionHandle,
webViewConfiguration
)
}
private val webView: TurboWebView get() = session.webView
private val webViewConfiguration: RNWebViewConfiguration = RNWebViewConfiguration()
private var _session: RNSession? = null
private val session: RNSession?
get() {
if (_session != null) {
return _session
}

if (!::sessionHandle.isInitialized) {
return null
}

_session = RNSessionManager.findOrCreateSession(reactContext, sessionHandle)
return _session
}

private val webView: TurboWebView? get() = session?.webView

private var onConfirmHandler: ((result: Boolean) -> Unit)? = null
private var onAlertHandler: (() -> Unit)? = null
Expand Down Expand Up @@ -105,13 +107,29 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
}

private fun updateWebViewConfiguration() {
if (canInitializeSession) {
session.updateWebViewConfiguration(webViewConfiguration)
if (webView == null) return
setUserAgentString(webView!!, applicationNameForUserAgent)
setOnTouchListener(webView!!, scrollEnabled)
}

private fun setUserAgentString(webView: TurboWebView, applicationNameForUserAgent: String?) {
var userAgentString = WebSettings.getDefaultUserAgent(webView.context)
if (applicationNameForUserAgent != null) {
userAgentString = "$userAgentString $applicationNameForUserAgent"
}
webView.settings.userAgentString = userAgentString
}

private fun setOnTouchListener(webView: TurboWebView, scrollEnabled: Boolean) {
if (!scrollEnabled) {
webView.setOnTouchListener(OnTouchListener { _, event -> event.action == MotionEvent.ACTION_MOVE })
} else {
webView.setOnTouchListener(null)
}
}

private fun performVisit(restoreWithCachedSnapshot: Boolean, reload: Boolean) {
session.visit(
session?.visit(
url = url,
restoreWithCachedSnapshot = restoreWithCachedSnapshot,
reload = reload,
Expand All @@ -127,7 +145,7 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
// Visit every time the WebView is reattached to the current Fragment.
if (isWebViewAttachedToNewDestination) {
val currentSessionVisitRestored =
!isInitialVisit && session.currentVisit?.destinationIdentifier == url.hashCode() && session.restoreCurrentVisit()
!isInitialVisit && session?.currentVisit?.destinationIdentifier == url.hashCode() && session?.restoreCurrentVisit() == true

if (!currentSessionVisitRestored) {
showProgressView()
Expand All @@ -139,11 +157,11 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
}

override fun refresh() {
webView.evaluateJavascript(REFRESH_SCRIPT, null)
webView?.evaluateJavascript(REFRESH_SCRIPT, null)
}

override fun reload(displayProgress: Boolean) {
if (webView.url == null) return
if (webView?.url == null) return

turboView.webViewRefresh?.apply {
if (displayProgress && !isRefreshing) {
Expand Down Expand Up @@ -182,7 +200,7 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib

override fun onAttachedToWindow() {
super.onAttachedToWindow()
session.registerVisitableView(this)
session?.registerVisitableView(this)
visit()
}

Expand All @@ -191,14 +209,14 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
// This can happen when the user uses one session for different
// bottom tabs. In this case, we need to remove the webview from
// the parent before attaching it to the new one.
if (webView.parent != null) {
(webView.parent as ViewGroup).removeView(webView)
if (webView!!.parent != null) {
(webView!!.parent as ViewGroup).removeView(webView)
}

// Re-layout the TurboView before attaching to make page restorations work correctly.
requestLayout()

turboView.attachWebView(webView) { attachedToNewDestination ->
turboView.attachWebView(webView!!) { attachedToNewDestination ->
updateWebViewConfiguration()
onReady(attachedToNewDestination)
}
Expand All @@ -207,9 +225,9 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
override fun detachWebView() {
screenshotView()

(webView.parent as ViewGroup?)?.endViewTransition(webView)
(webView!!.parent as ViewGroup?)?.endViewTransition(webView)

turboView.detachWebView(webView) {
turboView.detachWebView(webView!!) {
// Force layout to fix improper layout of the TurboWebView.
forceLayout()
}
Expand Down Expand Up @@ -280,7 +298,7 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib
// region SessionSubscriber

override fun injectJavaScript(script: String) {
webView.evaluateJavascript(script, null)
webView?.evaluateJavascript(script, null)
}

override fun handleMessage(message: WritableMap) {
Expand Down Expand Up @@ -330,16 +348,16 @@ class RNVisitableView(context: Context) : LinearLayout(context), SessionSubscrib

override fun visitRendered() {
sendEvent(RNVisitableViewEvent.LOAD, Arguments.createMap().apply {
putString("title", webView.title)
putString("url", webView.url)
putString("title", webView!!.title)
putString("url", webView!!.url)
})
removeTransitionalViews()
}

override fun visitCompleted(completedOffline: Boolean) {
sendEvent(RNVisitableViewEvent.LOAD, Arguments.createMap().apply {
putString("title", webView.title)
putString("url", webView.url)
putString("title", webView!!.title)
putString("url", webView!!.url)
})
CookieManager
.getInstance()
Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion packages/turbo/ios/RNVisitableView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ class RNVisitableView: UIView, RNSessionSubscriber {
return nil
}

return RNSessionManager.shared.findOrCreateSession(sessionHandle: sessionHandle!, webViewConfiguration: webViewConfiguration)
_session = RNSessionManager.shared.findOrCreateSession(sessionHandle: sessionHandle!, webViewConfiguration: webViewConfiguration)
return _session
}
private var webView: WKWebView? { session?.webView }
private var webViewConfiguration: WKWebViewConfiguration = WKWebViewConfiguration()
Expand Down

0 comments on commit bc743ed

Please sign in to comment.