diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-09-29 07:12:48 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-09-29 07:12:48 +0000 |
| commit | a492e2def3dabe5e8de5ef4486b92859850503db (patch) | |
| tree | 5b8ca48f754b26fbbbbdbebda9686d0b758b9a31 /app/src/main/java/org/terst/feedreader/data | |
| parent | cf8ff865f7764953ded1b93c8ec42d4aff589e81 (diff) | |
Reflow reader text live while pinching, and let a zoomed image pan
Pinching in the reader used to scale the whole WebView like a photo and snap
back to the real font size on release. It now drives WebSettings.textZoom as
the fingers move, so the text itself resizes and reflows during the gesture
with nothing to snap back from; images and margins stay put. The reload at the
new saved size is what returns textZoom to 100%, so the two never overlap --
and loading reader HTML now goes through ReaderWebView.loadReaderHtml, which
does both together, so a future load site can't forget the reset.
Reader view for a tapped link now honors the saved font size and the same
pinch gesture, instead of always rendering at the 18px default.
A zoomed image can be panned again. The viewer computed its pan bounds from
values captured when the dialog first composed -- an empty viewport around a
not-yet-decoded image -- because a pointerInput(Unit) block keeps the lambda it
was created with. Those bounds allowed exactly one offset, 0, so zooming worked
and dragging did nothing. The whole pinch/pan step is now one pure function the
gesture callback calls with values it reads fresh each time.
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/data')
| -rw-r--r-- | app/src/main/java/org/terst/feedreader/data/Settings.kt | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/app/src/main/java/org/terst/feedreader/data/Settings.kt b/app/src/main/java/org/terst/feedreader/data/Settings.kt index ebeba6c..18c5f9d 100644 --- a/app/src/main/java/org/terst/feedreader/data/Settings.kt +++ b/app/src/main/java/org/terst/feedreader/data/Settings.kt @@ -39,12 +39,30 @@ private const val READER_FONT_SIZE_MIN_PX = 14 private const val READER_FONT_SIZE_MAX_PX = 28 val READER_FONT_SIZE_RANGE_PX = READER_FONT_SIZE_MIN_PX..READER_FONT_SIZE_MAX_PX +/** WebView's textZoom baseline: 100% is "render the CSS font sizes exactly as written." */ +const val UNZOOMED_TEXT_ZOOM_PERCENT = 100 + // Pure so the pinch-to-zoom math is testable without a WebView/gesture detector in the loop -- // ReaderWebView.kt calls this once per gesture (at pinch-end, with the cumulative scale factor // accumulated across the whole gesture), not per touch-move frame. fun pinchZoomFontSizePx(basePx: Int, scaleFactor: Float): Int = (basePx * scaleFactor).roundToInt().coerceIn(READER_FONT_SIZE_RANGE_PX.first, READER_FONT_SIZE_RANGE_PX.last) +/** + * The WebView textZoom percentage that makes text laid out at [renderedPx] read as [targetPx]. + * + * This is what makes a pinch reflow live instead of scaling the whole page and snapping back: + * WebView's textZoom re-lays-out the text (and only the text -- images and padding stay put) + * the moment it changes, with no reload and no JavaScript. + * + * [renderedPx] is the size the currently-loaded HTML was actually written at, which isn't always + * the saved font size -- a second pinch can start before the reload from the first one has + * landed. Measuring against the saved size in that window would shrink the text back to the + * old layout for a frame before growing again. + */ +fun readerTextZoomPercent(renderedPx: Int, targetPx: Int): Int = + (targetPx * UNZOOMED_TEXT_ZOOM_PERCENT / renderedPx.coerceAtLeast(1).toFloat()).roundToInt() + /** Stash connection settings, configured on the Settings screen. Both blank until set. */ class Settings(private val context: Context) { val stashBaseUrl: Flow<String> = |
