Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,9 @@ class BrowserTabFragment :
}

private fun configureSwipeRefresh() {
val metrics = resources.displayMetrics
val distanceToTrigger = (DEFAULT_CIRCLE_TARGET_TIMES_1_5 * metrics.density).toInt()
swipeRefreshContainer.setDistanceToTriggerSync(distanceToTrigger)
swipeRefreshContainer.setColorSchemeColors(ContextCompat.getColor(requireContext(), R.color.cornflowerBlue))

swipeRefreshContainer.setOnRefreshListener {
Expand Down Expand Up @@ -1396,6 +1399,8 @@ class BrowserTabFragment :
private const val TRACKERS_INI_DELAY = 500L
private const val TRACKERS_SECONDARY_DELAY = 200L

private const val DEFAULT_CIRCLE_TARGET_TIMES_1_5 = 96

fun newInstance(tabId: String, query: String? = null, skipHome: Boolean): BrowserTabFragment {
val fragment = BrowserTabFragment()
val args = Bundle()
Expand Down
29 changes: 22 additions & 7 deletions app/src/main/java/com/duckduckgo/app/browser/DuckDuckGoWebView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ import androidx.core.view.ViewCompat
* Originally based on https://github.com/takahirom/webview-in-coordinatorlayout for scrolling behaviour
*/
class DuckDuckGoWebView : WebView, NestedScrollingChild {
private var lastClampedTopY: Boolean = false
private var lastClampedTopY: Boolean = true // when created we are always at the top
private var contentAllowsSwipeToRefresh: Boolean = true
private var enableSwipeRefreshCallback: ((Boolean) -> Unit)? = null
private var hasGestureFinished = true
private var canSwipeToRefresh = true

private var lastY: Int = 0
private var lastDeltaY: Int = 0
Expand Down Expand Up @@ -76,12 +78,15 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {
event.offsetLocation(0f, nestedOffsetY.toFloat())

when (action) {
MotionEvent.ACTION_UP -> {
hasGestureFinished = true
returnValue = super.onTouchEvent(event)
stopNestedScroll()
}
MotionEvent.ACTION_MOVE -> {
var deltaY = lastY - eventY

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

if (dispatchNestedPreScroll(0, deltaY, scrollConsumed, scrollOffset)) {
deltaY -= scrollConsumed[1]
Expand All @@ -98,15 +103,16 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {
lastY -= scrollOffset[1]
}

if (scrollY == 0 && lastClampedTopY && nestedOffsetY == 0) {
// we have reached the top, are clamped vertically and nestedScrollY is done too -> enable swipeRefresh (by default always disabled)
if (canSwipeToRefresh && scrollY == 0 && lastClampedTopY && nestedOffsetY == 0) {
// we are on a new gesture, have reached the top, are clamped vertically and nestedScrollY is done too -> enable swipeRefresh (by default always disabled)
enableSwipeRefresh(true)
}

lastDeltaY = deltaY
}

MotionEvent.ACTION_DOWN -> {
hasGestureFinished = false
// disable swipeRefresh until we can be sure it should be enabled
enableSwipeRefresh(false)

Expand Down Expand Up @@ -153,7 +159,16 @@ class DuckDuckGoWebView : WebView, NestedScrollingChild {
override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
// taking into account lastDeltaY since we are only interested whether we clamped at the top
lastClampedTopY = clampedY && lastDeltaY <= 0
enableSwipeRefresh(clampedY && scrollY == 0 && (lastDeltaY <= 0 || nestedOffsetY == 0))

if (!lastClampedTopY) {
canSwipeToRefresh = false // disable because user scrolled down so we need a new gesture
}

if (lastClampedTopY && hasGestureFinished) {
canSwipeToRefresh = true // only enable if at the top and gestured finished
}

enableSwipeRefresh(canSwipeToRefresh && clampedY && scrollY == 0 && (lastDeltaY <= 0 || nestedOffsetY == 0))
super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)
}

Expand Down