General improvements (#151)

* Updated folder synchronization logic and redesigned the file type filter dialog.

* Fixed CFI generation and navigation stability in the EPUB reader.

* Improved CFI scrolling and position calculation in the EPUB reader by implementing text node traversal using `TreeWalker`. This ensures accurate positioning and scrolling when a CFI offset spans multiple fragmented text nodes.

* fix fb2 multiline titles, retain footnotes, and prevent stream leaks

- Fix FB2 titles with multiple paragraphs by inserting breaks/spaces
- Prevent resource leaks by properly closing InputStreams in all importers
- Retain "notes" and "comments" sections in FB2 instead of skipping them
- Add support for FB2 poem, stanza, cite, and link tags

* Implement persistence for zoom and pan states when pan lock is enabled in the PDF reader.

* Added `FileTypeBadge` to home and library screens

* Bump version to 1.0.41(42)
This commit is contained in:
Aryan 2026-04-05 10:36:44 +05:30 committed by GitHub
parent 65e0570d0e
commit 26692d2c05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 747 additions and 664 deletions

View file

@ -432,6 +432,7 @@ internal fun PdfPageComposable(
draggingBoxId: String? = null,
isScrollLocked: Boolean = false,
isVisible: Boolean = true,
isActivePage: Boolean = true,
isStylusOnlyMode: Boolean = false,
isHighlighterSnapEnabled: Boolean = false,
userHighlights: List<PdfUserHighlight> = emptyList(),
@ -442,7 +443,9 @@ internal fun PdfPageComposable(
onTts: (Int, Int) -> Unit = { _, _ -> },
activeToolThickness: Float = 0f,
customHighlightColors: Map<PdfHighlightColor, Color> = emptyMap(),
onPaletteClick: (() -> Unit)? = null
onPaletteClick: (() -> Unit)? = null,
lockedState: Triple<Float, Float, Float>? = null,
onZoomAndPanChanged: ((Float, Offset) -> Unit)? = null
) {
val pdfDocumentItem = pdfDocument.item
var bitmapState by remember { mutableStateOf(PdfThumbnailCache.get(pageIndex)) }
@ -474,6 +477,10 @@ internal fun PdfPageComposable(
var scale by remember { mutableFloatStateOf(1f) }
var offset by remember { mutableStateOf(Offset.Zero) }
LaunchedEffect(scale, offset) {
onZoomAndPanChanged?.invoke(scale, offset)
}
val currentOnSingleTap by rememberUpdatedState(onSingleTap)
val currentOnDoubleTap by rememberUpdatedState(onDoubleTap)
@ -720,12 +727,6 @@ internal fun PdfPageComposable(
}
}
LaunchedEffect(pageIndex) {
scale = 1f
offset = Offset.Zero
onScaleChanged(1f)
}
LaunchedEffect(isPerformingOcrForSelection) { onOcrStateChange(isPerformingOcrForSelection) }
LaunchedEffect(
@ -1067,9 +1068,10 @@ internal fun PdfPageComposable(
canvasHeightPx.floatValue,
isVerticalScroll,
isScrolling,
virtualPage
virtualPage,
isActivePage
) {
val needsTiling = effectiveScale > 1f || actualBitmapWidthPx > 3000 || actualBitmapHeightPx > 3000
val needsTiling = (effectiveScale > 1f || actualBitmapWidthPx > 3000 || actualBitmapHeightPx > 3000) && (isVerticalScroll || isActivePage)
if (!needsTiling) {
if (tiles.isNotEmpty()) {
val oldTiles = tiles
@ -2594,7 +2596,7 @@ internal fun PdfPageComposable(
}
}
}, onDoubleTap = { tapOffset ->
if (isZoomEnabled && !isVerticalScroll) {
if (isZoomEnabled && !isVerticalScroll && !isScrollLocked) {
if (actualBitmapWidthPx == 0) return@detectTapGestures
coroutineScope.launch {
val startScale = scale
@ -2689,7 +2691,11 @@ internal fun PdfPageComposable(
if (!canceled) {
val rawPanChange = event.calculatePan()
val panChange = if (isScrollLocked) Offset(0f, rawPanChange.y) else rawPanChange
val panChange = if (isScrollLocked && pointerCount == 1) {
if (isVerticalScroll) Offset(0f, rawPanChange.y) else Offset.Zero
} else {
rawPanChange
}
val zoomChange = event.calculateZoom()
if (scale > 1f) {
@ -3112,14 +3118,21 @@ internal fun PdfPageComposable(
}
LaunchedEffect(
this@BoxWithConstraints.maxWidth, this@BoxWithConstraints.maxHeight
pageIndex, this@BoxWithConstraints.maxWidth, this@BoxWithConstraints.maxHeight,
isScrollLocked, lockedState
) {
scale = 1f
offset = Offset.Zero
onScaleChanged(1f)
if (isScrollLocked && !isVerticalScroll && lockedState != null) {
scale = lockedState.first
offset = Offset(lockedState.second, lockedState.third)
onScaleChanged(scale)
} else if (!isScrollLocked && !isVerticalScroll) {
scale = 1f
offset = Offset.Zero
onScaleChanged(1f)
}
Timber.d(
"PdfPageComposable Page $pageIndex | Constraints: maxWidth=${this@BoxWithConstraints.maxWidth}, maxHeight=${this@BoxWithConstraints.maxHeight}"
"PdfPageComposable Page $pageIndex initialized/resized/locked. scale=$scale, offset=$offset"
)
}