diff --git a/CHANGELOG.md b/CHANGELOG.md index e22d8b764..c140b5fce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co - `Other` - for technical stuff. ## [Unreleased] +### Changed +- LocalSource now reads ComicInfo.xml file for chapter (if available) to display chapter title, number and scanlator ([@raxod502](https://github.com/radian-software)) ([#2332](https://github.com/mihonapp/mihon/pull/2332)) + ### Fixes - Fixed scrollbar sometimes not showing during scroll or not reaching the bottom with few items ([@anirudhsnayak](https://github.com/anirudhsnayak)) ([#2304](https://github.com/mihonapp/mihon/pull/2304)) diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt index 3e4dd32cc..fc1d42112 100644 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/LocalSource.kt @@ -190,7 +190,7 @@ actual class LocalSource( noXmlFile == null -> { val chapterArchives = mangaDirFiles.filter(Archive::isSupported) - val copiedFile = copyComicInfoFileFromArchive(chapterArchives, mangaDir) + val copiedFile = copyComicInfoFileFromChapters(chapterArchives, mangaDir) if (copiedFile != null) { setMangaDetailsFromComicInfoFile(copiedFile.openInputStream(), manga) } else { @@ -206,13 +206,24 @@ actual class LocalSource( return@withIOContext manga } - private fun copyComicInfoFileFromArchive(chapterArchives: List, folder: UniFile): UniFile? { - for (chapter in chapterArchives) { - chapter.archiveReader(context).use { reader -> - reader.getInputStream(COMIC_INFO_FILE)?.use { stream -> - return copyComicInfoFile(stream, folder) - } + private fun getComicInfoForChapter(chapter: UniFile, block: (InputStream) -> T): T? { + if (chapter.isDirectory) { + return chapter.findFile(COMIC_INFO_FILE)?.let { file -> + file.openInputStream().use(block) } + } else { + return chapter.archiveReader(context).use { reader -> + reader.getInputStream(COMIC_INFO_FILE)?.use(block) + } + } + } + + private fun copyComicInfoFileFromChapters(chapterArchives: List, folder: UniFile): UniFile? { + for (chapter in chapterArchives) { + val file = getComicInfoForChapter(chapter) f@{ stream -> + return@f copyComicInfoFile(stream, folder) + } + if (file != null) return file } return null } @@ -225,12 +236,22 @@ actual class LocalSource( } } - private fun setMangaDetailsFromComicInfoFile(stream: InputStream, manga: SManga) { - val comicInfo = AndroidXmlReader(stream, StandardCharsets.UTF_8.name()).use { + private fun parseComicInfo(stream: InputStream): ComicInfo { + return AndroidXmlReader(stream, StandardCharsets.UTF_8.name()).use { xml.decodeFromReader(it) } + } - manga.copyFromComicInfo(comicInfo) + private fun setMangaDetailsFromComicInfoFile(stream: InputStream, manga: SManga) { + manga.copyFromComicInfo(parseComicInfo(stream)) + } + + private fun setChapterDetailsFromComicInfoFile(stream: InputStream, chapter: SChapter) { + val comicInfo = parseComicInfo(stream) + + comicInfo.title?.let { chapter.name = it.value } + comicInfo.number?.value?.toFloatOrNull()?.let { chapter.chapter_number = it } + comicInfo.translator?.let { chapter.scanlator = it.value } } // Chapters @@ -257,6 +278,10 @@ actual class LocalSource( format.file.epubReader(context).use { epub -> epub.fillMetadata(manga, this) } + } else { + getComicInfoForChapter(chapterFile) { stream -> + setChapterDetailsFromComicInfoFile(stream, this) + } } } }