aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt3
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/SwipeRefreshLayout.kt78
2 files changed, 81 insertions, 0 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index ed207896..42a0f6bb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -87,6 +87,9 @@ class LoginActivity : BaseActivity() {
toolbar(toolbar)
}
profileLoader = GlideApp.with(profile)
+ swipeRefresh.setOnChildScrollUpCallback { parent, child ->
+ web.canScrollVertically(-1)
+ }
launch {
for (refreshing in refreshChannel.uniqueOnly(this)) {
if (refreshing) swipeRefresh.isEnabled = true
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/SwipeRefreshLayout.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/SwipeRefreshLayout.kt
new file mode 100644
index 00000000..0ab11fc6
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/SwipeRefreshLayout.kt
@@ -0,0 +1,78 @@
+package com.pitchedapps.frost.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewConfiguration
+import android.webkit.WebView
+import android.widget.ListView
+import androidx.core.widget.ListViewCompat
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnChildScrollUpCallback
+import com.pitchedapps.frost.utils.L
+
+/**
+ * Variant that forbids refreshing if child layout is not at the top
+ * Inspired by https://github.com/slapperwan/gh4a/blob/master/app/src/main/java/com/gh4a/widget/SwipeRefreshLayout.java
+ *
+ */
+class SwipeRefreshLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+ SwipeRefreshLayout(context, attrs) {
+
+ private var preventRefresh: Boolean = false
+ private var downY: Float = -1f
+ private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
+
+ /**
+ * Copy of [canChildScrollUp], with additional support if necessary
+ */
+ private val canChildScrollUp = OnChildScrollUpCallback { parent, child ->
+ when (child) {
+ is WebView -> child.canScrollVertically(-1).apply {
+ L.d { "Webview can scroll up $this" }
+ }
+ is ListView -> ListViewCompat.canScrollList(child, -1)
+ // Supports webviews as well
+ else -> child?.canScrollVertically(-1) ?: false
+ }
+ }
+
+ init {
+ setOnChildScrollUpCallback(canChildScrollUp)
+ }
+
+ override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
+ if (ev.action != MotionEvent.ACTION_DOWN && preventRefresh) {
+ return false
+ }
+ when (ev.action) {
+ MotionEvent.ACTION_DOWN -> {
+ downY = ev.y
+ preventRefresh = canChildScrollUp()
+ }
+ MotionEvent.ACTION_MOVE -> {
+ if (downY - ev.y > touchSlop) {
+ preventRefresh = true
+ return false
+ }
+ }
+ }
+ return super.onInterceptTouchEvent(ev)
+ }
+
+ override fun onNestedScroll(target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) {
+ if (preventRefresh) {
+ /*
+ * Ignoring offsetInWindow since
+ * 1. It doesn't seem to matter in the typical use case
+ * 2. It isn't being transferred to the underlying array used by the super class
+ */
+ dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null)
+ } else {
+ super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
+ }
+ }
+
+ interface OnRefreshListener : SwipeRefreshLayout.OnRefreshListener
+} \ No newline at end of file