diff --git a/app/build.gradle b/app/build.gradle index 96f89da3d..490d40938 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -82,7 +82,7 @@ afterEvaluate { } dependencies { //noinspection GradleDependency - implementation('com.github.KotatsuApp:kotatsu-parsers:8852d1e22e') { + implementation('com.github.KotatsuApp:kotatsu-parsers:a8f9423307') { exclude group: 'org.json', module: 'json' } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/Manga.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/Manga.kt index d2b579b10..f98d055ae 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/Manga.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/Manga.kt @@ -13,6 +13,8 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaState import org.koitharu.kotatsu.parsers.util.mapToSet +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols import com.google.android.material.R as materialR @JvmName("mangaIds") @@ -113,3 +115,16 @@ val Manga.appUrl: Uri .appendQueryParameter("name", title) .appendQueryParameter("url", url) .build() + +private val chaptersNumberFormat = DecimalFormat("#.#").also { f -> + f.decimalFormatSymbols = DecimalFormatSymbols.getInstance().also { + it.decimalSeparator = '.' + } +} + +fun MangaChapter.formatNumber(): String? { + if (number <= 0f) { + return null + } + return chaptersNumberFormat.format(number.toDouble()) +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/parcelable/ParcelableChapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/parcelable/ParcelableChapter.kt index 190185bdd..3eb99abdc 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/parcelable/ParcelableChapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/parcelable/ParcelableChapter.kt @@ -19,7 +19,8 @@ data class ParcelableChapter( MangaChapter( id = parcel.readLong(), name = parcel.readString().orEmpty(), - number = parcel.readInt(), + number = parcel.readFloat(), + volume = parcel.readInt(), url = parcel.readString().orEmpty(), scanlator = parcel.readString(), uploadDate = parcel.readLong(), @@ -31,7 +32,8 @@ data class ParcelableChapter( override fun ParcelableChapter.write(parcel: Parcel, flags: Int) = with(chapter) { parcel.writeLong(id) parcel.writeString(name) - parcel.writeInt(number) + parcel.writeFloat(number) + parcel.writeInt(volume) parcel.writeString(url) parcel.writeString(scanlator) parcel.writeLong(uploadDate) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt index 55cbdccd5..518dcc800 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/model/ChapterListItem.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.details.ui.model import android.text.format.DateUtils import org.jsoup.internal.StringUtil.StringJoiner +import org.koitharu.kotatsu.core.model.formatNumber import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.MangaChapter @@ -49,8 +50,8 @@ data class ChapterListItem( private fun buildDescription(): String { val joiner = StringJoiner(" • ") - if (chapter.number != 0) { - joiner.add("#").append(chapter.number.toString()) + chapter.formatNumber()?.let { + joiner.add("#").append(it) } uploadDate?.let { date -> joiner.add(date.toString()) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt index 96a884748..8844e3293 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsViewModel.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.plus import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.model.formatNumber import org.koitharu.kotatsu.core.parser.MangaDataRepository import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.RemoteMangaRepository @@ -306,7 +307,7 @@ class DownloadsViewModel @Inject constructor( return chapters.mapNotNullTo(ArrayList(size)) { if (chapterIds == null || it.id in chapterIds) { DownloadChapter( - number = it.number, + number = it.formatNumber(), name = it.name, isDownloaded = it.id in localChapters, ) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/chapters/DownloadChapter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/chapters/DownloadChapter.kt index a9e2b3577..5a77ae407 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/chapters/DownloadChapter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/chapters/DownloadChapter.kt @@ -4,7 +4,7 @@ import org.koitharu.kotatsu.list.ui.ListModelDiffCallback import org.koitharu.kotatsu.list.ui.model.ListModel data class DownloadChapter( - val number: Int, + val number: String?, val name: String, val isDownloaded: Boolean, ) : ListModel { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt index 36368fddf..5bb6be433 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/MangaIndex.kt @@ -12,6 +12,8 @@ import org.koitharu.kotatsu.parsers.model.MangaState import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.parsers.util.find import org.koitharu.kotatsu.parsers.util.json.getBooleanOrDefault +import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault +import org.koitharu.kotatsu.parsers.util.json.getIntOrDefault import org.koitharu.kotatsu.parsers.util.json.getLongOrDefault import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet @@ -91,6 +93,7 @@ class MangaIndex(source: String?) { if (!chapters.has(chapter.id.toString())) { val jo = JSONObject() jo.put("number", chapter.number) + jo.put("volume", chapter.volume) jo.put("url", chapter.url) jo.put("name", chapter.name) jo.put("uploadDate", chapter.uploadDate) @@ -162,7 +165,8 @@ class MangaIndex(source: String?) { id = k.toLong(), name = v.getString("name"), url = v.getString("url"), - number = v.getInt("number"), + number = v.getFloatOrDefault("number", 0f), + volume = v.getIntOrDefault("volume", 0), uploadDate = v.getLongOrDefault("uploadDate", 0L), scanlator = v.getStringOrNull("scanlator"), branch = v.getStringOrNull("branch"), diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaDirInput.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaDirInput.kt index 6ac62b8de..dcf416efc 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaDirInput.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaDirInput.kt @@ -71,7 +71,8 @@ class LocalMangaDirInput(root: File) : LocalMangaInput(root) { MangaChapter( id = "$i${f.name}".longHashCode(), name = f.nameWithoutExtension.toHumanReadable(), - number = i + 1, + number = 0f, + volume = 0, source = MangaSource.LOCAL, uploadDate = f.creationTime, url = f.toUri().toString(), diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaInput.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaInput.kt index 45454631a..13d129235 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaInput.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaInput.kt @@ -100,6 +100,7 @@ sealed class LocalMangaInput( id = id, name = name, number = number, + volume = volume, url = url, scanlator = scanlator, uploadDate = uploadDate, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaZipInput.kt b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaZipInput.kt index cc679b7b6..02b4bcf8a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaZipInput.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/local/data/input/LocalMangaZipInput.kt @@ -76,7 +76,8 @@ class LocalMangaZipInput(root: File) : LocalMangaInput(root) { MangaChapter( id = "$i$s".longHashCode(), name = s.ifEmpty { title }, - number = i + 1, + number = 0f, + volume = 0, source = MangaSource.LOCAL, uploadDate = 0L, url = uriBuilder.fragment(s).build().toString(), diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt index 03473f94f..700144283 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -51,6 +51,7 @@ import org.koitharu.kotatsu.history.data.PROGRESS_NONE import org.koitharu.kotatsu.history.domain.HistoryUpdateUseCase import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaPage +import org.koitharu.kotatsu.parsers.util.assertNotNull import org.koitharu.kotatsu.reader.domain.ChaptersLoader import org.koitharu.kotatsu.reader.domain.DetectReaderModeUseCase import org.koitharu.kotatsu.reader.domain.PageLoader @@ -381,18 +382,20 @@ class ReaderViewModel @Inject constructor( @WorkerThread private fun notifyStateChanged() { - val state = getCurrentState() - val chapter = state?.chapterId?.let { chaptersLoader.peekChapter(it) } + val state = getCurrentState().assertNotNull("state") ?: return + val chapter = chaptersLoader.peekChapter(state.chapterId).assertNotNull("chapter") ?: return + val m = manga.assertNotNull("manga") ?: return + val chapterIndex = m.chapters[chapter.branch]?.indexOf(chapter) ?: -1 val newState = ReaderUiState( - mangaName = manga?.toManga()?.title, - branch = chapter?.branch, - chapterName = chapter?.name, - chapterNumber = chapter?.number ?: 0, - chaptersTotal = manga?.chapters?.get(chapter?.branch)?.size ?: 0, - totalPages = if (chapter != null) chaptersLoader.getPagesCount(chapter.id) else 0, - currentPage = state?.page ?: 0, + mangaName = m.toManga().title, + branch = chapter.branch, + chapterName = chapter.name, + chapterNumber = chapterIndex + 1, + chaptersTotal = m.chapters[chapter.branch]?.size ?: 0, + totalPages = chaptersLoader.getPagesCount(chapter.id), + currentPage = state.page, isSliderEnabled = settings.isReaderSliderEnabled, - percent = if (state != null) computePercent(state.chapterId, state.page) else PROGRESS_NONE, + percent = computePercent(state.chapterId, state.page), ) uiState.value = newState }