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
|
|
@ -33,9 +33,9 @@ import com.github.damontecres.wholphin.data.model.BaseItem
|
|||
import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||
import com.github.damontecres.wholphin.ui.data.RowColumnSaver
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
|
@ -359,34 +359,34 @@ suspend fun showToast(
|
|||
context: Context,
|
||||
text: CharSequence,
|
||||
duration: Int,
|
||||
) = withContext(Dispatchers.Main) {
|
||||
) = withContext(WholphinDispatchers.Main) {
|
||||
Toast.makeText(context, text, duration).show()
|
||||
}
|
||||
|
||||
suspend fun showToast(
|
||||
context: Context,
|
||||
text: CharSequence,
|
||||
) = withContext(Dispatchers.Main) {
|
||||
) = withContext(WholphinDispatchers.Main) {
|
||||
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a coroutine with [Dispatchers.IO] plus the provided [CoroutineContext] defaulting to using [ExceptionHandler]
|
||||
* Launches a coroutine with [WholphinDispatchers.IO] plus the provided [CoroutineContext] defaulting to using [ExceptionHandler]
|
||||
*/
|
||||
fun CoroutineScope.launchIO(
|
||||
context: CoroutineContext = ExceptionHandler(),
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit,
|
||||
): Job = launch(context = Dispatchers.IO + context, start = start, block = block)
|
||||
): Job = launch(context = WholphinDispatchers.IO + context, start = start, block = block)
|
||||
|
||||
/**
|
||||
* Launches a coroutine with [Dispatchers.Default] plus the provided [CoroutineContext] defaulting to using [ExceptionHandler]
|
||||
* Launches a coroutine with [WholphinDispatchers.Default] plus the provided [CoroutineContext] defaulting to using [ExceptionHandler]
|
||||
*/
|
||||
fun CoroutineScope.launchDefault(
|
||||
context: CoroutineContext = ExceptionHandler(),
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit,
|
||||
): Job = launch(context = Dispatchers.Default + context, start = start, block = block)
|
||||
): Job = launch(context = WholphinDispatchers.Default + context, start = start, block = block)
|
||||
|
||||
/**
|
||||
* Converts a UUID to the format used server-side (ie without hyphens).
|
||||
|
|
@ -410,7 +410,7 @@ fun logTab(
|
|||
ACRA.errorReporter.putCustomData("tabInfo", info)
|
||||
}
|
||||
|
||||
suspend fun <T> onMain(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block)
|
||||
suspend fun <T> onMain(block: suspend CoroutineScope.() -> T) = withContext(WholphinDispatchers.Main, block)
|
||||
|
||||
fun Modifier.dimAndBlur(enabled: Boolean) =
|
||||
this.ifElse(
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import coil3.request.crossfade
|
|||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||
import com.github.damontecres.wholphin.ui.components.Genre
|
||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.wholphin.ui.setup.rememberIdColor
|
||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||
import java.util.UUID
|
||||
|
|
|
|||
|
|
@ -32,9 +32,7 @@ import coil3.request.ImageRequest
|
|||
import coil3.request.crossfade
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||
import com.github.damontecres.wholphin.ui.components.Genre
|
||||
import com.github.damontecres.wholphin.ui.components.Studio
|
||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.wholphin.ui.setup.rememberIdColor
|
||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||
import java.util.UUID
|
||||
|
|
|
|||
|
|
@ -70,13 +70,13 @@ import com.github.damontecres.wholphin.util.ExceptionHandler
|
|||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.GetPersonsHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.successValue
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
|
|
@ -251,7 +251,7 @@ class CollectionFolderViewModel
|
|||
|
||||
fun saveViewOptions(viewOptions: ViewOptions) {
|
||||
_state.update { it.copy(viewOptions = viewOptions) }
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
saveLibraryDisplayInfo(viewOptions = viewOptions)
|
||||
if (!viewOptions.showBackdrop) {
|
||||
backdropService.clearBackdrop()
|
||||
|
|
@ -295,7 +295,7 @@ class CollectionFolderViewModel
|
|||
recursive: Boolean,
|
||||
filter: GetItemsFilter,
|
||||
useSeriesForPrimary: Boolean,
|
||||
) = viewModelScope.launch(Dispatchers.IO) {
|
||||
) = viewModelScope.launch(WholphinDispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(
|
||||
items = DataLoadingState.Loading,
|
||||
|
|
@ -437,7 +437,7 @@ class CollectionFolderViewModel
|
|||
)
|
||||
|
||||
suspend fun positionOfLetter(letter: Char): Int? =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val sort = state.value.sortAndDirection
|
||||
val filter = state.value.filter
|
||||
val request =
|
||||
|
|
@ -461,7 +461,7 @@ class CollectionFolderViewModel
|
|||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
(state.value.items as? DataLoadingState.Success)?.let {
|
||||
(it.data as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
@ -474,7 +474,7 @@ class CollectionFolderViewModel
|
|||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
(state.value.items as? DataLoadingState.Success)?.let {
|
||||
(it.data as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ import com.github.damontecres.wholphin.ui.tryRequestFocus
|
|||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.GetGenresRequestHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.mayakapps.kache.InMemoryKache
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -142,7 +142,7 @@ class GenreViewModel
|
|||
}
|
||||
|
||||
suspend fun positionOfLetter(letter: Char): Int =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val request =
|
||||
GetGenresRequest(
|
||||
parentId = itemId,
|
||||
|
|
@ -197,7 +197,7 @@ suspend fun getGenreImageMap(
|
|||
val semaphore = Semaphore(4)
|
||||
genres
|
||||
.map { genreId ->
|
||||
scope.async(Dispatchers.IO) {
|
||||
scope.async(WholphinDispatchers.IO) {
|
||||
semaphore.withPermit {
|
||||
val item =
|
||||
GetItemsRequestHandler
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ import com.github.damontecres.wholphin.util.ApiRequestPager
|
|||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.RequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
@ -150,7 +150,7 @@ class ItemGridViewModel
|
|||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
(state.value.items as? DataLoadingState.Success)?.let {
|
||||
(it.data as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
@ -163,7 +163,7 @@ class ItemGridViewModel
|
|||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
(state.value.items as? DataLoadingState.Success)?.let {
|
||||
(it.data as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
|
|||
|
|
@ -48,13 +48,13 @@ import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
|||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.RequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
|
@ -173,7 +173,7 @@ class RecommendedViewModel
|
|||
}
|
||||
|
||||
private fun fetchSuggestions() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(WholphinDispatchers.IO) {
|
||||
val limit =
|
||||
userPreferencesService
|
||||
.getCurrent()
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ import com.github.damontecres.wholphin.ui.launchIO
|
|||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.GetStudiosRequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
@ -113,7 +113,7 @@ class StudioViewModel
|
|||
}
|
||||
|
||||
suspend fun positionOfLetter(letter: Char): Int =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val request =
|
||||
GetStudiosRequest(
|
||||
userId = serverRepository.currentUser?.id,
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import android.speech.RecognizerIntent
|
|||
import android.speech.SpeechRecognizer
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.github.damontecres.wholphin.R
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.android.asCoroutineDispatcher
|
||||
|
|
@ -175,7 +175,7 @@ class VoiceInputManager
|
|||
|
||||
private fun provideMainDispatcher(): CoroutineDispatcher =
|
||||
try {
|
||||
Dispatchers.Main.immediate
|
||||
WholphinDispatchers.Main.immediate
|
||||
} catch (_: IllegalStateException) {
|
||||
// Fallback for unit tests where Main dispatcher is not installed
|
||||
handler.asCoroutineDispatcher()
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ import com.github.damontecres.wholphin.ui.playback.isForwardButton
|
|||
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
|
@ -217,7 +217,7 @@ fun <T : CardGridItem> CardGrid(
|
|||
{ letter: Char ->
|
||||
scope.launch(ExceptionHandler()) {
|
||||
val jumpPosition =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
letterPosition.invoke(letter)
|
||||
}
|
||||
Timber.d("Alphabet jump to $jumpPosition")
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ import com.github.damontecres.wholphin.ui.util.StringStringProvider
|
|||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
@ -166,7 +166,7 @@ class HomeRowGridViewModel
|
|||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
(state.value.loading as? HomeRowLoadingState.Success)?.let {
|
||||
(it.items as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
@ -179,7 +179,7 @@ class HomeRowGridViewModel
|
|||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
(state.value.loading as? HomeRowLoadingState.Success)?.let {
|
||||
(it.items as? ApiRequestPager<*>)?.refreshItem(position, itemId)
|
||||
|
|
|
|||
|
|
@ -107,12 +107,12 @@ import com.github.damontecres.wholphin.util.ApiRequestPager
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -316,14 +316,14 @@ class PlaylistViewModel
|
|||
fun setWatched(
|
||||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
}
|
||||
|
||||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ import com.github.damontecres.wholphin.util.ExceptionHandler
|
|||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -210,7 +210,7 @@ class CollectionViewModel
|
|||
supervisorScope {
|
||||
val jobs =
|
||||
typesInCollection.map { type ->
|
||||
async(Dispatchers.IO) {
|
||||
async(WholphinDispatchers.IO) {
|
||||
val title = ResStringProvider(formatTypeName(type))
|
||||
val result =
|
||||
try {
|
||||
|
|
@ -359,7 +359,7 @@ class CollectionViewModel
|
|||
)
|
||||
|
||||
suspend fun letterPosition(letter: Char): Int =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val sort = state.value.sortAndDirection
|
||||
val filter = state.value.itemFilter
|
||||
val request =
|
||||
|
|
@ -387,7 +387,7 @@ class CollectionViewModel
|
|||
itemId: UUID,
|
||||
played: Boolean,
|
||||
position: RowColumn?,
|
||||
) = viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) {
|
||||
) = viewModelScope.launch(WholphinDispatchers.IO + ExceptionHandler()) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
if (itemId == state.value.collection?.id) {
|
||||
refreshCollection()
|
||||
|
|
@ -400,7 +400,7 @@ class CollectionViewModel
|
|||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
position: RowColumn?,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
if (itemId == state.value.collection?.id) {
|
||||
refreshCollection()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.github.damontecres.wholphin.ui.launchIO
|
|||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.successValue
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -31,7 +32,6 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -73,7 +73,7 @@ class DiscoverMovieViewModel
|
|||
}
|
||||
|
||||
private fun fetchAndSetItem(): Deferred<MovieDetails?> =
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
try {
|
||||
val movie = seerrService.api.moviesApi.movieMovieIdGet(movieId = item.id)
|
||||
_state.update { it.copy(movie = DataLoadingState.Success(movie)) }
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.github.damontecres.wholphin.ui.launchIO
|
|||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.successValue
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -30,7 +31,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -71,7 +71,7 @@ class DiscoverSeriesViewModel
|
|||
}
|
||||
|
||||
private fun fetchAndSetItem(): Deferred<TvDetails?> =
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
try {
|
||||
val tv = seerrService.api.tvApi.tvTvIdGet(tvId = item.id)
|
||||
_state.update { it.copy(tvSeries = DataLoadingState.Success(tv)) }
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ import com.github.damontecres.wholphin.ui.nav.Destination
|
|||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -126,7 +126,7 @@ class EpisodeViewModel
|
|||
fun setWatched(
|
||||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
fetchAndSetItem()
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ class EpisodeViewModel
|
|||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
fetchAndSetItem()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ import com.github.damontecres.wholphin.ui.rememberInt
|
|||
import com.github.damontecres.wholphin.ui.rememberPosition
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import eu.wewox.programguide.ProgramGuide
|
||||
import eu.wewox.programguide.ProgramGuideDimensions
|
||||
import eu.wewox.programguide.ProgramGuideItem
|
||||
import eu.wewox.programguide.rememberSaveableProgramGuideState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
|
|
@ -319,7 +319,7 @@ fun TvGuideGridContent(
|
|||
var focusedProgramIndex by rememberInt(0)
|
||||
|
||||
LaunchedEffect(onFocus, focusedProgramIndex) {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(WholphinDispatchers.Default) {
|
||||
val program = programs.programs.getOrNull(focusedProgramIndex)
|
||||
if (program != null) {
|
||||
val channelIndex = channels.indexOfFirst { it.id == program.channelId }
|
||||
|
|
|
|||
|
|
@ -86,12 +86,12 @@ import com.github.damontecres.wholphin.util.ApiRequestPager
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -242,7 +242,7 @@ class AlbumViewModel
|
|||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
val album =
|
||||
api.userLibraryApi
|
||||
|
|
|
|||
|
|
@ -81,12 +81,12 @@ import com.github.damontecres.wholphin.util.ApiRequestPager
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -254,7 +254,7 @@ class ArtistViewModel
|
|||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
val artist =
|
||||
api.userLibraryApi
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ import com.github.damontecres.wholphin.ui.playback.ControllerViewState
|
|||
import com.github.damontecres.wholphin.ui.playback.overlay.PlaybackAction
|
||||
import com.github.damontecres.wholphin.ui.playback.overlay.PlaybackButton
|
||||
import com.github.damontecres.wholphin.ui.playback.overlay.PlaybackButtons
|
||||
import com.github.damontecres.wholphin.ui.playback.overlay.PlaybackFaButton
|
||||
import com.github.damontecres.wholphin.ui.playback.overlay.buttonSpacing
|
||||
import com.github.damontecres.wholphin.ui.theme.PreviewInteractionSource
|
||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ import com.github.damontecres.wholphin.ui.launchDefault
|
|||
import com.github.damontecres.wholphin.ui.main.settings.MoveDirection
|
||||
import com.github.damontecres.wholphin.ui.onMain
|
||||
import com.github.damontecres.wholphin.ui.playback.ControllerViewState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.mayakapps.kache.InMemoryKache
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -95,7 +95,7 @@ class NowPlayingViewModel
|
|||
|
||||
private val lyricCache =
|
||||
InMemoryKache<UUID, LyricDto>(20) {
|
||||
creationScope = CoroutineScope(Dispatchers.IO)
|
||||
creationScope = CoroutineScope(WholphinDispatchers.IO)
|
||||
}
|
||||
|
||||
init {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.DenseListItem
|
||||
import androidx.tv.material3.Icon
|
||||
import androidx.tv.material3.ListItem
|
||||
import androidx.tv.material3.ListItemDefaults
|
||||
import androidx.tv.material3.LocalContentColor
|
||||
import androidx.tv.material3.Text
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.github.damontecres.wholphin.util.DataLoadingState
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetEpisodesRequestHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.successValue
|
||||
import com.google.common.cache.CacheBuilder
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -50,7 +51,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -137,7 +137,7 @@ class SeriesViewModel
|
|||
|
||||
val episodeListDeferred =
|
||||
if (seriesPageType == SeriesPageType.OVERVIEW) {
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
if (seasonEpisodeIds != null) {
|
||||
loadEpisodesInternal(
|
||||
seasonEpisodeIds.seasonId,
|
||||
|
|
@ -292,7 +292,7 @@ class SeriesViewModel
|
|||
series: BaseItem,
|
||||
seasonNum: Int?,
|
||||
): Deferred<List<BaseItem?>> =
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
Timber.v("getSeasons for %s", series.id)
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
|
|
@ -405,7 +405,7 @@ class SeriesViewModel
|
|||
itemId: UUID,
|
||||
played: Boolean,
|
||||
listIndex: Int?,
|
||||
) = viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) {
|
||||
) = viewModelScope.launch(WholphinDispatchers.IO + ExceptionHandler()) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
listIndex?.let {
|
||||
refreshEpisode(itemId, listIndex)
|
||||
|
|
@ -440,7 +440,7 @@ class SeriesViewModel
|
|||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
listIndex: Int?,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
if (listIndex != null) {
|
||||
refreshEpisode(itemId, listIndex)
|
||||
|
|
@ -452,13 +452,13 @@ class SeriesViewModel
|
|||
fun setSeasonWatched(
|
||||
seasonId: UUID,
|
||||
played: Boolean,
|
||||
) = viewModelScope.launch(Dispatchers.IO + ExceptionHandler()) {
|
||||
) = viewModelScope.launch(WholphinDispatchers.IO + ExceptionHandler()) {
|
||||
setWatched(seasonId, played, null)
|
||||
updateSeries()
|
||||
}
|
||||
|
||||
fun setWatchedSeries(played: Boolean) =
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(seriesId, played)
|
||||
updateSeries()
|
||||
}
|
||||
|
|
@ -466,7 +466,7 @@ class SeriesViewModel
|
|||
fun refreshEpisode(
|
||||
itemId: UUID,
|
||||
listIndex: Int,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
val eps = state.value.episodes
|
||||
if (eps is EpisodeList.Success) {
|
||||
eps.episodes.refreshItem(listIndex, itemId)
|
||||
|
|
@ -481,7 +481,7 @@ class SeriesViewModel
|
|||
* Play whichever episode is next up for series or else the first episode
|
||||
*/
|
||||
fun playNextUp() {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
val result by api.tvShowsApi.getNextUp(seriesId = seriesId)
|
||||
val nextUp =
|
||||
result.items.firstOrNull() ?: api.tvShowsApi
|
||||
|
|
@ -491,7 +491,7 @@ class SeriesViewModel
|
|||
).content.items
|
||||
.firstOrNull()
|
||||
if (nextUp != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
navigateTo(Destination.Playback(BaseItem(nextUp)))
|
||||
}
|
||||
} else {
|
||||
|
|
@ -582,7 +582,7 @@ class SeriesViewModel
|
|||
val result =
|
||||
peopleInEpisodeCache
|
||||
.get(item.id) {
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
val list =
|
||||
api.userLibraryApi
|
||||
.getItem(item.id)
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ import com.github.damontecres.wholphin.ui.launchIO
|
|||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.DataLoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -77,7 +77,7 @@ class SeerrRequestsViewModel
|
|||
val requests =
|
||||
mediaRequests.mapNotNull { request ->
|
||||
if (request.media?.tmdbId != null) {
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
semaphore.withPermit {
|
||||
val type = SeerrItemType.fromString(request.type)
|
||||
when (type) {
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ import com.github.damontecres.wholphin.ui.util.EmptyStringProvider
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -117,7 +117,7 @@ class HomeViewModel
|
|||
val deferred =
|
||||
settings.rows
|
||||
.map { row ->
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
semaphore.withPermit {
|
||||
Timber.v("Fetching row: %s", row)
|
||||
try {
|
||||
|
|
@ -220,9 +220,9 @@ class HomeViewModel
|
|||
fun setWatched(
|
||||
itemId: UUID,
|
||||
played: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setWatched(itemId, played)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
init()
|
||||
}
|
||||
}
|
||||
|
|
@ -230,9 +230,9 @@ class HomeViewModel
|
|||
fun setFavorite(
|
||||
itemId: UUID,
|
||||
favorite: Boolean,
|
||||
) = viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
) = viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
favoriteWatchManager.setFavorite(itemId, favorite)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
init()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,9 +103,9 @@ import com.github.damontecres.wholphin.ui.rememberPosition
|
|||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.SearchRelevance
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -253,7 +253,7 @@ class SearchViewModel
|
|||
}
|
||||
|
||||
private fun searchCombined(query: String) {
|
||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
viewModelScope.launch(ExceptionHandler() + WholphinDispatchers.IO) {
|
||||
try {
|
||||
val request =
|
||||
GetItemsRequest(
|
||||
|
|
@ -477,7 +477,7 @@ fun SearchPage(
|
|||
) {
|
||||
if (!searchClicked) return@LaunchedEffect
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
// Want to focus on the first successful row after all of the ones before it are finished searching
|
||||
val results =
|
||||
if (isLibraryTab) {
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ import com.github.damontecres.wholphin.ui.util.ResStringProvider
|
|||
import com.github.damontecres.wholphin.ui.util.StringStringProvider
|
||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
|
|
@ -129,7 +129,7 @@ class HomeSettingsViewModel
|
|||
.let { state ->
|
||||
state.rows
|
||||
.map { row ->
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
semaphore.withPermit {
|
||||
try {
|
||||
homeSettingsService.fetchDataForRow(
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ import com.github.damontecres.wholphin.util.ExceptionHandler
|
|||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.PlaybackItemState
|
||||
import com.github.damontecres.wholphin.util.TrackActivityPlaybackListener
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import com.github.damontecres.wholphin.util.checkForSupport
|
||||
import com.github.damontecres.wholphin.util.mpv.MpvPlayer
|
||||
import com.github.damontecres.wholphin.util.mpv.mpvDeviceProfile
|
||||
|
|
@ -79,7 +80,6 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -242,7 +242,7 @@ class PlaybackViewModel
|
|||
Timber.d("Selected backend: %s", playerBackend)
|
||||
if (currentPlayer.value?.backend != playerBackend) {
|
||||
Timber.i("Switching player backend to %s", playerBackend)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
disconnectPlayer()
|
||||
}
|
||||
|
||||
|
|
@ -421,7 +421,7 @@ class PlaybackViewModel
|
|||
positionMs: Long,
|
||||
forceTranscoding: Boolean = this.forceTranscoding,
|
||||
): Boolean =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val item =
|
||||
when (playlistItem) {
|
||||
is PlaylistItem.Intro -> playlistItem.item
|
||||
|
|
@ -581,7 +581,7 @@ class PlaybackViewModel
|
|||
trickPlayInfo = trickPlayInfo,
|
||||
)
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
changeStreams(
|
||||
item,
|
||||
itemPlaybackToUse,
|
||||
|
|
@ -612,7 +612,7 @@ class PlaybackViewModel
|
|||
userInitiated: Boolean,
|
||||
enableDirectPlay: Boolean = !this.forceTranscoding,
|
||||
enableDirectStream: Boolean = !this.forceTranscoding,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
) = withContext(WholphinDispatchers.IO) {
|
||||
val itemId = item.id
|
||||
|
||||
val currentPlayback = state.value.currentPlayback
|
||||
|
|
@ -779,7 +779,7 @@ class PlaybackViewModel
|
|||
)
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
// TODO, don't need to release & recreate when switching streams
|
||||
this@PlaybackViewModel.activityListener?.let {
|
||||
it.release()
|
||||
|
|
@ -850,7 +850,7 @@ class PlaybackViewModel
|
|||
subtitleIndex: Int?,
|
||||
userInitiated: Boolean,
|
||||
): Boolean =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
// TODO there's probably no reason why we can't add external subtitles?
|
||||
Timber.v("changeStreams direct play")
|
||||
|
||||
|
|
@ -859,7 +859,7 @@ class PlaybackViewModel
|
|||
|
||||
if (externalSubtitle == null) {
|
||||
val result =
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
TrackSelectionUtils.createTrackSelections(
|
||||
onMain { player.trackSelectionParameters },
|
||||
onMain { player.currentTracks },
|
||||
|
|
@ -1124,7 +1124,7 @@ class PlaybackViewModel
|
|||
MediaSegmentType.INTRO -> prefs.skipIntros
|
||||
MediaSegmentType.UNKNOWN -> SkipSegmentBehavior.IGNORE
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
val newSegment =
|
||||
when (behavior) {
|
||||
SkipSegmentBehavior.AUTO_SKIP -> {
|
||||
|
|
@ -1318,7 +1318,7 @@ class PlaybackViewModel
|
|||
|
||||
override fun onPlayerError(error: PlaybackException) {
|
||||
Timber.e(error, "Playback error")
|
||||
viewModelScope.launch(Dispatchers.Main + ExceptionHandler()) {
|
||||
viewModelScope.launch(WholphinDispatchers.Main + ExceptionHandler()) {
|
||||
state.value.currentPlayback?.let {
|
||||
when (it.playMethod) {
|
||||
PlayMethod.TRANSCODE -> {
|
||||
|
|
@ -1346,7 +1346,7 @@ class PlaybackViewModel
|
|||
enableDirectPlay = false,
|
||||
enableDirectStream = false,
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
player.prepare()
|
||||
player.play()
|
||||
}
|
||||
|
|
@ -1367,7 +1367,7 @@ class PlaybackViewModel
|
|||
.subscribe<PlaystateMessage>()
|
||||
.onEach { message ->
|
||||
message.data?.let {
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
when (it.command) {
|
||||
PlaystateCommand.STOP -> {
|
||||
release()
|
||||
|
|
@ -1422,7 +1422,7 @@ class PlaybackViewModel
|
|||
* Atomically update [currentMediaInfo]
|
||||
*/
|
||||
internal suspend fun updateCurrentMedia(block: (CurrentMediaInfo) -> CurrentMediaInfo) =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(currentMediaInfo = block.invoke(it.currentMediaInfo))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.github.damontecres.wholphin.data.model.TrackIndex
|
|||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.onMain
|
||||
import com.github.damontecres.wholphin.ui.showToast
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -183,7 +183,7 @@ fun PlaybackViewModel.downloadAndSwitchSubtitles(
|
|||
}
|
||||
}
|
||||
subtitleSearchState.update { it.copy(status = SubtitleSearchStatus.Inactive) }
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
if (wasPlaying) {
|
||||
player.play()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
|||
import com.github.damontecres.wholphin.util.TrackSupport
|
||||
import com.github.damontecres.wholphin.util.TrackSupportReason
|
||||
import com.github.damontecres.wholphin.util.TrackType
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -90,7 +90,7 @@ fun PlaybackDebugOverlay(
|
|||
)
|
||||
|
||||
val memoryUsed by produceState("") {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(WholphinDispatchers.Default) {
|
||||
while (isActive) {
|
||||
val runtime = Runtime.getRuntime()
|
||||
val total = runtime.totalMemory()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.ui.window.Dialog
|
|||
import androidx.compose.ui.window.DialogProperties
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.wholphin.R
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ import com.github.damontecres.wholphin.ui.main.settings.MoveDirection
|
|||
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
@ -317,7 +317,7 @@ class NavDrawerPreferencesViewModel
|
|||
return@launchDefault
|
||||
}
|
||||
val navDrawerPins =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
serverPreferencesDao
|
||||
.getNavDrawerPinnedItems(user)
|
||||
.associateBy { it.itemId }
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import com.github.damontecres.wholphin.R
|
|||
import com.github.damontecres.wholphin.ui.FontAwesome
|
||||
import com.github.damontecres.wholphin.ui.PreviewTvSpec
|
||||
import com.github.damontecres.wholphin.ui.components.BasicDialog
|
||||
import com.github.damontecres.wholphin.ui.components.Button
|
||||
import com.github.damontecres.wholphin.ui.components.TextButton
|
||||
import com.github.damontecres.wholphin.ui.playback.isEnterKey
|
||||
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ import com.github.damontecres.wholphin.services.SetupNavigationManager
|
|||
import com.github.damontecres.wholphin.ui.launchDefault
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -119,7 +119,7 @@ class SwitchUserViewModel
|
|||
}
|
||||
|
||||
fun trySwitchUser(user: JellyfinUser): Deferred<String?> =
|
||||
viewModelScope.async(Dispatchers.IO) {
|
||||
viewModelScope.async(WholphinDispatchers.IO) {
|
||||
try {
|
||||
val current = serverRepository.changeUser(server, user)
|
||||
setupNavigationManager.navigateTo(SetupDestination.AppContent(current))
|
||||
|
|
@ -234,7 +234,7 @@ class SwitchUserViewModel
|
|||
}
|
||||
|
||||
private suspend fun getUsers(): List<JellyfinUserAndImage> =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(WholphinDispatchers.IO) {
|
||||
val api = jellyfin.createApi(server.url)
|
||||
val knownUsers =
|
||||
serverDao
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ import com.github.damontecres.wholphin.util.ApiRequestPager
|
|||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||
import com.github.damontecres.wholphin.util.LoadingState
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -377,7 +377,7 @@ class SlideshowViewModel
|
|||
),
|
||||
)
|
||||
Timber.d("Saved VideoFilter for image %s", it.image.id)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
showToast(
|
||||
context,
|
||||
"Saved",
|
||||
|
|
@ -406,7 +406,7 @@ class SlideshowViewModel
|
|||
),
|
||||
)
|
||||
Timber.d("Saved VideoFilter for album %s", slideshowSettings.parentId)
|
||||
withContext(Dispatchers.Main) {
|
||||
withContext(WholphinDispatchers.Main) {
|
||||
showToast(
|
||||
context,
|
||||
"Saved",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import androidx.compose.runtime.compositionLocalOf
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.github.damontecres.wholphin.ui.getTimeFormatter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import com.github.damontecres.wholphin.util.WholphinDispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -34,7 +34,7 @@ data class Clock(
|
|||
fun ProvideLocalClock(content: @Composable () -> Unit) {
|
||||
val clock = remember { Clock() }
|
||||
LaunchedEffect(Unit) {
|
||||
withContext(Dispatchers.Default) {
|
||||
withContext(WholphinDispatchers.Default) {
|
||||
while (isActive) {
|
||||
val now = LocalDateTime.now()
|
||||
val time = getTimeFormatter().format(now)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue