From 6b2d39d754efccca70e133c79de008a6586f2e12 Mon Sep 17 00:00:00 2001 From: dimitris Date: Sat, 16 May 2026 01:35:04 +0200 Subject: [PATCH] fix(browser): hide spinner on main-frame load errors in BrowserClient BrowserClient flips BrowserCallback.onLoadingStateChanged on onPageStarted (true) and onPageFinished (false), but does not override onReceivedError. On many failure modes (DNS, certificate, offline, 4xx/5xx) onPageFinished does not always fire after the error, so the toolbar / progress UI stays stuck on isLoading = true even though the page never loaded. Add a main-frame-only onReceivedError override that flips isLoading = false too. isForMainFrame keeps a single blocked sub-resource from flipping the spinner off while the main load is still running. --- .../landwarderer/futon/browser/BrowserClient.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserClient.kt b/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserClient.kt index 82a9450e0c..b3d2b52d85 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserClient.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserClient.kt @@ -3,6 +3,7 @@ package io.github.landwarderer.futon.browser import android.annotation.SuppressLint import android.graphics.Bitmap import android.os.Looper +import android.webkit.WebResourceError import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView @@ -33,6 +34,21 @@ open class BrowserClient( callback.onLoadingStateChanged(isLoading = true) } + override fun onReceivedError( + view: WebView?, + request: WebResourceRequest?, + error: WebResourceError?, + ) { + super.onReceivedError(view, request, error) + // Drop the spinner on main-frame failures (DNS, certificate, offline, + // 4xx/5xx) too, since onPageFinished does not always fire after an + // error and the BrowserCallback would otherwise stay stuck on + // isLoading = true. + if (request?.isForMainFrame == true) { + callback.onLoadingStateChanged(isLoading = false) + } + } + override fun onPageCommitVisible(view: WebView, url: String) { super.onPageCommitVisible(view, url) callback.onTitleChanged(view.title.orEmpty(), url)