Fix offline details loading

master
Koitharu 2 years ago
parent ce705e12a8
commit 9b658cf0b8
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -19,7 +19,9 @@ class NetworkState(
override fun onActive() { override fun onActive() {
invalidate() invalidate()
val request = NetworkRequest.Builder() val request = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build() .build()
connectivityManager.registerNetworkCallback(request, callback) connectivityManager.registerNetworkCallback(request, callback)
} }

@ -19,6 +19,8 @@ fun ConnectivityManager.isOnline(): Boolean {
} }
private fun ConnectivityManager.isOnline(network: Network): Boolean { private fun ConnectivityManager.isOnline(network: Network): Boolean {
val capabilities = getNetworkCapabilities(network) val capabilities = getNetworkCapabilities(network) ?: return false
return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
} }

@ -60,8 +60,7 @@ class DetailsLoadUseCase @Inject constructor(
} catch (e: IOException) { } catch (e: IOException) {
local?.await()?.manga?.also { localManga -> local?.await()?.manga?.also { localManga ->
send(MangaDetails(localManga, null, localManga.description?.parseAsHtml(withImages = false), true)) send(MangaDetails(localManga, null, localManga.description?.parseAsHtml(withImages = false), true))
} } ?: close(e)
throw e
} }
} }

@ -0,0 +1,32 @@
package org.koitharu.kotatsu.local.data
import androidx.collection.MutableLongObjectMap
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.local.data.input.LocalMangaInput
import org.koitharu.kotatsu.local.domain.model.LocalManga
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import java.io.File
class LocalMangaMappingCache {
private val map = MutableLongObjectMap<File>()
suspend fun get(mangaId: Long): LocalManga? {
val file = synchronized(this) {
map[mangaId]
} ?: return null
return runCatchingCancellable {
LocalMangaInput.of(file).getManga()
}.onFailure {
it.printStackTraceDebug()
}.getOrNull()
}
operator fun set(mangaId: Long, localManga: LocalManga?) = synchronized(this) {
if (localManga == null) {
map.remove(mangaId)
} else {
map[mangaId] = localManga.file
}
}
}

@ -51,6 +51,7 @@ class LocalMangaRepository @Inject constructor(
override val source = MangaSource.LOCAL override val source = MangaSource.LOCAL
private val locks = MultiMutex<Long>() private val locks = MultiMutex<Long>()
private val localMappingCache = LocalMangaMappingCache()
override val isMultipleTagsSupported: Boolean = true override val isMultipleTagsSupported: Boolean = true
override val isTagsExclusionSupported: Boolean = true override val isTagsExclusionSupported: Boolean = true
@ -141,6 +142,10 @@ class LocalMangaRepository @Inject constructor(
} }
suspend fun findSavedManga(remoteManga: Manga): LocalManga? = runCatchingCancellable { suspend fun findSavedManga(remoteManga: Manga): LocalManga? = runCatchingCancellable {
// very fast path
localMappingCache.get(remoteManga.id)?.let {
return@runCatchingCancellable it
}
// fast path // fast path
LocalMangaInput.find(storageManager.getReadableDirs(), remoteManga)?.let { LocalMangaInput.find(storageManager.getReadableDirs(), remoteManga)?.let {
return it.getManga() return it.getManga()
@ -162,6 +167,8 @@ class LocalMangaRepository @Inject constructor(
} }
} }
}.firstOrNull()?.getManga() }.firstOrNull()?.getManga()
}.onSuccess { x: LocalManga? ->
localMappingCache[remoteManga.id] = x
}.onFailure { }.onFailure {
it.printStackTraceDebug() it.printStackTraceDebug()
}.getOrNull() }.getOrNull()

Loading…
Cancel
Save