🛠️ Always show chapters in Reader

* In all file formats (except EPUB) using first line as chapter title (which is usually book title)
This commit is contained in:
Acclorite 2024-10-07 17:33:40 +03:00
parent 5728253988
commit fefeecd650
7 changed files with 53 additions and 21 deletions

View file

@ -8,10 +8,11 @@ import org.w3c.dom.Element
import org.w3c.dom.NodeList
import ua.acclorite.book_story.R
import ua.acclorite.book_story.data.parser.TextParser
import ua.acclorite.book_story.domain.model.Chapter
import ua.acclorite.book_story.domain.model.ChapterWithText
import ua.acclorite.book_story.domain.util.Resource
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
import java.io.File
import javax.inject.Inject
import javax.xml.parsers.DocumentBuilderFactory
@ -114,15 +115,23 @@ class Fb2TextParser @Inject constructor() : TextParser {
yield()
if (formattedLines.isEmpty()) {
if (formattedLines.size < 2) {
return Resource.Error(UIText.StringResource(R.string.error_file_empty))
}
val title = formattedLines.first().clearMarkdown()
formattedLines.removeAt(0)
Log.i(FB2_TAG, "Successfully finished FB2 parsing.")
Resource.Success(
listOf(
ChapterWithText(
chapter = Constants.EMPTY_CHAPTER,
chapter = Chapter(
index = 0,
title = title,
startIndex = 0,
endIndex = formattedLines.lastIndex
),
text = formattedLines
)
)

View file

@ -10,6 +10,7 @@ import ua.acclorite.book_story.domain.model.Chapter
import ua.acclorite.book_story.domain.model.ChapterWithText
import ua.acclorite.book_story.domain.util.Resource
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
import java.io.File
import javax.inject.Inject
@ -23,20 +24,30 @@ class HtmlTextParser @Inject constructor(
Log.i(HTML_TAG, "Started HTML parsing: ${file.name}.")
return try {
val lines = documentParser.run { Jsoup.parse(file).parseDocument() }
val lines = documentParser.run {
Jsoup.parse(file).parseDocument()
}.toMutableList()
yield()
if (lines.isEmpty()) {
if (lines.size < 2) {
Log.e(HTML_TAG, "Could not extract text from HTML.")
return Resource.Error(UIText.StringResource(R.string.error_file_empty))
}
val title = lines.first().clearMarkdown()
lines.removeAt(0)
Log.i(HTML_TAG, "Successfully finished HTML parsing.")
Resource.Success(
listOf(
ChapterWithText(
chapter = Chapter(title = "", startIndex = 0, endIndex = 0),
chapter = Chapter(
index = 0,
title = title,
startIndex = 0,
endIndex = lines.lastIndex
),
text = lines
)
)

View file

@ -8,10 +8,11 @@ import com.tom_roush.pdfbox.text.PDFTextStripper
import kotlinx.coroutines.yield
import ua.acclorite.book_story.R
import ua.acclorite.book_story.data.parser.TextParser
import ua.acclorite.book_story.domain.model.Chapter
import ua.acclorite.book_story.domain.model.ChapterWithText
import ua.acclorite.book_story.domain.util.Resource
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
import java.io.File
import javax.inject.Inject
@ -116,15 +117,23 @@ class PdfTextParser @Inject constructor(
yield()
if (strings.isEmpty()) {
if (strings.size < 2) {
return Resource.Error(UIText.StringResource(R.string.error_file_empty))
}
val title = strings.first().clearMarkdown()
strings.removeAt(0)
Log.i(PDF_TAG, "Successfully finished PDF parsing.")
Resource.Success(
listOf(
ChapterWithText(
chapter = Constants.EMPTY_CHAPTER,
chapter = Chapter(
index = 0,
title = title,
startIndex = 0,
endIndex = strings.lastIndex
),
text = strings
)
)

View file

@ -6,10 +6,11 @@ import kotlinx.coroutines.withContext
import kotlinx.coroutines.yield
import ua.acclorite.book_story.R
import ua.acclorite.book_story.data.parser.TextParser
import ua.acclorite.book_story.domain.model.Chapter
import ua.acclorite.book_story.domain.model.ChapterWithText
import ua.acclorite.book_story.domain.util.Resource
import ua.acclorite.book_story.domain.util.UIText
import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.util.clearMarkdown
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
@ -37,15 +38,23 @@ class TxtTextParser @Inject constructor() : TextParser {
yield()
if (lines.isEmpty()) {
if (lines.size < 2) {
return Resource.Error(UIText.StringResource(R.string.error_file_empty))
}
val title = lines.first().clearMarkdown()
lines.removeAt(0)
Log.i(TXT_TAG, "Successfully finished TXT parsing.")
Resource.Success(
listOf(
ChapterWithText(
chapter = Constants.EMPTY_CHAPTER,
chapter = Chapter(
index = 0,
title = title,
startIndex = 0,
endIndex = lines.lastIndex
),
text = lines
)
)

View file

@ -181,10 +181,7 @@ class BookRepositoryImpl @Inject constructor(
)
}
data!!.map { it.text }.flatten() to data.map { it.chapter }.run {
if (size < 2) return@run emptyList()
return@run this
}
data!!.map { it.text }.flatten() to data.map { it.chapter }
}
Log.i(CHECK_FOR_TEXT_UPDATE, "Successfully got new text and chapters.")

View file

@ -167,10 +167,7 @@ class FileSystemRepositoryImpl @Inject constructor(
return NotNull(
bookWithTextAndCover = BookWithTextAndCover(
book = parsedBook.book.copy(
chapters = parsedText.data!!.map { it.chapter }.run {
if (this.size == 1) return@run emptyList()
this
}
chapters = parsedText.data!!.map { it.chapter } //todo remove this and make every parser take first line as chapter title(exc epub ofc)
),
coverImage = parsedBook.coverImage,
text = parsedText.data.map {

View file

@ -596,7 +596,7 @@ class ReaderViewModel @Inject constructor(
.distinctUntilChanged()
.debounce(300)
.collectLatest { index ->
if (_state.value.book.chapters.size < 2) {
if (_state.value.book.chapters.isEmpty()) {
_state.update {
it.copy(
currentChapter = null