Use Wholphin-specific dispatchers (#1583)
## Description Switches all usages of `kotlinx.coroutines.Dispatchers` to `WholphinDispatchers`. `WholphinDispatchers` provides an easier and more reliable mechanism to use a test dispatcher in unit tests. For regular app usage, `WholphinDispatchers` just delegates to `Dispatchers`. There are no user facing changes ### Related issues None ### Testing Basic emulator testing & unit tests ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
ddbec0da73
commit
e17ae3eb8a
68 changed files with 252 additions and 226 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package com.github.damontecres.wholphin.util
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.ApiClientFactory
|
||||
|
|
@ -21,7 +20,7 @@ import kotlin.coroutines.CoroutineContext
|
|||
*/
|
||||
class CoroutineContextApiClient(
|
||||
private val client: ApiClient,
|
||||
private val coroutineContext: CoroutineContext = Dispatchers.IO,
|
||||
private val coroutineContext: CoroutineContext = WholphinDispatchers.IO,
|
||||
) : ApiClient() {
|
||||
override val baseUrl: String?
|
||||
get() = client.baseUrl
|
||||
|
|
@ -65,7 +64,7 @@ class CoroutineContextApiClient(
|
|||
|
||||
class CoroutineContextApiClientFactory(
|
||||
private val factory: OkHttpFactory,
|
||||
private val coroutineContext: CoroutineContext = Dispatchers.IO,
|
||||
private val coroutineContext: CoroutineContext = WholphinDispatchers.IO,
|
||||
) : ApiClientFactory,
|
||||
SocketConnectionFactory {
|
||||
override fun create(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import androidx.compose.runtime.setValue
|
|||
import com.github.damontecres.wholphin.ui.DEFAULT_PAGE_SIZE
|
||||
import com.google.common.cache.CacheBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
|
@ -85,7 +84,7 @@ abstract class RequestPager<T>(
|
|||
get() = totalCount
|
||||
|
||||
private fun fetchPage(position: Int): Job =
|
||||
scope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
scope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
fetchPageBlocking(position, false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.github.damontecres.wholphin.data.model.ItemPlayback
|
|||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.playback.CurrentPlayback
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.playStateApi
|
||||
|
|
@ -34,7 +33,7 @@ class TrackActivityPlaybackListener(
|
|||
private val player: Player,
|
||||
private val getState: () -> PlaybackItemState?,
|
||||
) : Player.Listener {
|
||||
private val coroutineScope = CoroutineScope(Dispatchers.Main)
|
||||
private val coroutineScope = CoroutineScope(WholphinDispatchers.Main)
|
||||
private val task: TimerTask =
|
||||
object : TimerTask() {
|
||||
override fun run() {
|
||||
|
|
@ -57,7 +56,7 @@ class TrackActivityPlaybackListener(
|
|||
PlaybackStartInfo(
|
||||
canSeek = true,
|
||||
itemId = state.itemId,
|
||||
isPaused = withContext(Dispatchers.Main) { !player.isPlaying },
|
||||
isPaused = withContext(WholphinDispatchers.Main) { !player.isPlaying },
|
||||
playMethod = state.playMethod,
|
||||
repeatMode = RepeatMode.REPEAT_NONE,
|
||||
playbackOrder = PlaybackOrder.DEFAULT,
|
||||
|
|
@ -117,11 +116,11 @@ class TrackActivityPlaybackListener(
|
|||
launch("saveActivity") {
|
||||
getState.invoke()?.let { state ->
|
||||
val calcPosition =
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
(if (position >= 0) position else player.currentPosition)
|
||||
}
|
||||
if (calcPosition > 0) {
|
||||
val isPaused = withContext(Dispatchers.Main) { !player.isPlaying }
|
||||
val isPaused = withContext(WholphinDispatchers.Main) { !player.isPlaying }
|
||||
Timber.v("saveActivity: itemId=${state.itemId}, pos=$calcPosition")
|
||||
api.playStateApi.reportPlaybackProgress(
|
||||
PlaybackProgressInfo(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.github.damontecres.wholphin.util
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.MainCoroutineDispatcher
|
||||
|
||||
/**
|
||||
* Analogous to [kotlinx.coroutines.Dispatchers], but easier to swap for testing
|
||||
*/
|
||||
object WholphinDispatchers {
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
val Main: MainCoroutineDispatcher get() = kotlinx.coroutines.Dispatchers.Main
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
var IO: CoroutineDispatcher = kotlinx.coroutines.Dispatchers.IO
|
||||
internal set
|
||||
|
||||
@Suppress("ktlint:standard:property-naming")
|
||||
var Default: CoroutineDispatcher = kotlinx.coroutines.Dispatchers.Default
|
||||
internal set
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue