Autodetect webtoon
This commit is contained in:
@@ -19,8 +19,7 @@ class MangaPreferencesRepository : KoinComponent {
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getReaderMode(mangaId: Long): ReaderMode {
|
||||
suspend fun getReaderMode(mangaId: Long): ReaderMode? {
|
||||
return db.preferencesDao().find(mangaId)?.let { ReaderMode.valueOf(it.mode) }
|
||||
?: ReaderMode.UNKNOWN
|
||||
}
|
||||
}
|
||||
57
app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt
Normal file
57
app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt
Normal file
@@ -0,0 +1,57 @@
|
||||
package org.koitharu.kotatsu.domain
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Size
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.core.model.MangaPage
|
||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||
import org.koitharu.kotatsu.utils.ext.await
|
||||
import org.koitharu.kotatsu.utils.ext.medianOrNull
|
||||
import java.io.InputStream
|
||||
|
||||
object MangaUtils : KoinComponent {
|
||||
|
||||
/**
|
||||
* Automatic determine type of manga by page size
|
||||
* @return ReaderMode.WEBTOON if page is wide
|
||||
*/
|
||||
suspend fun determineReaderMode(pages: List<MangaPage>): ReaderMode? {
|
||||
try {
|
||||
val page = pages.medianOrNull() ?: return null
|
||||
val url = MangaProviderFactory.create(page.source).getPageFullUrl(page)
|
||||
val client = get<OkHttpClient>()
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.get()
|
||||
.build()
|
||||
val size = client.newCall(request).await().use {
|
||||
getBitmapSize(it.body?.byteStream())
|
||||
}
|
||||
return when {
|
||||
size.width * 2 < size.height -> ReaderMode.WEBTOON
|
||||
else -> ReaderMode.STANDARD
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun getBitmapSize(input: InputStream?): Size {
|
||||
val options = BitmapFactory.Options().apply {
|
||||
inJustDecodeBounds = true
|
||||
}
|
||||
BitmapFactory.decodeStream(input, null, options)
|
||||
val imageHeight: Int = options.outHeight
|
||||
val imageWidth: Int = options.outWidth
|
||||
check(imageHeight > 0 && imageWidth > 0)
|
||||
return Size(imageWidth, imageHeight)
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.koitharu.kotatsu.core.model.MangaPage
|
||||
import org.koitharu.kotatsu.core.prefs.ReaderMode
|
||||
import org.koitharu.kotatsu.domain.MangaPreferencesRepository
|
||||
import org.koitharu.kotatsu.domain.MangaProviderFactory
|
||||
import org.koitharu.kotatsu.domain.MangaUtils
|
||||
import org.koitharu.kotatsu.domain.history.HistoryRepository
|
||||
import org.koitharu.kotatsu.ui.common.BasePresenter
|
||||
import org.koitharu.kotatsu.utils.MediaStoreCompat
|
||||
@@ -34,7 +35,18 @@ class ReaderPresenter : BasePresenter<ReaderView>() {
|
||||
val chapter = state.chapter ?: repo.getDetails(state.manga).chapters
|
||||
?.first { it.id == state.chapterId }
|
||||
?: throw RuntimeException("Chapter ${state.chapterId} not found")
|
||||
repo.getPages(chapter) to MangaPreferencesRepository().getReaderMode(state.manga.id)
|
||||
var mode = MangaPreferencesRepository().getReaderMode(state.manga.id)
|
||||
val pages = repo.getPages(chapter)
|
||||
if (mode == null) {
|
||||
mode = MangaUtils.determineReaderMode(pages)
|
||||
if (mode != null) {
|
||||
MangaPreferencesRepository().saveData(
|
||||
mangaId = state.manga.id,
|
||||
mode = mode
|
||||
)
|
||||
}
|
||||
}
|
||||
pages to (mode ?: ReaderMode.UNKNOWN)
|
||||
}
|
||||
viewState.onInitReader(pages, mode, state)
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -19,4 +19,9 @@ inline fun <T> Iterable<T>.sumByLong(selector: (T) -> Long): Long {
|
||||
sum += selector(element)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun <T> List<T>.medianOrNull(): T? = when {
|
||||
isEmpty() -> null
|
||||
else -> get((size / 2).coerceIn(indices))
|
||||
}
|
||||
Reference in New Issue
Block a user