From e04bb0aca72bb306f5a3b07d221e0adf3bf8ac16 Mon Sep 17 00:00:00 2001 From: Acclorite <140836141+Acclorite@users.noreply.github.com> Date: Sat, 28 Sep 2024 12:53:02 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=20Improve=20Chapter=20par?= =?UTF-8?q?sing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Made parsing more universal (more books are supported) --- .../ua/acclorite/book_story/Application.kt | 3 +- .../data/mapper/book/BookMapperImpl.kt | 2 +- .../book_story/data/parser/DocumentParser.kt | 7 +---- .../data/parser/epub/EpubTextParser.kt | 31 ++++++++++++------- .../data/parser/htm/HtmTextParser.kt | 2 +- .../data/parser/html/HtmlTextParser.kt | 2 +- .../core/components/AnimatedTopAppBar.kt | 2 +- .../core/navigation/Navigation.kt | 2 +- 8 files changed, 27 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/ua/acclorite/book_story/Application.kt b/app/src/main/java/ua/acclorite/book_story/Application.kt index 4732ef7f..0fcbac19 100644 --- a/app/src/main/java/ua/acclorite/book_story/Application.kt +++ b/app/src/main/java/ua/acclorite/book_story/Application.kt @@ -3,7 +3,6 @@ package ua.acclorite.book_story import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager -import android.content.Context import dagger.hilt.android.HiltAndroidApp import ua.acclorite.book_story.data.local.notification.UpdatesNotificationService @@ -23,7 +22,7 @@ class Application : Application() { ) val notificationManager = getSystemService( - Context.NOTIFICATION_SERVICE + NOTIFICATION_SERVICE ) as NotificationManager notificationManager.createNotificationChannel(channel) } diff --git a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt index a2b59c7c..fcb3944a 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/mapper/book/BookMapperImpl.kt @@ -19,7 +19,7 @@ class BookMapperImpl @Inject constructor() : BookMapper { author = book.author.getAsString(), textPath = book.textPath, description = book.description, - image = if (book.coverImage != null) book.coverImage.toString() else null, + image = book.coverImage?.toString(), category = book.category, chapters = book.chapters ) diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt index b5efb63a..9b0a0e97 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/DocumentParser.kt @@ -7,11 +7,10 @@ import javax.inject.Inject class DocumentParser @Inject constructor() { /** * Parses document to get it's text. - * If [fragment] is not null, searches document for specific [fragment]. * * @return Parsed text line by line. */ - suspend fun Document.parseDocument(fragment: String?): List { + suspend fun Document.parseDocument(): List { val lines = mutableListOf() yield() @@ -32,10 +31,6 @@ class DocumentParser @Inject constructor() { yield() body() - .run { - fragment?.let { return@run getElementById(it) ?: this } - this - } .wholeText() .lines() .forEach { line -> diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt index 09355b26..5bc26d18 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/epub/EpubTextParser.kt @@ -107,7 +107,7 @@ class EpubTextParser @Inject constructor( it.readText() } - val chapter = documentParser.run { Jsoup.parse(content).parseDocument(fragment = null) } + val chapter = documentParser.run { Jsoup.parse(content).parseDocument() } if (chapter.isEmpty()) { Log.w(EPUB_TAG, "Chapter ${entry.name} is empty.") return@forEach @@ -146,7 +146,7 @@ class EpubTextParser @Inject constructor( private suspend fun parseWithToc(tocEntry: ZipEntry, zip: ZipFile): List? { Log.i(EPUB_TAG, "TOC Entry: ${tocEntry.name}") - val chapters = mutableListOf() + val chapters = mutableMapOf() var emptyChapters = 0 var chapterTextIndex = -1 var chapterIndex = 1 @@ -172,12 +172,22 @@ class EpubTextParser @Inject constructor( return null } - val uri = Uri.parse(this) ?: return@run this to null - (uri.path ?: this) to uri.fragment + Uri.parse(this).path ?: this } + if (chapters.containsKey(chapterSrc)) { + chapters[chapterSrc] = chapters[chapterSrc]!!.run { + copy( + chapter = chapter.copy( + title = "${chapter.title} / $chapterTitle" + ) + ) + } + return@forEach + } + zip.entries().asSequence().find { entry -> - entry.name.endsWith(chapterSrc.first) + entry.name.endsWith(chapterSrc) }.apply { if (this == null) { Log.e(EPUB_TAG, "No chapter entry found: $chapterTitle") @@ -191,9 +201,7 @@ class EpubTextParser @Inject constructor( } val chapter = documentParser.run { - Jsoup.parse(content).parseDocument( - fragment = chapterSrc.second - ).dropWhile { + Jsoup.parse(content).parseDocument().dropWhile { it == chapterTitle // Remove chapter title if present } } @@ -203,8 +211,9 @@ class EpubTextParser @Inject constructor( return@forEach } - chapters.add( - ChapterWithText( + chapters.put( + key = chapterSrc, + value = ChapterWithText( chapter = Chapter( index = chapters.size, title = chapterTitle, @@ -231,6 +240,6 @@ class EpubTextParser @Inject constructor( return null } - return chapters + return chapters.values.toList().sortedBy { it.chapter.index } } } \ No newline at end of file diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/htm/HtmTextParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/htm/HtmTextParser.kt index ee513b21..f6b4e95b 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/htm/HtmTextParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/htm/HtmTextParser.kt @@ -23,7 +23,7 @@ class HtmTextParser @Inject constructor( Log.i(HTM_TAG, "Started HTM parsing: ${file.name}.") return try { - val lines = documentParser.run { Jsoup.parse(file).parseDocument(null) } + val lines = documentParser.run { Jsoup.parse(file).parseDocument() } yield() diff --git a/app/src/main/java/ua/acclorite/book_story/data/parser/html/HtmlTextParser.kt b/app/src/main/java/ua/acclorite/book_story/data/parser/html/HtmlTextParser.kt index e4fddf89..16b1f23b 100644 --- a/app/src/main/java/ua/acclorite/book_story/data/parser/html/HtmlTextParser.kt +++ b/app/src/main/java/ua/acclorite/book_story/data/parser/html/HtmlTextParser.kt @@ -23,7 +23,7 @@ class HtmlTextParser @Inject constructor( Log.i(HTML_TAG, "Started HTML parsing: ${file.name}.") return try { - val lines = documentParser.run { Jsoup.parse(file).parseDocument(null) } + val lines = documentParser.run { Jsoup.parse(file).parseDocument() } yield() diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/components/AnimatedTopAppBar.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/components/AnimatedTopAppBar.kt index 0a1960de..b0151158 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/core/components/AnimatedTopAppBar.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/components/AnimatedTopAppBar.kt @@ -72,7 +72,7 @@ fun AnimatedTopAppBar( Box(modifier = Modifier.fillMaxWidth()) { animatedTopBars.forEach { data -> CustomAnimatedVisibility( - visible = data.contentVisibility ?: false, + visible = data.contentVisibility == true, enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)), exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow)) ) { diff --git a/app/src/main/java/ua/acclorite/book_story/presentation/core/navigation/Navigation.kt b/app/src/main/java/ua/acclorite/book_story/presentation/core/navigation/Navigation.kt index d824d0cb..04a15065 100644 --- a/app/src/main/java/ua/acclorite/book_story/presentation/core/navigation/Navigation.kt +++ b/app/src/main/java/ua/acclorite/book_story/presentation/core/navigation/Navigation.kt @@ -244,7 +244,7 @@ class Navigator @AssistedInject constructor( savedStateHandle[USE_BACK_ANIM] = useBackAnimation savedStateHandle[CURRENT_SCREEN] = backStack.value.last() - backStack.value.removeLast() + backStack.value.removeAt(backStack.value.lastIndex) } }