Respect network data saver #1390
This commit is contained in:
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.os
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
@@ -42,6 +43,17 @@ class NetworkState(
|
||||
connectivityManager.unregisterNetworkCallback(callback)
|
||||
}
|
||||
|
||||
fun isMetered(): Boolean {
|
||||
return connectivityManager.isActiveNetworkMetered
|
||||
}
|
||||
|
||||
fun isDataSaverEnabled(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
&& connectivityManager.restrictBackgroundStatus == RESTRICT_BACKGROUND_STATUS_ENABLED
|
||||
|
||||
fun isRestricted() = isMetered() && isDataSaverEnabled()
|
||||
|
||||
fun isOfflineOrRestricted() = !isOnline() || isRestricted()
|
||||
|
||||
suspend fun awaitForConnection() {
|
||||
if (value) {
|
||||
return
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.koitharu.kotatsu.core.db.entity.MangaPrefsEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.toEntities
|
||||
import org.koitharu.kotatsu.core.db.entity.toEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.toManga
|
||||
import org.koitharu.kotatsu.core.db.entity.toMangaChapters
|
||||
import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
||||
import org.koitharu.kotatsu.core.model.LocalMangaSource
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
@@ -119,10 +120,10 @@ class MangaDataRepository @Inject constructor(
|
||||
return db.getMangaDao().findByPublicUrl(publicUrl)?.toManga()
|
||||
}
|
||||
|
||||
suspend fun resolveIntent(intent: MangaIntent): Manga? = when {
|
||||
intent.manga != null -> intent.manga
|
||||
intent.mangaId != 0L -> findMangaById(intent.mangaId, true)
|
||||
intent.uri != null -> resolverProvider.get().resolve(intent.uri)
|
||||
suspend fun resolveIntent(intent: MangaIntent, withChapters: Boolean): Manga? = when {
|
||||
intent.manga != null -> intent.manga.withCachedChaptersIfNeeded(withChapters)
|
||||
intent.mangaId != 0L -> findMangaById(intent.mangaId, withChapters)
|
||||
intent.uri != null -> resolverProvider.get().resolve(intent.uri).withCachedChaptersIfNeeded(withChapters)
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -184,6 +185,17 @@ class MangaDataRepository @Inject constructor(
|
||||
emitInitialState = emitInitialState,
|
||||
)
|
||||
|
||||
private suspend fun Manga.withCachedChaptersIfNeeded(flag: Boolean): Manga = if (flag && chapters.isNullOrEmpty()) {
|
||||
val cachedChapters = db.getChaptersDao().findAll(id)
|
||||
if (cachedChapters.isEmpty()) {
|
||||
this
|
||||
} else {
|
||||
copy(chapters = cachedChapters.toMangaChapters())
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
private fun MangaPrefsEntity.getColorFilterOrNull(): ReaderColorFilter? {
|
||||
return if (cfBrightness != 0f || cfContrast != 0f || cfInvert || cfGrayscale) {
|
||||
ReaderColorFilter(cfBrightness, cfContrast, cfInvert, cfGrayscale)
|
||||
|
||||
@@ -16,6 +16,7 @@ import kotlinx.coroutines.runInterruptible
|
||||
import okio.IOException
|
||||
import org.koitharu.kotatsu.core.model.isLocal
|
||||
import org.koitharu.kotatsu.core.nav.MangaIntent
|
||||
import org.koitharu.kotatsu.core.os.NetworkState
|
||||
import org.koitharu.kotatsu.core.parser.CachingMangaRepository
|
||||
import org.koitharu.kotatsu.core.parser.MangaDataRepository
|
||||
import org.koitharu.kotatsu.core.parser.MangaRepository
|
||||
@@ -40,17 +41,12 @@ class DetailsLoadUseCase @Inject constructor(
|
||||
private val recoverUseCase: RecoverMangaUseCase,
|
||||
private val imageGetter: Html.ImageGetter,
|
||||
private val newChaptersUseCaseProvider: Provider<CheckNewChaptersUseCase>,
|
||||
private val networkState: NetworkState,
|
||||
) {
|
||||
|
||||
operator fun invoke(intent: MangaIntent, force: Boolean): Flow<MangaDetails> = channelFlow {
|
||||
val manga = requireNotNull(mangaDataRepository.resolveIntent(intent)) {
|
||||
val manga = requireNotNull(mangaDataRepository.resolveIntent(intent, withChapters = true)) {
|
||||
"Cannot resolve intent $intent"
|
||||
}.let { m ->
|
||||
if (m.chapters.isNullOrEmpty()) {
|
||||
getCachedDetails(m.id) ?: m
|
||||
} else {
|
||||
m
|
||||
}
|
||||
}
|
||||
val override = mangaDataRepository.getOverride(manga.id)
|
||||
send(
|
||||
@@ -69,6 +65,22 @@ class DetailsLoadUseCase @Inject constructor(
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (!force && networkState.isOfflineOrRestricted()) {
|
||||
// try to avoid loading if has saved manga
|
||||
val localManga = local?.await()
|
||||
if (manga.isLocal || localManga != null) {
|
||||
send(
|
||||
MangaDetails(
|
||||
manga = manga,
|
||||
localManga = localManga,
|
||||
override = override,
|
||||
description = manga.description?.parseAsHtml(withImages = true)?.trim(),
|
||||
isLoaded = true,
|
||||
),
|
||||
)
|
||||
return@channelFlow
|
||||
}
|
||||
}
|
||||
try {
|
||||
val details = getDetails(manga, force)
|
||||
launch { mangaDataRepository.updateChapters(details) }
|
||||
@@ -147,8 +159,4 @@ class DetailsLoadUseCase @Inject constructor(
|
||||
}.onFailure { e ->
|
||||
e.printStackTraceDebug()
|
||||
}
|
||||
|
||||
private suspend fun getCachedDetails(mangaId: Long): Manga? = runCatchingCancellable {
|
||||
mangaDataRepository.findMangaById(mangaId, withChapters = true)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user