diff --git a/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkState.kt b/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkState.kt new file mode 100644 index 000000000..49d1704d6 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkState.kt @@ -0,0 +1,54 @@ +package org.koitharu.kotatsu.core.os + +import android.content.Context +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkRequest +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.flow.first +import org.koitharu.kotatsu.utils.MediatorStateFlow +import org.koitharu.kotatsu.utils.ext.connectivityManager +import org.koitharu.kotatsu.utils.ext.isNetworkAvailable +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NetworkState @Inject constructor( + @ApplicationContext context: Context, +) : MediatorStateFlow() { + + private val connectivityManager = context.connectivityManager + private val callback = NetworkCallbackImpl() + + override val initialValue: Boolean + get() = connectivityManager.isNetworkAvailable + + override fun onActive() { + val request = NetworkRequest.Builder().build() + connectivityManager.registerNetworkCallback(request, callback) + } + + override fun onInactive() { + connectivityManager.unregisterNetworkCallback(callback) + } + + suspend fun awaitForConnection() { + if (value) { + return + } + first { it } + } + + private inner class NetworkCallbackImpl : NetworkCallback() { + + override fun onAvailable(network: Network) = update() + + override fun onLost(network: Network) = update() + + override fun onUnavailable() = update() + + private fun update() { + publishValue(connectivityManager.isNetworkAvailable) + } + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkStateObserver.kt b/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkStateObserver.kt deleted file mode 100644 index 8450028e9..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/core/os/NetworkStateObserver.kt +++ /dev/null @@ -1,78 +0,0 @@ -package org.koitharu.kotatsu.core.os - -import android.content.Context -import android.net.ConnectivityManager.NetworkCallback -import android.net.Network -import android.net.NetworkRequest -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.channels.ProducerScope -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.onSuccess -import kotlinx.coroutines.channels.trySendBlocking -import kotlinx.coroutines.flow.FlowCollector -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.first -import org.koitharu.kotatsu.utils.ext.connectivityManager -import org.koitharu.kotatsu.utils.ext.isNetworkAvailable -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class NetworkStateObserver @Inject constructor( - @ApplicationContext context: Context, -) : StateFlow { - - private val connectivityManager = context.connectivityManager - - override val replayCache: List - get() = listOf(value) - - override val value: Boolean - get() = connectivityManager.isNetworkAvailable - - override suspend fun collect(collector: FlowCollector): Nothing { - collector.emit(value) - while (true) { - observeImpl().collect(collector) - } - } - - suspend fun awaitForConnection(): Unit { - if (value) { - return - } - first { it } - } - - private fun observeImpl() = callbackFlow { - val request = NetworkRequest.Builder().build() - val callback = FlowNetworkCallback(this) - connectivityManager.registerNetworkCallback(request, callback) - awaitClose { - connectivityManager.unregisterNetworkCallback(callback) - } - } - - private inner class FlowNetworkCallback( - private val producerScope: ProducerScope, - ) : NetworkCallback() { - - private var prevValue = value - - override fun onAvailable(network: Network) = update() - - override fun onLost(network: Network) = update() - - override fun onUnavailable() = update() - - private fun update() { - val newValue = connectivityManager.isNetworkAvailable - if (newValue != prevValue) { - producerScope.trySendBlocking(newValue).onSuccess { - prevValue = newValue - } - } - } - } -} diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt index 03380ff51..a5f032ff6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt @@ -5,7 +5,7 @@ import androidx.annotation.CallSuper import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.LayoutPageInfoBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -14,12 +14,12 @@ abstract class BasePageHolder( protected val binding: B, loader: PageLoader, settings: ReaderSettings, - networkStateObserver: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : RecyclerView.ViewHolder(binding.root), PageHolderDelegate.Callback { @Suppress("LeakingThis") - protected val delegate = PageHolderDelegate(loader, settings, this, networkStateObserver, exceptionResolver) + protected val delegate = PageHolderDelegate(loader, settings, this, networkState, exceptionResolver) protected val bindingInfo = LayoutPageInfoBinding.bind(binding.root) val context: Context diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReaderAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReaderAdapter.kt index 1a914b41e..3144ef655 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReaderAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/BaseReaderAdapter.kt @@ -5,7 +5,7 @@ import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings import org.koitharu.kotatsu.utils.ext.resetTransformations @@ -16,7 +16,7 @@ import kotlin.coroutines.suspendCoroutine abstract class BaseReaderAdapter>( private val loader: PageLoader, private val readerSettings: ReaderSettings, - private val networkState: NetworkStateObserver, + private val networkState: NetworkState, private val exceptionResolver: ExceptionResolver, ) : RecyclerView.Adapter() { @@ -70,7 +70,7 @@ abstract class BaseReaderAdapter>( parent: ViewGroup, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ): H diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt index 27431e75b..51db77550 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/PageHolderDelegate.kt @@ -17,7 +17,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.plus import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -28,7 +28,7 @@ class PageHolderDelegate( private val loader: PageLoader, private val readerSettings: ReaderSettings, private val callback: Callback, - private val networkState: NetworkStateObserver, + private val networkState: NetworkState, private val exceptionResolver: ExceptionResolver, ) : DefaultOnImageEventListener, Observer { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt index 8e686ae81..f907de4a9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPageHolder.kt @@ -6,7 +6,7 @@ import android.widget.FrameLayout import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -16,7 +16,7 @@ class ReversedPageHolder( binding: ItemPageBinding, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : PageHolder(binding, loader, settings, networkState, exceptionResolver) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPagesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPagesAdapter.kt index d68f39334..4c6eeb28e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPagesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedPagesAdapter.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.reversed import android.view.LayoutInflater import android.view.ViewGroup import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -12,7 +12,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter class ReversedPagesAdapter( loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : BaseReaderAdapter(loader, settings, networkState, exceptionResolver) { @@ -20,7 +20,7 @@ class ReversedPagesAdapter( parent: ViewGroup, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) = ReversedPageHolder( binding = ItemPageBinding.inflate(LayoutInflater.from(parent.context), parent, false), diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt index df4a739ac..0302134dd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt @@ -8,7 +8,7 @@ import android.view.ViewGroup import androidx.core.view.children import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.async -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.FragmentReaderStandardBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.pager.BaseReader @@ -26,7 +26,7 @@ import kotlin.math.absoluteValue class ReversedReaderFragment : BaseReader() { @Inject - lateinit var networkStateObserver: NetworkStateObserver + lateinit var networkState: NetworkState private var pagerAdapter: ReversedPagesAdapter? = null @@ -41,7 +41,7 @@ class ReversedReaderFragment : BaseReader() { pagerAdapter = ReversedPagesAdapter( viewModel.pageLoader, viewModel.readerSettings, - networkStateObserver, + networkState, exceptionResolver, ) with(binding.pager) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt index b56163f54..c2501e499 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PageHolder.kt @@ -10,7 +10,7 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -22,7 +22,7 @@ open class PageHolder( binding: ItemPageBinding, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : BasePageHolder(binding, loader, settings, networkState, exceptionResolver), View.OnClickListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt index 889f5189f..07633f5e2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt @@ -8,7 +8,7 @@ import android.view.ViewGroup import androidx.core.view.children import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.async -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.FragmentReaderStandardBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.pager.BaseReader @@ -25,7 +25,7 @@ import kotlin.math.absoluteValue class PagerReaderFragment : BaseReader() { @Inject - lateinit var networkStateObserver: NetworkStateObserver + lateinit var networkState: NetworkState private var pagesAdapter: PagesAdapter? = null @@ -40,7 +40,7 @@ class PagerReaderFragment : BaseReader() { pagesAdapter = PagesAdapter( viewModel.pageLoader, viewModel.readerSettings, - networkStateObserver, + networkState, exceptionResolver, ) with(binding.pager) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagesAdapter.kt index 293ca6273..a36057bf7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagesAdapter.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.standard import android.view.LayoutInflater import android.view.ViewGroup import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -12,15 +12,15 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter class PagesAdapter( loader: PageLoader, settings: ReaderSettings, - networkStateObserver: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, -) : BaseReaderAdapter(loader, settings, networkStateObserver, exceptionResolver) { +) : BaseReaderAdapter(loader, settings, networkState, exceptionResolver) { override fun onCreateViewHolder( parent: ViewGroup, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) = PageHolder( binding = ItemPageBinding.inflate(LayoutInflater.from(parent.context), parent, false), diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonAdapter.kt index 6d92ff321..e47711f49 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonAdapter.kt @@ -3,7 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon import android.view.LayoutInflater import android.view.ViewGroup import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -12,7 +12,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter class WebtoonAdapter( loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : BaseReaderAdapter(loader, settings, networkState, exceptionResolver) { @@ -20,7 +20,7 @@ class WebtoonAdapter( parent: ViewGroup, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) = WebtoonHolder( binding = ItemPageWebtoonBinding.inflate( diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt index 086081097..81ce8fb80 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonHolder.kt @@ -8,7 +8,7 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.ItemPageWebtoonBinding import org.koitharu.kotatsu.reader.domain.PageLoader import org.koitharu.kotatsu.reader.ui.config.ReaderSettings @@ -25,7 +25,7 @@ class WebtoonHolder( binding: ItemPageWebtoonBinding, loader: PageLoader, settings: ReaderSettings, - networkState: NetworkStateObserver, + networkState: NetworkState, exceptionResolver: ExceptionResolver, ) : BasePageHolder(binding, loader, settings, networkState, exceptionResolver), View.OnClickListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt index 7fe5fb1f4..1142fedcb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt @@ -7,7 +7,7 @@ import android.view.ViewGroup import android.view.animation.AccelerateDecelerateInterpolator import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.async -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.databinding.FragmentReaderWebtoonBinding import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.reader.ui.pager.BaseReader @@ -22,7 +22,7 @@ import javax.inject.Inject class WebtoonReaderFragment : BaseReader() { @Inject - lateinit var networkStateObserver: NetworkStateObserver + lateinit var networkState: NetworkState private val scrollInterpolator = AccelerateDecelerateInterpolator() private var webtoonAdapter: WebtoonAdapter? = null @@ -37,7 +37,7 @@ class WebtoonReaderFragment : BaseReader() { webtoonAdapter = WebtoonAdapter( viewModel.pageLoader, viewModel.readerSettings, - networkStateObserver, + networkState, exceptionResolver, ) with(binding.recyclerView) { diff --git a/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt index a56d848ea..78cb8050a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/shelf/ui/ShelfViewModel.kt @@ -12,7 +12,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.base.ui.util.ReversibleAction import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.core.os.NetworkStateObserver +import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode import org.koitharu.kotatsu.core.prefs.observeAsFlow @@ -46,14 +46,14 @@ class ShelfViewModel @Inject constructor( private val favouritesRepository: FavouritesRepository, private val trackingRepository: TrackingRepository, private val settings: AppSettings, - networkStateObserver: NetworkStateObserver, + networkState: NetworkState, ) : BaseViewModel(), ListExtraProvider { val onActionDone = SingleLiveEvent() val content: LiveData> = combine( settings.observeAsFlow(AppSettings.KEY_SHELF_SECTIONS) { shelfSections }, - networkStateObserver, + networkState, repository.observeShelfContent(), ) { sections, isConnected, content -> mapList(content, sections, isConnected) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/MediatorStateFlow.kt b/app/src/main/java/org/koitharu/kotatsu/utils/MediatorStateFlow.kt new file mode 100644 index 000000000..618d098b0 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/MediatorStateFlow.kt @@ -0,0 +1,42 @@ +package org.koitharu.kotatsu.utils + +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import java.util.concurrent.atomic.AtomicInteger + +abstract class MediatorStateFlow : StateFlow { + + @Suppress("LeakingThis") + private val delegate = MutableStateFlow(initialValue) + private val collectors = AtomicInteger(0) + + protected abstract val initialValue: T + + final override val replayCache: List + get() = delegate.replayCache + + final override val value: T + get() = delegate.value + + final override suspend fun collect(collector: FlowCollector): Nothing { + try { + if (collectors.getAndIncrement() == 0) { + onActive() + } + delegate.collect(collector) + } finally { + if (collectors.decrementAndGet() == 0) { + onInactive() + } + } + } + + protected fun publishValue(v: T) { + delegate.value = v + } + + abstract fun onActive() + + abstract fun onInactive() +}