Improved TOC scrolling behavior and fixed incorrect content indentation logic. Added test for image-only sections.

This commit is contained in:
Sergey Chernov 2026-05-25 20:48:44 +03:00
parent 7681590992
commit 9f54c0aca0
3 changed files with 63 additions and 1 deletions

View File

@ -1551,7 +1551,7 @@ internal fun buildReaderContentPlan(book: Fb2Book): ReaderContentPlan {
}
}
}
val childDepth = if (blocks.isEmpty()) readerDepth else readerDepth + 1
val childDepth = if (blocks.hasIndentBearingContent()) readerDepth + 1 else readerDepth
addSections(section.sections, childDepth)
}
@ -1811,6 +1811,19 @@ private fun Fb2Section.readableBlocks(): List<Fb2Block> =
images.map(Fb2Block::Image) + paragraphs.map { Fb2Block.Paragraph(Fb2Text(listOf(Fb2TextSpan(it)))) }
}
private fun List<Fb2Block>.hasIndentBearingContent(): Boolean =
any { block ->
when (block) {
Fb2Block.EmptyLine,
is Fb2Block.Image,
is Fb2Block.Subtitle -> false
is Fb2Block.Cite,
is Fb2Block.Epigraph,
is Fb2Block.Paragraph,
is Fb2Block.Poem -> true
}
}
private data class ChapterEntry(
val title: String,
val section: Fb2Section,

View File

@ -693,11 +693,23 @@ private fun TableOfContentsDialog(
onOpenEntry: (ReaderTocEntry) -> Unit,
onDismiss: () -> Unit,
) {
val selectedEntryIndex = currentItemIndex?.let { itemIndex ->
contentPlan.tocEntries.indexOfFirst { it.itemIndex == itemIndex }.takeIf { it >= 0 }
}
val listState = rememberLazyListState(
initialFirstVisibleItemIndex = selectedEntryIndex?.let { it + 1 } ?: 0,
)
LaunchedEffect(contentPlan, selectedEntryIndex) {
selectedEntryIndex?.let { listState.scrollToItem(it + 1) }
}
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(strings.tableOfContents) },
text = {
LazyColumn(
state = listState,
modifier = Modifier.fillMaxWidth().heightIn(max = 480.dp),
) {
item(key = "back") {

View File

@ -6,6 +6,7 @@ import net.sergeych.toread.fb2.Fb2Block
import net.sergeych.toread.fb2.Fb2Book
import net.sergeych.toread.fb2.Fb2Epigraph
import net.sergeych.toread.fb2.Fb2EpigraphBlock
import net.sergeych.toread.fb2.Fb2ImageRef
import net.sergeych.toread.fb2.Fb2Poem
import net.sergeych.toread.fb2.Fb2PoemBlock
import net.sergeych.toread.fb2.Fb2Section
@ -275,6 +276,42 @@ class ReadAloudContentPlanTest {
)
}
@Test
fun imageOnlyPartStructureDoesNotIndentWholeBook() {
val plan = buildReaderContentPlan(
Fb2Book(
title = "Book",
sections = listOf(
Fb2Section(
title = "Wrapper title",
sections = listOf(
Fb2Section(
images = listOf(Fb2ImageRef("#front.jpg")),
),
Fb2Section(
title = "Part one",
blocks = listOf(Fb2Block.Image(Fb2ImageRef("#part.png"))),
sections = listOf(
Fb2Section(
title = "Chapter one",
blocks = listOf(paragraph("Chapter text.")),
),
),
),
),
),
),
),
)
assertEquals(0, plan.elements.filterIsInstance<ReaderElement.Paragraph>().single().depth)
assertEquals(
listOf(0, 0, 0),
plan.elements.filterIsInstance<ReaderElement.SectionTitle>().map { it.depth },
)
assertEquals(listOf(0, 0, 0, 0), plan.tocEntries.map { it.depth })
}
@Test
fun realNestedSectionsKeepRelativeIndent() {
val plan = buildReaderContentPlan(