mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
feat(napplets): back gesture pages back in the WebView, then exits to Amethyst
The sandbox host now routes the back gesture into the applet/site's own history first: an OnBackPressedCallback calls webView.goBack() while there's history to pop (in-page links, iframe navigations, and history.pushState all count), and only disables itself — letting system back return to Amethyst — once the WebView is at its first page. The callback's enabled state tracks canGoBack() via doUpdateVisitedHistory / onPageFinished. Works with predictive back. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ncMHuBBVHEf7spAoSssde
This commit is contained in:
+40
@@ -49,6 +49,7 @@ import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
@@ -132,6 +133,25 @@ class NappletHostActivity : ComponentActivity() {
|
||||
// Set once the WebView has begun loading the shell, so a retry doesn't reload it.
|
||||
private var started = false
|
||||
|
||||
// Back goes "page back" inside the applet's WebView history first; only when it can't go back
|
||||
// further does this disable itself and let the system back exit the sandbox to Amethyst.
|
||||
private val backCallback =
|
||||
object : OnBackPressedCallback(false) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (this@NappletHostActivity::webView.isInitialized && webView.canGoBack()) {
|
||||
webView.goBack()
|
||||
} else {
|
||||
isEnabled = false
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Keep the in-WebView back gesture enabled exactly while the applet has history to pop. */
|
||||
private fun syncBackState() {
|
||||
if (this::webView.isInitialized) backCallback.isEnabled = webView.canGoBack()
|
||||
}
|
||||
|
||||
private val brokerConnection =
|
||||
object : ServiceConnection {
|
||||
override fun onServiceConnected(
|
||||
@@ -190,6 +210,9 @@ class NappletHostActivity : ComponentActivity() {
|
||||
// class reference, so this sandbox module needs no dependency on :amethyst.
|
||||
bindService(Intent().setClassName(this, NappletHostContract.BROKER_SERVICE_CLASS), brokerConnection, BIND_AUTO_CREATE)
|
||||
|
||||
// Route the back gesture into the WebView's history first (see backCallback).
|
||||
onBackPressedDispatcher.addCallback(this, backCallback)
|
||||
|
||||
// Persistent trusted chrome (anti-phishing bar the applet can't draw over) over a content
|
||||
// frame that shows a loading screen → the applet's WebView, or an "unavailable" screen.
|
||||
val root =
|
||||
@@ -359,6 +382,23 @@ class NappletHostActivity : ComponentActivity() {
|
||||
request: WebResourceRequest,
|
||||
): WebResourceResponse? = contentServer.serve(request)
|
||||
|
||||
// The applet's in-page / in-iframe navigations (links + history.pushState) change the
|
||||
// WebView's back/forward list; keep the back gesture enabled exactly while it can pop.
|
||||
override fun doUpdateVisitedHistory(
|
||||
view: WebView,
|
||||
url: String,
|
||||
isReload: Boolean,
|
||||
) {
|
||||
syncBackState()
|
||||
}
|
||||
|
||||
override fun onPageFinished(
|
||||
view: WebView,
|
||||
url: String,
|
||||
) {
|
||||
syncBackState()
|
||||
}
|
||||
|
||||
override fun shouldOverrideUrlLoading(
|
||||
view: WebView,
|
||||
request: WebResourceRequest,
|
||||
|
||||
Reference in New Issue
Block a user