feat(pdf): wire double-tap to toggle zoom in viewer

The zoomable library's onDoubleTap callback is not wired by default,
so double-tapping the PDF page did nothing — no scale change, no
hi-res re-render. Pass an onDoubleTap handler that calls
zoomState.toggleScale(2.5x, tapPosition). The scale animation runs
through the same Animatable snapshotFlow already observes, so the
debounced hi-res render kicks in automatically once the animation
settles.
This commit is contained in:
Claude
2026-04-19 16:14:43 +00:00
parent e244271bd0
commit 0c88b83c3f
@@ -85,6 +85,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import net.engawapg.lib.zoomable.rememberZoomState
import net.engawapg.lib.zoomable.toggleScale
import net.engawapg.lib.zoomable.zoomable
// Hard ceiling on each base-rendered page bitmap, in pixels. Higher = sharper when
@@ -100,6 +101,10 @@ private const val HI_RES_MAX_DIM_PX = 6144
private const val HI_RES_ZOOM_THRESHOLD = 1.2f
private const val HI_RES_DEBOUNCE_MS = 200L
// Zoom level the viewer animates to when the user double-taps. Matches the
// threshold region where we swap in the hi-res bitmap.
private const val DOUBLE_TAP_ZOOM_SCALE = 2.5f
// How many recently-rendered pages to keep around. Pager already pre-composes the
// current page plus one neighbor; this just speeds up small back/forward swipes.
// At VIEWER_MAX_DIM_PX = 3072 this caps memory at ~80 MB worth of page bitmaps.
@@ -357,7 +362,12 @@ private fun PdfPageView(
modifier =
Modifier
.fillMaxSize()
.zoomable(zoomState),
.zoomable(
zoomState = zoomState,
onDoubleTap = { position ->
zoomState.toggleScale(targetScale = DOUBLE_TAP_ZOOM_SCALE, position = position)
},
),
)
} else {
CircularProgressIndicator(color = Color.White)