Skip to content

BrowserClient leaves spinner stuck on isLoading=true when a load fails #67

@jim-daf

Description

@jim-daf

BrowserClient (app/src/main/kotlin/io/github/landwarderer/futon/browser/BrowserClient.kt:20) tracks the loading state of the in-app browser via the BrowserCallback.onLoadingStateChanged(isLoading: Boolean) callback. It overrides onPageStarted (isLoading = true) and onPageFinished (isLoading = false) but does not override onReceivedError:

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
    super.onPageStarted(view, url, favicon)
    callback.onLoadingStateChanged(isLoading = true)
}

override fun onPageFinished(webView: WebView, url: String) {
    super.onPageFinished(webView, url)
    callback.onLoadingStateChanged(isLoading = false)
}

On many failure modes (DNS, certificate, offline, 4xx/5xx) the WebView reports the failure through onReceivedError and onPageFinished does not always fire afterwards. When that happens the toolbar / progress UI driven by onLoadingStateChanged stays stuck on isLoading = true even though the page never loaded.

Suggested fix

Add a main-frame-only onReceivedError override that also flips isLoading = false:

override fun onReceivedError(
    view: WebView?,
    request: WebResourceRequest?,
    error: WebResourceError?,
) {
    super.onReceivedError(view, request, error)
    if (request?.isForMainFrame == true) {
        callback.onLoadingStateChanged(isLoading = false)
    }
}

isForMainFrame keeps a single blocked sub-resource from prematurely flipping the spinner off while the main load is still running.

A PR with the addition is open at #68.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions