summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-22 19:14:44 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-22 19:14:44 +0000
commit7b0be4757356af46df1eb55d596f819c21b00f3e (patch)
tree53d1fb08c5e4d32a7a53c9084dcdb8474fcfb5eb /app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
parent36ed34cd9ccd7388b96510e0225afe96979403a9 (diff)
Fix scroll regression and feed-setting reset on re-import
- ReaderScreen: the direction-ratio gesture rewrite (using a generic, non-oriented detectDragGestures to compute a custom dx/dy ratio) broke scrolling entirely -- reported live as "the article view doesn't scroll at all anymore." Root cause: detectDragGestures' touch-slop detection is isotropic (claims the first bit of movement in ANY direction before it knows which way the gesture is going), unlike detectHorizontalDragGestures which is orientation-aware and simply never engages for a vertical- dominant drag. Reverted to detectHorizontalDragGestures, keeping the distance-based (not edge-anchored) commit threshold from the previous fix. Verified live: a long article now scrolls properly on a diagonal swipe, and a deliberate horizontal swipe still changes pages. - AddFeedScreen: both the OPML import and single-URL add built a bare FeedEntity(id, title, siteUrl) and upserted it (REPLACE) even when a feed with that id already existed -- silently wiping readerModeDisabled (and etag/lastModified/lastError) back to defaults on every re-import or re-add. This is exactly what made a feed's reader-mode toggle appear not to persist. Now preserves the existing row via .copy() when one exists. Verified live: set kottke.org's readerModeDisabled=1, re-imported the same OPML file (107 feeds), and confirmed the flag was still 1 afterward.
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt70
1 files changed, 27 insertions, 43 deletions
diff --git a/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt b/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
index 9b53f8c..eae11af 100644
--- a/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
+++ b/app/src/main/java/org/terst/feedreader/ui/ReaderScreen.kt
@@ -3,7 +3,7 @@ package org.terst.feedreader.ui
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.gestures.detectDragGestures
+import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@@ -58,7 +58,6 @@ import org.terst.feedreader.readability.ReaderExtractor
import org.terst.feedreader.stash.StashClient
import org.terst.feedreader.stash.StashSaveResult
import java.net.URLEncoder
-import kotlin.math.abs
// Below this length (of the plain feed-provided HTML), assume it's a teaser/summary,
// not the real article body, and auto-fall-back to on-device Readability extraction.
@@ -106,59 +105,44 @@ fun ReaderScreen(
val initialIndex = safeIds.indexOf(initialArticleId).coerceAtLeast(0)
val pagerState = rememberPagerState(initialPage = initialIndex) { safeIds.size }
val scope = rememberCoroutineScope()
- val directionLockPx = with(LocalDensity.current) { 16.dp.toPx() }
val swipeThresholdPx = with(LocalDensity.current) { 80.dp.toPx() }
// HorizontalPager's own full-surface drag detection was grabbing ordinary vertical
// scrolling inside the embedded WebView (a native View, which doesn't arbitrate with
// Compose's gesture system the way a pure-Compose scrollable child would) as an
- // attempted horizontal page-turn on anything less than a perfectly vertical swipe --
- // which is most real thumb scrolling. An edge-zone-gated version of this was tried
- // first, but on gesture-nav Android the screen edges belong to the OS's own back
- // gesture, which wins before the app ever sees the touch (confirmed live: an edge
- // swipe triggered system back, not the pager). So instead: disable the Pager's own
- // gesture and drive it from a detector that works anywhere on screen but only commits
- // to a page turn once the drag is clearly horizontal-dominant (>2x the vertical
- // movement) -- ordinary scrolling, even sloppy/diagonal, stays vertical-dominant and
- // is left completely unconsumed for the WebView to handle normally.
+ // attempted horizontal page-turn on anything less than a perfectly vertical swipe.
+ // detectHorizontalDragGestures has its own orientation-aware touch-slop detection, so
+ // it already declines to engage for vertical-dominant movement -- confirmed live: a
+ // diagonal mid-screen scroll stays vertical, doesn't page-turn. (A generic,
+ // non-oriented detectDragGestures was tried for a stricter dx/dy ratio check and broke
+ // scrolling entirely: its slop detector claims the first bit of movement in ANY
+ // direction isotropically, before it knows which way the gesture is really going --
+ // reported live as "the article view doesn't scroll at all anymore.") Also: page-turn
+ // commit is based on total drag distance, not where the gesture started, since an
+ // edge-anchored version collided with Android's own edge-swipe-back gesture (confirmed
+ // live: an edge swipe triggered system back, not the pager).
Box(
modifier = Modifier
.fillMaxSize()
.pointerInput(safeIds.size) {
- var totalDx = 0f
- var totalDy = 0f
- var committedHorizontal = false
- detectDragGestures(
- onDragStart = {
- totalDx = 0f
- totalDy = 0f
- committedHorizontal = false
- },
- onDragCancel = { committedHorizontal = false },
+ var totalDrag = 0f
+ detectHorizontalDragGestures(
+ onDragStart = { totalDrag = 0f },
+ onDragCancel = { totalDrag = 0f },
onDragEnd = {
- if (committedHorizontal) {
- val direction = when {
- totalDx <= -swipeThresholdPx -> 1
- totalDx >= swipeThresholdPx -> -1
- else -> 0
- }
- if (direction != 0) {
- val target = (pagerState.currentPage + direction).coerceIn(0, safeIds.size - 1)
- scope.launch { pagerState.animateScrollToPage(target) }
- }
+ val direction = when {
+ totalDrag <= -swipeThresholdPx -> 1
+ totalDrag >= swipeThresholdPx -> -1
+ else -> 0
}
- committedHorizontal = false
- },
- onDrag = { change, dragAmount ->
- totalDx += dragAmount.x
- totalDy += dragAmount.y
- if (!committedHorizontal &&
- abs(totalDx) > directionLockPx &&
- abs(totalDx) > abs(totalDy) * 2f
- ) {
- committedHorizontal = true
+ if (direction != 0) {
+ val target = (pagerState.currentPage + direction).coerceIn(0, safeIds.size - 1)
+ scope.launch { pagerState.animateScrollToPage(target) }
}
- if (committedHorizontal) change.consume()
+ },
+ onHorizontalDrag = { change, dragAmount ->
+ change.consume()
+ totalDrag += dragAmount
}
)
}