diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/pages/DeckOptions.kt b/AnkiDroid/src/main/java/com/ichi2/anki/pages/DeckOptions.kt index 31c31c4c37e0..4bc71fdd722c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/pages/DeckOptions.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/pages/DeckOptions.kt @@ -18,10 +18,12 @@ package com.ichi2.anki.pages import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.View import android.webkit.JavascriptInterface import android.webkit.WebResourceRequest import android.webkit.WebView import androidx.activity.OnBackPressedCallback +import androidx.core.view.isVisible import androidx.fragment.app.FragmentActivity import anki.collection.OpChanges import anki.collection.Progress @@ -136,6 +138,15 @@ class DeckOptions : PageFragment() { } } + /** @see onWebViewReady */ + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + pageLoadingIndicator.isVisible = true + super.onViewCreated(view, savedInstanceState) + } + override fun onWebViewCreated(webView: WebView) { // addJavascriptInterface needs to happen before loadUrl webView.addJavascriptInterface(ModalJavaScriptInterfaceListener(), "ankidroid") @@ -152,6 +163,11 @@ class DeckOptions : PageFragment() { return object : PageWebViewClient() { private val ankiManualHostRegex = Regex("^docs\\.ankiweb\\.net\$") + /** @see onWebViewReady */ + override fun onShowWebView(webView: WebView) { + // no-op: handled in onVebViewReady + } + override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest?, @@ -205,7 +221,8 @@ class DeckOptions : PageFragment() { fun onWebViewReady() { Timber.d("WebView ready to receive input") - // TODO: handle this + webView.isVisible = true + pageLoadingIndicator.isVisible = false } companion object { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageFragment.kt index c50e1a1beecc..6cb97edef933 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageFragment.kt @@ -28,6 +28,7 @@ import androidx.annotation.LayoutRes import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import com.google.android.material.appbar.MaterialToolbar +import com.google.android.material.progressindicator.CircularProgressIndicator import com.ichi2.anki.R import com.ichi2.anki.SingleFragmentActivity import com.ichi2.themes.Themes @@ -46,6 +47,15 @@ open class PageFragment( lateinit var webView: WebView private val server = AnkiServer(this).also { it.start() } + /** + * A loading indicator for the page. May be shown before the WebView is loaded to + * stop flickering + * + * @exception IllegalStateException if accessed before [onViewCreated] + */ + val pageLoadingIndicator: CircularProgressIndicator + get() = requireView().findViewById(R.id.page_loading) + /** * Override this to set a custom [WebViewClient] to the page. * This is called in [onViewCreated]. diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageWebViewClient.kt b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageWebViewClient.kt index f4d5d1c63ce6..5381ce5c16d6 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageWebViewClient.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PageWebViewClient.kt @@ -34,9 +34,6 @@ import java.io.IOException * Base WebViewClient to be used on [PageFragment] */ open class PageWebViewClient : WebViewClient() { - /** Wait for the provided promise to complete before showing the WebView */ - open val promiseToWaitFor: String? = null - val onPageFinishedCallbacks: MutableList = mutableListOf() override fun shouldInterceptRequest( @@ -87,6 +84,17 @@ open class PageWebViewClient : WebViewClient() { } } + /** + * Shows the WebView after the page is loaded + * + * This may be overridden if additional 'screen ready' logic is provided by the backend + * @see DeckOptions + */ + open fun onShowWebView(webView: WebView) { + Timber.v("Displaying WebView") + webView.isVisible = true + } + override fun onPageFinished( view: WebView?, url: String?, @@ -94,50 +102,9 @@ open class PageWebViewClient : WebViewClient() { super.onPageFinished(view, url) if (view == null) return onPageFinishedCallbacks.map { callback -> callback.onPageFinished(view) } - if (promiseToWaitFor == null) { - /** [PageFragment.webView] is invisible by default to avoid flashes while - * the page is loaded, and can be made visible again after it finishes loading */ - Timber.v("displaying WebView") - view.isVisible = true - } else { - view.evaluateJavascript( - """$promiseToWaitFor.then(() => { console.log("page-fully-loaded:"); window.location.href = "page-fully-loaded:" } )""", - ) { - Timber.v("waiting for '$promiseToWaitFor' before displaying WebView") - } - } - } - - @Suppress("DEPRECATION", "OVERRIDE_DEPRECATION") // still needed for API 23 - override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { - if (view == null || url == null) return super.shouldOverrideUrlLoading(view, url) - if (handleUrl(view, url)) { - return true - } - return super.shouldOverrideUrlLoading(view, url) - } - - override fun shouldOverrideUrlLoading( - view: WebView?, - request: WebResourceRequest?, - ): Boolean { - if (view == null || request == null) return super.shouldOverrideUrlLoading(view, request) - if (handleUrl(view, request.url.toString())) { - return true - } - return super.shouldOverrideUrlLoading(view, request) - } - - private fun handleUrl( - view: WebView, - url: String, - ): Boolean { - if (url == "page-fully-loaded:") { - Timber.v("displaying WebView after '$promiseToWaitFor' executed") - view.isVisible = true - return true - } - return false + /** [PageFragment.webView] is invisible by default to avoid flashes while + * the page is loaded, and can be made visible again after it finishes loading */ + onShowWebView(view) } } diff --git a/AnkiDroid/src/main/res/layout/page_fragment.xml b/AnkiDroid/src/main/res/layout/page_fragment.xml index abde86eb07ac..df29a9361506 100644 --- a/AnkiDroid/src/main/res/layout/page_fragment.xml +++ b/AnkiDroid/src/main/res/layout/page_fragment.xml @@ -2,6 +2,7 @@ @@ -15,10 +16,32 @@ app:navigationIcon="?attr/homeAsUpIndicator" /> - + > + + + + \ No newline at end of file