Skip to content

Commit

Permalink
Disable swipe to refresh on pages that define overscrollBehavior
Browse files Browse the repository at this point in the history
- Added JavaScript interface to retrieve the css overscrollBehaviorY value

- Added switch on custom WebView to allow disabling swipe to refresh completely

- Minor fix for lastClampedY issue on pages where height <= window to detect whether we actually are clampedY at the top
  • Loading branch information
Usiel Riedl committed Jun 26, 2020
1 parent ecdc014 commit c1bea60
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
Expand Up @@ -834,8 +834,17 @@ class BrowserTabFragment : Fragment(), FindListener, CoroutineScope, DaxDialogLi
}

it.setEnableSwipeRefreshCallback { enable ->
swipeRefreshContainer?.isEnabled = enable
try {
activity?.runOnUiThread {
swipeRefreshContainer?.isEnabled = enable
}
} catch (e: Exception) {
Timber.e("ERROR: ${Thread.currentThread().name} $e")
}
}
it.addJavascriptInterface(BrowserWebViewClient.WebAppInterface { enable ->
it.setContentAllowsSwipeToRefresh(enable)
}, "ddg_swipe_handler");

registerForContextMenu(it)

Expand Down
Expand Up @@ -32,6 +32,7 @@ import kotlinx.coroutines.*
import timber.log.Timber
import java.net.URI


class BrowserWebViewClient(
private val requestRewriter: RequestRewriter,
private val specialUrlDetector: SpecialUrlDetector,
Expand Down Expand Up @@ -137,6 +138,7 @@ class BrowserWebViewClient(
val navigationList = webView.safeCopyBackForwardList() ?: return
webViewClientListener?.navigationStateChanged(WebViewNavigationState(navigationList))
flushCookies()
detectOverscrollBehavior(webView)
} catch (e: Throwable) {
GlobalScope.launch {
uncaughtExceptionRepository.recordUncaughtException(e, ON_PAGE_FINISHED)
Expand All @@ -145,6 +147,16 @@ class BrowserWebViewClient(
}
}

private fun detectOverscrollBehavior(webView: WebView) {
webView.loadUrl(
"""
javascript:(function() {
ddg_swipe_handler.registerOverscrollBehavior(getComputedStyle(document.querySelector('body')).overscrollBehaviorY);
})();
"""
)
}

private fun flushCookies() {
GlobalScope.launch(Dispatchers.IO) {
cookieManager.flush()
Expand Down Expand Up @@ -242,4 +254,11 @@ class BrowserWebViewClient(
it.requiresAuthentication(request)
}
}

class WebAppInterface internal constructor(private var enableSwipeRefresh: (Boolean) -> Unit) {
@JavascriptInterface
fun registerOverscrollBehavior(behavior: String) {
enableSwipeRefresh(behavior == "auto")
}
}
}
23 changes: 18 additions & 5 deletions app/src/main/java/com/duckduckgo/app/browser/DuckDuckGoWebView.kt
Expand Up @@ -35,10 +35,12 @@ import androidx.core.view.ViewCompat
* Originally based on https://github.com/takahirom/webview-in-coordinatorlayout for scrolling behaviour
*/
class DuckDuckGoWebView : WebView, NestedScrollingChild {
private var lastClampedY: Boolean = false
private var lastClampedTopY: Boolean = false
private var contentAllowsSwipeToRefresh: Boolean = true
private var enableSwipeRefreshCallback: ((Boolean) -> Unit)? = null

private var lastY: Int = 0
private var lastDeltaY: Int = 0
private val scrollOffset = IntArray(2)
private val scrollConsumed = IntArray(2)
private var nestedOffsetY: Int = 0
Expand Down Expand Up @@ -78,7 +80,7 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {
var deltaY = lastY - eventY

if (deltaY > 0) {
lastClampedY = false
lastClampedTopY = false
}

if (dispatchNestedPreScroll(0, deltaY, scrollConsumed, scrollOffset)) {
Expand All @@ -90,15 +92,18 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {

returnValue = super.onTouchEvent(event)

if (scrollY == 0 && lastClampedY) {
if (scrollY == 0 && lastClampedTopY) {
// we have reached the top and are clamped -> enable swipeRefresh (by default always disabled)
enableSwipeRefresh(true)

stopNestedScroll()
} else if (dispatchNestedScroll(0, scrollOffset[1], 0, deltaY, scrollOffset)) {
event.offsetLocation(0f, scrollOffset[1].toFloat())
nestedOffsetY += scrollOffset[1]
lastY -= scrollOffset[1]
}

lastDeltaY = deltaY
}

MotionEvent.ACTION_DOWN -> {
Expand Down Expand Up @@ -146,19 +151,27 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {
nestedScrollHelper.dispatchNestedPreFling(velocityX, velocityY)

override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
lastClampedY = clampedY
// taking into account lastDeltaY since we are only interested whether we clamped at the top
lastClampedTopY = clampedY && lastDeltaY <= 0
enableSwipeRefresh(clampedY && scrollY == 0)
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)
}

private fun enableSwipeRefresh(enable: Boolean) {
enableSwipeRefreshCallback?.invoke(enable)
enableSwipeRefreshCallback?.invoke(enable && contentAllowsSwipeToRefresh)
}

fun setEnableSwipeRefreshCallback(callback: (Boolean) -> Unit) {
enableSwipeRefreshCallback = callback
}

fun setContentAllowsSwipeToRefresh(allowed: Boolean) {
contentAllowsSwipeToRefresh = allowed
if (!allowed) {
enableSwipeRefresh(false)
}
}

companion object {

/*
Expand Down

0 comments on commit c1bea60

Please sign in to comment.