Browse Source

Open external url (like terms and condition) in a Custom Chrome Tab, and disable to "Leave page" dialog.

pull/3467/head
Benoit Marty 1 month ago committed by Benoit Marty
parent
commit
aab5a27a91
  1. 13
      features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountNode.kt
  2. 21
      features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountView.kt
  3. 9
      features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt

13
features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountNode.kt

@ -7,14 +7,18 @@ @@ -7,14 +7,18 @@
package io.element.android.features.login.impl.screens.createaccount
import android.app.Activity
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.anvilannotations.ContributesNode
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.androidutils.browser.openUrlInChromeCustomTab
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.AppScope
@ -31,13 +35,22 @@ class CreateAccountNode @AssistedInject constructor( @@ -31,13 +35,22 @@ class CreateAccountNode @AssistedInject constructor(
private val presenter = presenterFactory.create(inputs<Inputs>().url)
private fun onOpenExternalUrl(activity: Activity, darkTheme: Boolean, url: String) {
activity.openUrlInChromeCustomTab(null, darkTheme, url)
}
@Composable
override fun View(modifier: Modifier) {
val activity = LocalContext.current as Activity
val isDark = ElementTheme.isLightTheme.not()
val state = presenter.present()
CreateAccountView(
state = state,
modifier = modifier,
onBackClick = ::navigateUp,
onOpenExternalUrl = {
onOpenExternalUrl(activity, isDark, it)
},
)
}
}

21
features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/CreateAccountView.kt

@ -9,6 +9,7 @@ package io.element.android.features.login.impl.screens.createaccount @@ -9,6 +9,7 @@ package io.element.android.features.login.impl.screens.createaccount
import android.annotation.SuppressLint
import android.view.ViewGroup
import android.webkit.JsResult
import android.webkit.WebChromeClient
import android.webkit.WebView
import androidx.compose.animation.AnimatedVisibility
@ -41,12 +42,14 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold @@ -41,12 +42,14 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.theme.progressIndicatorTrackColor
import timber.log.Timber
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateAccountView(
state: CreateAccountState,
onBackClick: () -> Unit,
onOpenExternalUrl: (String) -> Unit,
modifier: Modifier = Modifier,
) {
Scaffold(
@ -76,9 +79,14 @@ fun CreateAccountView( @@ -76,9 +79,14 @@ fun CreateAccountView(
.fillMaxSize(),
state = state,
onWebViewCreate = { webView ->
WebViewMessageInterceptor(webView, state.isDebugBuild) {
state.eventSink(CreateAccountEvents.OnMessageReceived(it))
}
WebViewMessageInterceptor(
webView,
state.isDebugBuild,
onOpenExternalUrl = onOpenExternalUrl,
onMessage = {
state.eventSink(CreateAccountEvents.OnMessageReceived(it))
},
)
}
)
AnimatedVisibility(
@ -153,6 +161,12 @@ private fun WebView.setup(state: CreateAccountState) { @@ -153,6 +161,12 @@ private fun WebView.setup(state: CreateAccountState) {
super.onProgressChanged(view, newProgress)
state.eventSink(CreateAccountEvents.SetPageProgress(newProgress))
}
override fun onJsBeforeUnload(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
Timber.w("onJsBeforeUnload, cancelling the dialog, we will open external links in a Custom Chrome Tab")
result?.confirm()
return true
}
}
}
@ -162,5 +176,6 @@ internal fun CreateAccountViewPreview(@PreviewParameter(CreateAccountStateProvid @@ -162,5 +176,6 @@ internal fun CreateAccountViewPreview(@PreviewParameter(CreateAccountStateProvid
CreateAccountView(
state = state,
onBackClick = {},
onOpenExternalUrl = {},
)
}

9
features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/WebViewMessageInterceptor.kt

@ -9,6 +9,7 @@ package io.element.android.features.login.impl.screens.createaccount @@ -9,6 +9,7 @@ package io.element.android.features.login.impl.screens.createaccount
import android.graphics.Bitmap
import android.webkit.JavascriptInterface
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.webkit.WebViewCompat
@ -17,6 +18,7 @@ import androidx.webkit.WebViewFeature @@ -17,6 +18,7 @@ import androidx.webkit.WebViewFeature
class WebViewMessageInterceptor(
webView: WebView,
private val debugLog: Boolean,
private val onOpenExternalUrl: (String) -> Unit,
private val onMessage: (String) -> Unit,
) {
companion object {
@ -50,6 +52,13 @@ class WebViewMessageInterceptor( @@ -50,6 +52,13 @@ class WebViewMessageInterceptor(
null
)
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
request ?: return super.shouldOverrideUrlLoading(view, request)
// Load the URL in a Chrome Custom Tab, and return true to cancel the load
onOpenExternalUrl(request.url.toString())
return true
}
}
// Use WebMessageListener if supported, otherwise use JavascriptInterface

Loading…
Cancel
Save