summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/ImageZoomLinks.kt
AgeCommit message (Collapse)Author
37 hoursClose the class: a caller can no longer forget where the article livesPeter Stone
The fix before this made site-relative images zoomable by resolving them against the article's own address. It left the parameter optional, which leaves the bug one forgetful call site away from coming back -- and coming back silently, as every image on a site-relative feed quietly refusing to zoom, which is exactly how it went unnoticed on Ftrain in the first place. It has no default now. Null is still a legitimate answer, because an article with no address genuinely cannot resolve anything, but it has to be given on purpose. A future reader surface that omits it fails to compile rather than shipping the old behaviour. Nothing about what the app does changed: the same 157 tests pass, and the six test call sites that relied on the default now say baseUrl = null, which is what they always meant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
37 hoursMake an image zoomable even when the feed didn't spell out where it livesPeter Stone
Tapping an image in a Ftrain article did nothing. The zoom affordance was there, and the rendering path was the ordinary one -- the feed's own HTML, with reader mode off -- but a tap went nowhere at all. Tap detection works by wrapping every article image in a link to a scheme nothing can navigate to, which the WebView then hands to shouldOverrideUrlLoading. That href has to carry the complete image URL on its own, so an image whose src was relative got no wrapper and no tap: better an image that can't be zoomed, the reasoning went, than a link that goes nowhere. Ftrain's <content:encoded> is entirely site-relative -- every image in it is src="/art/uploads/..." -- so not one of them was zoomable. That reasoning had an unexamined premise. The page itself resolves those srcs perfectly well, against the base URL loadReaderHtml already hands loadDataWithBaseURL: the article's own link. Resolving them the same way at HTML-assembly time produces exactly the URL the WebView went and fetched, so the wrapper can be built after all. Both reader surfaces now pass that base URL down to the zoom pass. Where there genuinely is no base URL to resolve against -- nothing else in the app loads reader HTML without one today -- the old behavior stands and the image stays un-zoomable rather than acquiring a dead link, and a data: or javascript: src is still refused however it was reached, since the viewer could never open one. This is why the report could only have come from a feed with reader mode off. Reader mode never hits it: Readability rewrites every src to an absolute URL before the extracted HTML reaches us, which is also why the same images zoom fine the moment the feed's reader toggle is on. TDD: site-relative and path-relative resolution, and the whole trip through wrapReaderHtml, were written first against the unused parameter and went red on assertion mismatches (3 of 38 in ImageZoomTest), green on the resolution itself. The data:-src case was written at the same time and passed immediately -- it pins existing behavior against the new code path rather than having driven it. Verified on the emulator against the reported article itself, subscribed live from ftrain.com/feed.xml with reader mode off: on the previous build, a tap on the header image left the screen byte-identical; on this one the same tap at the same point opens the full-screen viewer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
2026-09-29Reflow reader text live while pinching, and let a zoomed image panPeter Stone
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.