diff --git a/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt b/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt index b5bc119f..6aa749f1 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt @@ -60,10 +60,10 @@ import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.util.ProvideLocalClock import com.github.damontecres.wholphin.util.DebugLogTree import com.github.damontecres.wholphin.util.ExceptionHandler +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.first @@ -170,7 +170,7 @@ class MainActivity : AppCompatActivity() { viewModel.serverRepository.currentUserFlow .onEach { user -> - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { if (user?.hasPin == true) { window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) } else { @@ -184,7 +184,7 @@ class MainActivity : AppCompatActivity() { screensaverService.keepScreenOn .onEach { keepScreenOn -> Timber.v("keepScreenOn: %s", keepScreenOn) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { if (keepScreenOn) { window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } else { @@ -383,7 +383,7 @@ class MainActivity : AppCompatActivity() { } fun changeDisplayMode(modeId: Int) { - lifecycleScope.launch(Dispatchers.Main + ExceptionHandler(autoToast = true)) { + lifecycleScope.launch(WholphinDispatchers.Main + ExceptionHandler(autoToast = true)) { val attrs = window.attributes if (attrs.preferredDisplayModeId != modeId) { Timber.d("Switch preferredDisplayModeId to %s", modeId) diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt index b2dedf26..c3afbc33 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt @@ -7,7 +7,7 @@ import com.github.damontecres.wholphin.data.model.PlaybackLanguageChoice import com.github.damontecres.wholphin.data.model.TrackIndex import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.StreamChoiceService -import kotlinx.coroutines.Dispatchers +import com.github.damontecres.wholphin.util.WholphinDispatchers import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.MediaSourceInfo import org.jellyfin.sdk.model.api.MediaStream @@ -108,7 +108,7 @@ class ItemPlaybackRepository itemId: UUID, sourceId: UUID, ): ItemPlayback? = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { serverRepository.currentUser?.let { user -> val itemPlayback = ItemPlayback( diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt b/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt index 05cc9bd3..4f3ccbd1 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/ServerRepository.kt @@ -9,9 +9,9 @@ import com.github.damontecres.wholphin.data.model.JellyfinUser import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.services.hilt.IoDispatcher import com.github.damontecres.wholphin.ui.toServerString +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -109,7 +109,7 @@ class ServerRepository }.build() } val currentUser = CurrentUser(updatedServer, updatedUser) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { _current.value = currentUser _currentUserDto.value = userDto } @@ -222,7 +222,7 @@ class ServerRepository suspend fun removeUser(user: JellyfinUser) { if (current.value?.user?.id == user.id) { - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { _current.value = null } userPreferencesDataStore.updateData { @@ -241,7 +241,7 @@ class ServerRepository suspend fun removeServer(server: JellyfinServer) { if (current.value?.server?.id == server.id) { - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { _current.value = null } userPreferencesDataStore.updateData { diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/BackdropService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/BackdropService.kt index 1bf34929..8025a6f6 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/BackdropService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/BackdropService.kt @@ -18,8 +18,8 @@ import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.DiscoverItem import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.preferences.BackdropStyle +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow @@ -55,7 +55,7 @@ class BackdropService * Update the backdrop to use the specified item */ suspend fun submit(item: BaseItem) = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { val imageUrl = if (item.type == BaseItemKind.GENRE) { item.imageUrlOverride @@ -76,7 +76,7 @@ class BackdropService suspend fun submit( itemId: String, imageUrl: String?, - ) = withContext(Dispatchers.IO) { + ) = withContext(WholphinDispatchers.IO) { if (backdropFlow.firstOrNull()?.imageUrl != imageUrl) { _backdropFlow.update { it.copy( @@ -132,7 +132,7 @@ class BackdropService } suspend fun extractColorsFromBackdrop(imageUrl: String?): ExtractedColors = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { if (imageUrl.isNullOrBlank()) { return@withContext ExtractedColors.DEFAULT } diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt index 382ac22e..ceb84695 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt @@ -9,12 +9,12 @@ import com.github.damontecres.wholphin.preferences.AppPreference import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope import com.github.damontecres.wholphin.ui.collectLatestIn import com.github.damontecres.wholphin.util.GetEpisodesRequestHandler +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.google.common.cache.CacheBuilder import dagger.hilt.android.qualifiers.ActivityContext import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.withContext import org.jellyfin.sdk.api.client.ApiClient @@ -56,7 +56,7 @@ class DatePlayedService adjacentTo = item.id, limit = 1, ) - return scope.async(Dispatchers.IO) { + return scope.async(WholphinDispatchers.IO) { val premiereDate = item.data.premiereDate try { val result = @@ -92,7 +92,7 @@ class DatePlayedService * the previous episode's last played timestamp, and the episode's premiere date */ suspend fun getLastPlayed(item: BaseItem): LocalDateTime? = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { val seriesId = item.data.seriesId return@withContext if (seriesId != null) { datePlayedCache diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/DeviceProfileService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/DeviceProfileService.kt index 4405092e..ce4ea7dc 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/DeviceProfileService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/DeviceProfileService.kt @@ -3,10 +3,10 @@ package com.github.damontecres.wholphin.services import android.content.Context import com.github.damontecres.wholphin.preferences.AssPlaybackMode import com.github.damontecres.wholphin.preferences.PlaybackPreferences +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.profile.MediaCodecCapabilitiesTest import com.github.damontecres.wholphin.util.profile.createDeviceProfile import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext @@ -37,7 +37,7 @@ class DeviceProfileService prefs: PlaybackPreferences, serverVersion: ServerVersion?, ): DeviceProfile = - withContext(Dispatchers.Default) { + withContext(WholphinDispatchers.Default) { mutex.withLock { val newConfig = DeviceProfileConfiguration( diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpService.kt index 2bc9943f..f67dd100 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpService.kt @@ -8,8 +8,8 @@ package com.github.damontecres.wholphin.services import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.util.LocalDateTimeSerializer +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.supportItemKinds -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.sync.Semaphore @@ -143,14 +143,14 @@ class LatestNextUpService resume: List, nextUp: List, ): List = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { val start = System.currentTimeMillis() val semaphore = Semaphore(3) val deferred = nextUp .filter { it.data.seriesId != null } .map { item -> - async(Dispatchers.IO) { + async(WholphinDispatchers.IO) { try { semaphore.withPermit { datePlayedService.getLastPlayed(item) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpWorker.kt b/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpWorker.kt index 04706b94..01ed9dd2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpWorker.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/LatestNextUpWorker.kt @@ -16,12 +16,12 @@ import androidx.work.workDataOf import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.ui.collectLatestIn import com.github.damontecres.wholphin.util.ExceptionHandler +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.assisted.Assisted import dagger.assisted.AssistedInject import dagger.hilt.android.qualifiers.ActivityContext import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.model.serializer.toUUIDOrNull @@ -92,7 +92,7 @@ class LatestNextUpSchedulerService ) // Exposed for testing - internal var dispatcher: CoroutineDispatcher = Dispatchers.IO + internal var dispatcher: CoroutineDispatcher = WholphinDispatchers.IO init { serverRepository.current.collectLatestIn(activity.lifecycleScope) { user -> diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/MusicService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/MusicService.kt index c339a8dd..de99d579 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/MusicService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/MusicService.kt @@ -24,10 +24,10 @@ import com.github.damontecres.wholphin.util.BlockingList 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.profile.supportedAudioCodecs import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -177,9 +177,9 @@ class MusicService items: BlockingList, startIndex: Int, shuffled: Boolean, - ) = withContext(Dispatchers.IO) { + ) = withContext(WholphinDispatchers.IO) { Timber.d("setQueue: %s items, startIndex=%s, shuffled=%s", items.size, startIndex, shuffled) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { player.setMediaItems(emptyList()) player.shuffleModeEnabled = shuffled } @@ -199,7 +199,7 @@ class MusicService items .filter { it.type == BaseItemKind.AUDIO } .map(::convert) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { player.setMediaItems(mediaItems) player.shuffleModeEnabled = shuffled updateQueueSize() @@ -216,7 +216,7 @@ class MusicService ) { if (item.type == BaseItemKind.AUDIO) { val mediaItem = convert(item) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { if (index != null) { player.addMediaItem(index, mediaItem) } else { @@ -293,7 +293,7 @@ class MusicService */ private suspend fun updateQueueSize() { // val ids = -// withContext(Dispatchers.Default) { +// withContext(WholphinDispatchers.Default) { // (0..() .onEach { message -> message.data?.let { - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { when (it.command) { PlaystateCommand.STOP -> { stop() diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/NavDrawerService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/NavDrawerService.kt index 21253e1e..b8322efe 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/NavDrawerService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/NavDrawerService.kt @@ -13,11 +13,11 @@ import com.github.damontecres.wholphin.ui.nav.Destination import com.github.damontecres.wholphin.ui.nav.NavDrawerItem import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem import com.github.damontecres.wholphin.ui.showToast +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.supportedCollectionTypes import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -209,7 +209,7 @@ class NavDrawerService val allItems = builtins + libraries val navDrawerPins = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { serverPreferencesDao.getNavDrawerPinnedItems(user).associateBy { it.itemId } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/PlayerFactory.kt b/app/src/main/java/com/github/damontecres/wholphin/services/PlayerFactory.kt index 7f4886b4..6cdeeb34 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/PlayerFactory.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/PlayerFactory.kt @@ -29,6 +29,7 @@ import com.github.damontecres.wholphin.preferences.MediaExtensionStatus import com.github.damontecres.wholphin.preferences.PlaybackPreferences import com.github.damontecres.wholphin.preferences.PlayerBackend import com.github.damontecres.wholphin.services.hilt.AuthOkHttpClient +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.mpv.MpvPlayer import dagger.hilt.android.qualifiers.ApplicationContext import io.github.peerless2012.ass.media.AssHandler @@ -36,7 +37,6 @@ import io.github.peerless2012.ass.media.factory.AssRenderersFactory import io.github.peerless2012.ass.media.kt.withAssMkvSupport import io.github.peerless2012.ass.media.parser.AssSubtitleParserFactory import io.github.peerless2012.ass.media.type.AssRenderType -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import timber.log.Timber @@ -62,7 +62,7 @@ class PlayerFactory backend: PlayerBackend, prefs: PlaybackPreferences, ): PlayerCreation { - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { if (currentPlayer?.isReleased == false) { Timber.w("Player was not released before trying to create a new one!") currentPlayer?.release() @@ -138,7 +138,7 @@ class PlayerFactory .build() .apply { assHandler?.init(this) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { setAudioAttributes( AudioAttributes .Builder() diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/RefreshRateService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/RefreshRateService.kt index 91df9518..174c103b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/RefreshRateService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/RefreshRateService.kt @@ -8,9 +8,9 @@ import android.os.Looper import android.view.Display import com.github.damontecres.wholphin.MainActivity import com.github.damontecres.wholphin.ui.showToast +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeoutOrNull @@ -38,7 +38,7 @@ class RefreshRateService stream: MediaStream, switchRefreshRate: Boolean, switchResolution: Boolean, - ) = withContext(Dispatchers.IO) { + ) = withContext(WholphinDispatchers.IO) { if (!switchRefreshRate && !switchResolution) { Timber.v("Not switching either refresh rate nor resolution") return@withContext diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/RememberedTabService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/RememberedTabService.kt index 515caad4..a3b5b795 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/RememberedTabService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/RememberedTabService.kt @@ -3,7 +3,7 @@ package com.github.damontecres.wholphin.services import com.github.damontecres.wholphin.data.RememberedTabDao import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.model.RememberedTab -import kotlinx.coroutines.Dispatchers +import com.github.damontecres.wholphin.util.WholphinDispatchers import kotlinx.coroutines.withContext import javax.inject.Inject import javax.inject.Singleton @@ -16,7 +16,7 @@ class RememberedTabService private val rememberedTabDao: RememberedTabDao, ) { suspend fun getRememberedTab(itemId: String): Int? = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { serverRepository.currentUser?.rowId?.let { userId -> rememberedTabDao.getRememberedTab(userId, itemId)?.index } @@ -26,7 +26,7 @@ class RememberedTabService itemId: String, tabIndex: Int, ): Unit = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { serverRepository.currentUser?.rowId?.let { userId -> rememberedTabDao.save(RememberedTab(userId, itemId, tabIndex)) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/ScreensaverService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/ScreensaverService.kt index 6069c00a..871a20e2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/ScreensaverService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/ScreensaverService.kt @@ -10,10 +10,10 @@ import com.github.damontecres.wholphin.ui.launchDefault 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.WholphinDispatchers import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow @@ -224,7 +224,7 @@ class ScreensaverService if (index > pager.lastIndex) index = 0 } } - }.flowOn(Dispatchers.Default).cancellable() + }.flowOn(WholphinDispatchers.Default).cancellable() private suspend fun createPager(): ApiRequestPager { val prefs = diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsCache.kt b/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsCache.kt index 0921a1be..eedbffc5 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsCache.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsCache.kt @@ -4,11 +4,11 @@ package com.github.damontecres.wholphin.services import android.content.Context import com.github.damontecres.wholphin.ui.toServerString +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.mayakapps.kache.InMemoryKache import com.mayakapps.kache.ObjectKache import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.ExperimentalSerializationApi @@ -43,7 +43,7 @@ class SuggestionsCache private val memoryCache = InMemoryKache(maxSize = 8) { - creationScope = CoroutineScope(Dispatchers.IO) + creationScope = CoroutineScope(WholphinDispatchers.IO) } private fun cacheKey( diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsWorker.kt b/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsWorker.kt index 800d31fd..aa64058d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsWorker.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/SuggestionsWorker.kt @@ -9,9 +9,9 @@ import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.preferences.AppPreference import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.util.GetItemsRequestHandler +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.assisted.Assisted import dagger.assisted.AssistedInject -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope @@ -81,7 +81,7 @@ class SuggestionsWorker .takeIf { it > 0 } ?: AppPreference.HomePageItems.defaultValue.toInt() - val context = Dispatchers.IO.limitedParallelism(2, "fetchSuggestions") + val context = WholphinDispatchers.IO.limitedParallelism(2, "fetchSuggestions") if (requestedParentId != null && requestedItemKind != null) { Timber.d( "Fetching on-demand suggestions for parent=%s kind=%s", @@ -128,7 +128,7 @@ class SuggestionsWorker supervisorScope { supportedViews .map { view -> - async(Dispatchers.IO) { + async(WholphinDispatchers.IO) { runCatching { Timber.v("Fetching suggestions for parent=%s kind=%s", view.id, view.itemKind) fetchAndCacheSuggestions( @@ -293,7 +293,7 @@ class SuggestionsWorker limit = freshLimit, ) } - withContext(Dispatchers.Default) { + withContext(WholphinDispatchers.Default) { val contextual = contextualDeferred.await() val random = randomDeferred.await() val fresh = freshDeferred.await() diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/ThemeSongPlayer.kt b/app/src/main/java/com/github/damontecres/wholphin/services/ThemeSongPlayer.kt index e1b6cf1b..036ca505 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/ThemeSongPlayer.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/ThemeSongPlayer.kt @@ -14,10 +14,10 @@ import com.github.damontecres.wholphin.preferences.ThemeSongVolume import com.github.damontecres.wholphin.services.hilt.AuthOkHttpClient import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope import com.github.damontecres.wholphin.ui.launchIO +import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.profile.Codec import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.flow.MutableStateFlow @@ -102,7 +102,7 @@ class ThemeSongPlayer Codec.Audio.FLAC, ), ) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { player.apply { stop() volume = volumeLevel @@ -127,7 +127,7 @@ class ThemeSongPlayer scope.launch { mutex.withLock { state.value.job?.cancelAndJoin() - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { Timber.v("Stopping theme song") player.stop() } diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/UpdateChecker.kt b/app/src/main/java/com/github/damontecres/wholphin/services/UpdateChecker.kt index b56d8a7d..7fbcbe53 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/UpdateChecker.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/UpdateChecker.kt @@ -21,8 +21,8 @@ import com.github.damontecres.wholphin.services.hilt.StandardOkHttpClient import com.github.damontecres.wholphin.ui.isNotNullOrBlank import com.github.damontecres.wholphin.ui.showToast import com.github.damontecres.wholphin.util.Version +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json @@ -131,7 +131,7 @@ class UpdateChecker suspend fun getRelease(version: Version): Release? { val url = "https://api.github.com/repos/damontecres/Wholphin/releases/tags/v${version.major}.${version.minor}.${version.patch}" - return withContext(Dispatchers.IO) { + return withContext(WholphinDispatchers.IO) { val request = Request .Builder() @@ -146,7 +146,7 @@ class UpdateChecker * Get the latest released version */ suspend fun getLatestRelease(updateUrl: String): Release? = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { val request = Request .Builder() @@ -199,7 +199,7 @@ class UpdateChecker release: Release, callback: DownloadCallback, ) { - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { cleanup() val request = Request @@ -210,7 +210,7 @@ class UpdateChecker okHttpClient.newCall(request).execute().use { if (it.isSuccessful && it.body != null) { Timber.v("Request successful for ${release.downloadUrl}") - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { callback.contentLength(it.body.contentLength()) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -396,7 +396,7 @@ suspend fun copyTo( while (bytes >= 0) { out.write(buffer, 0, bytes) bytesCopied += bytes - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { callback.bytesDownloaded(bytesCopied) } bytes = input.read(buffer) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/UserSwitchListener.kt b/app/src/main/java/com/github/damontecres/wholphin/services/UserSwitchListener.kt index 2565f077..536dfb40 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/UserSwitchListener.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/UserSwitchListener.kt @@ -12,9 +12,9 @@ import com.github.damontecres.wholphin.data.model.JellyfinUser import com.github.damontecres.wholphin.data.model.SeerrAuthMethod import com.github.damontecres.wholphin.ui.launchDefault import com.github.damontecres.wholphin.ui.launchIO +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.hilt.android.qualifiers.ActivityContext import dagger.hilt.android.scopes.ActivityScoped -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.update import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.withContext @@ -56,7 +56,7 @@ class UserSwitchListener user.uiLanguage?.let { LocaleListCompat.forLanguageTags(it) } ?: LocaleListCompat.getEmptyLocaleList() Timber.i("Switching locale to %s", localeList) - withContext(Dispatchers.Main) { + withContext(WholphinDispatchers.Main) { AppCompatDelegate.setApplicationLocales(localeList) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/hilt/AppModule.kt b/app/src/main/java/com/github/damontecres/wholphin/services/hilt/AppModule.kt index 25dd1be3..06607cf9 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/hilt/AppModule.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/hilt/AppModule.kt @@ -7,6 +7,7 @@ import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.services.SeerrApi import com.github.damontecres.wholphin.util.CoroutineContextApiClientFactory +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -14,7 +15,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import okhttp3.OkHttpClient import org.jellyfin.sdk.Jellyfin @@ -42,21 +42,21 @@ annotation class AuthOkHttpClient annotation class StandardOkHttpClient /** - * A [CoroutineScope] with [Dispatchers.IO] + * A [CoroutineScope] with [WholphinDispatchers.IO] */ @Qualifier @Retention(AnnotationRetention.BINARY) annotation class IoCoroutineScope /** - * A [CoroutineScope] with [Dispatchers.Default] + * A [CoroutineScope] with [WholphinDispatchers.Default] */ @Qualifier @Retention(AnnotationRetention.BINARY) annotation class DefaultCoroutineScope /** - * [Dispatchers.IO] + * [WholphinDispatchers.IO] * * @see IoCoroutineScope */ @@ -65,7 +65,7 @@ annotation class DefaultCoroutineScope annotation class IoDispatcher /** - * [Dispatchers.Default] + * [WholphinDispatchers.Default] * * @see DefaultCoroutineScope */ @@ -156,7 +156,7 @@ object AppModule { @Provides @Singleton @IoDispatcher - fun ioDispatcher(): CoroutineDispatcher = Dispatchers.IO + fun ioDispatcher(): CoroutineDispatcher = WholphinDispatchers.IO @Provides @Singleton @@ -168,7 +168,7 @@ object AppModule { @Provides @Singleton @DefaultDispatcher - fun defaultDispatcher(): CoroutineDispatcher = Dispatchers.Default + fun defaultDispatcher(): CoroutineDispatcher = WholphinDispatchers.Default @Provides @Singleton diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/hilt/DatabaseModule.kt b/app/src/main/java/com/github/damontecres/wholphin/services/hilt/DatabaseModule.kt index 97718089..29688664 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/hilt/DatabaseModule.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/hilt/DatabaseModule.kt @@ -44,7 +44,7 @@ object DatabaseModule { ).addMigrations(Migrations.Migrate2to3) // .setQueryCallback({ sqlQuery, args -> // Timber.v("sqlQuery=$sqlQuery, args=$args") -// }, Dispatchers.IO.asExecutor()) +// }, WholphinDispatchers.IO.asExecutor()) .build() @Provides diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/Extensions.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/Extensions.kt index 2c633c35..31ad597a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/Extensions.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/Extensions.kt @@ -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 onMain(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block) +suspend fun onMain(block: suspend CoroutineScope.() -> T) = withContext(WholphinDispatchers.Main, block) fun Modifier.dimAndBlur(enabled: Boolean) = this.ifElse( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GenreCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GenreCard.kt index a32fece9..654999f4 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GenreCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GenreCard.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/StudioCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/StudioCard.kt index fb89a58b..c128285d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/StudioCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/StudioCard.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderView.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderView.kt index eb769626..dd6ed7ce 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderView.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderView.kt @@ -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) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt index 18e335f1..00dfbb56 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/GenreCardGrid.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/ItemGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/ItemGrid.kt index d4609d79..9a188a6c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/ItemGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/ItemGrid.kt @@ -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) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt index dd264d0f..7dc5d11a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt @@ -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() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/StudioCardGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/StudioCardGrid.kt index cf3e7ed9..3f424bad 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/StudioCardGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/StudioCardGrid.kt @@ -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, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceInputManager.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceInputManager.kt index d2d6fa32..57874b0c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceInputManager.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/VoiceInputManager.kt @@ -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() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/CardGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/CardGrid.kt index 1d42848b..b399766c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/CardGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/CardGrid.kt @@ -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 CardGrid( { letter: Char -> scope.launch(ExceptionHandler()) { val jumpPosition = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { letterPosition.invoke(letter) } Timber.d("Alphabet jump to $jumpPosition") diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/HomeRowGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/HomeRowGrid.kt index 51c496dc..7948662c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/HomeRowGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/HomeRowGrid.kt @@ -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) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/PlaylistDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/PlaylistDetails.kt index 0557edbc..070268cb 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/PlaylistDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/PlaylistDetails.kt @@ -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) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/collection/CollectionViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/collection/CollectionViewModel.kt index 3b778ce6..1576b745 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/collection/CollectionViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/collection/CollectionViewModel.kt @@ -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() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieViewModel.kt index 60e6a816..14440539 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieViewModel.kt @@ -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 = - 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)) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverSeriesViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverSeriesViewModel.kt index 4a13c65f..96ba1efa 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverSeriesViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverSeriesViewModel.kt @@ -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 = - 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)) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt index 1c6249da..ef94620a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt @@ -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() } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/TvGuideGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/TvGuideGrid.kt index e4cc19ec..c9b72031 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/TvGuideGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/livetv/TvGuideGrid.kt @@ -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 } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/AlbumDetailsPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/AlbumDetailsPage.kt index 293807fb..55dc6b4c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/AlbumDetailsPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/AlbumDetailsPage.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/ArtistDetailsPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/ArtistDetailsPage.kt index e87419aa..d8806b59 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/ArtistDetailsPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/ArtistDetailsPage.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt index db5bbf4c..f8dc0ccd 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingButtons.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingViewModel.kt index f1cc9225..a076bd29 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/NowPlayingViewModel.kt @@ -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(20) { - creationScope = CoroutineScope(Dispatchers.IO) + creationScope = CoroutineScope(WholphinDispatchers.IO) } init { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/SongListDisplay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/SongListDisplay.kt index 4e5fa329..011bb8ea 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/SongListDisplay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/music/SongListDisplay.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt index bdce9a20..499dc44f 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt @@ -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> = - 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) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/discover/SeerrRequestsPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/discover/SeerrRequestsPage.kt index d83f840b..50f2464c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/discover/SeerrRequestsPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/discover/SeerrRequestsPage.kt @@ -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) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt index d6dd37e2..feaf8d04 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt @@ -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() } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt index ecb0e74d..ea978971 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/SearchPage.kt @@ -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) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt index 22a55f12..4fb8398e 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt @@ -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( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt index f197998f..fbc694d5 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt @@ -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() .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)) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/SubtitleSearchUtils.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/SubtitleSearchUtils.kt index 5892b01a..95d52a1a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/SubtitleSearchUtils.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/SubtitleSearchUtils.kt @@ -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() } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt index 1420ffb6..2aecdc65 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/overlay/PlaybackDebugOverlay.kt @@ -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() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/LocaleChoiceDialog.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/LocaleChoiceDialog.kt index a3e50a85..b352c550 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/LocaleChoiceDialog.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/LocaleChoiceDialog.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt index 4f2fb968..e2024aa2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/preferences/NavDrawerPreference.kt @@ -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 } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt index f9f22591..ef97620c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/PinEntry.kt @@ -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 diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt index fce4a01c..8b8c159a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/setup/SwitchUserViewModel.kt @@ -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 = - 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 = - withContext(Dispatchers.IO) { + withContext(WholphinDispatchers.IO) { val api = jellyfin.createApi(server.url) val knownUsers = serverDao diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/slideshow/SlideshowViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/slideshow/SlideshowViewModel.kt index 9744c9de..8db01751 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/slideshow/SlideshowViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/slideshow/SlideshowViewModel.kt @@ -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", diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/util/LocalClock.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/util/LocalClock.kt index 213dc725..8664d604 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/util/LocalClock.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/util/LocalClock.kt @@ -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) diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/CoroutineContextApiClient.kt b/app/src/main/java/com/github/damontecres/wholphin/util/CoroutineContextApiClient.kt index 3ea6bdf9..412130d7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/util/CoroutineContextApiClient.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/util/CoroutineContextApiClient.kt @@ -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( diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/RequestPager.kt b/app/src/main/java/com/github/damontecres/wholphin/util/RequestPager.kt index b478338b..d8a34de6 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/util/RequestPager.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/util/RequestPager.kt @@ -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( get() = totalCount private fun fetchPage(position: Int): Job = - scope.launch(ExceptionHandler() + Dispatchers.IO) { + scope.launch(ExceptionHandler() + WholphinDispatchers.IO) { fetchPageBlocking(position, false) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/TrackActivityPlaybackListener.kt b/app/src/main/java/com/github/damontecres/wholphin/util/TrackActivityPlaybackListener.kt index 86ba1425..30241845 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/util/TrackActivityPlaybackListener.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/util/TrackActivityPlaybackListener.kt @@ -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( diff --git a/app/src/main/java/com/github/damontecres/wholphin/util/WholphinDispatchers.kt b/app/src/main/java/com/github/damontecres/wholphin/util/WholphinDispatchers.kt new file mode 100644 index 00000000..2a466742 --- /dev/null +++ b/app/src/main/java/com/github/damontecres/wholphin/util/WholphinDispatchers.kt @@ -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 +} diff --git a/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpSchedulerServiceTest.kt b/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpSchedulerServiceTest.kt index d4f4d436..256ee9d8 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpSchedulerServiceTest.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpSchedulerServiceTest.kt @@ -8,17 +8,17 @@ import androidx.lifecycle.LifecycleRegistry import androidx.work.WorkManager import com.github.damontecres.wholphin.data.CurrentUser import com.github.damontecres.wholphin.data.ServerRepository +import com.github.damontecres.wholphin.util.WholphinDispatchers +import com.github.damontecres.wholphin.util.configure +import com.github.damontecres.wholphin.util.reset import io.mockk.every import io.mockk.mockk import io.mockk.verify -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.advanceUntilIdle -import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before import org.junit.Rule @@ -36,14 +36,14 @@ class LatestNextUpSchedulerServiceTest { @Before fun setUp() { - Dispatchers.setMain(testDispatcher) + WholphinDispatchers.configure(testDispatcher) every { mockActivity.lifecycle } returns lifecycleRegistry every { mockServerRepository.current } returns currentUser lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME) } @After - fun tearDown() = Dispatchers.resetMain() + fun tearDown() = WholphinDispatchers.reset() private fun createService() = LatestNextUpSchedulerService( @@ -56,7 +56,7 @@ class LatestNextUpSchedulerServiceTest { @Test fun cancels_latestNextUp_work_when_user_null() = - runTest { + runTest(testDispatcher) { createService() currentUser.value = null diff --git a/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpServiceTests.kt b/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpServiceTests.kt index 4c605df4..d4590cf7 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpServiceTests.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/services/LatestNextUpServiceTests.kt @@ -5,15 +5,15 @@ package com.github.damontecres.wholphin.services +import com.github.damontecres.wholphin.util.WholphinDispatchers +import com.github.damontecres.wholphin.util.configure +import com.github.damontecres.wholphin.util.reset import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import kotlinx.serialization.UseSerializers import kotlinx.serialization.json.Json import org.jellyfin.sdk.api.client.ApiClient @@ -56,14 +56,14 @@ class LatestNextUpServiceTests { @OptIn(ExperimentalCoroutinesApi::class) @Before fun setUp() { - Dispatchers.setMain(testDispatcher) + WholphinDispatchers.configure(testDispatcher) every { mockApi.tvShowsApi } returns mockTvShowsApi } @OptIn(ExperimentalCoroutinesApi::class) @After fun tearDown() { - Dispatchers.resetMain() + WholphinDispatchers.reset() } @Test diff --git a/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionServiceTest.kt b/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionServiceTest.kt index 436fd360..403a2715 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionServiceTest.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionServiceTest.kt @@ -8,19 +8,19 @@ import androidx.work.WorkManager import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.model.JellyfinUser import com.github.damontecres.wholphin.util.GetItemsRequestHandler +import com.github.damontecres.wholphin.util.WholphinDispatchers +import com.github.damontecres.wholphin.util.configure +import com.github.damontecres.wholphin.util.reset import io.mockk.coEvery import io.mockk.every import io.mockk.mockk import io.mockk.verify -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.Response import org.jellyfin.sdk.model.api.BaseItemDto @@ -48,12 +48,12 @@ class SuggestionServiceTest { @Before fun setUp() { - Dispatchers.setMain(testDispatcher) + WholphinDispatchers.configure(testDispatcher) } @After fun tearDown() { - Dispatchers.resetMain() + WholphinDispatchers.reset() io.mockk.unmockkObject(GetItemsRequestHandler) } diff --git a/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionsSchedulerServiceTest.kt b/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionsSchedulerServiceTest.kt index 0d52db15..f66e7292 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionsSchedulerServiceTest.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/services/SuggestionsSchedulerServiceTest.kt @@ -11,19 +11,19 @@ import com.github.damontecres.wholphin.data.CurrentUser import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.model.JellyfinServer import com.github.damontecres.wholphin.data.model.JellyfinUser +import com.github.damontecres.wholphin.util.WholphinDispatchers +import com.github.damontecres.wholphin.util.configure +import com.github.damontecres.wholphin.util.reset import com.google.common.util.concurrent.ListenableFuture import io.mockk.every import io.mockk.mockk import io.mockk.slot import io.mockk.verify -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.advanceUntilIdle -import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before @@ -43,14 +43,14 @@ class SuggestionsSchedulerServiceTest { @Before fun setUp() { - Dispatchers.setMain(testDispatcher) + WholphinDispatchers.configure(testDispatcher) every { mockActivity.lifecycle } returns lifecycleRegistry every { mockServerRepository.current } returns currentUser lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME) } @After - fun tearDown() = Dispatchers.resetMain() + fun tearDown() = WholphinDispatchers.reset() private fun createService() = SuggestionsSchedulerService( diff --git a/app/src/test/java/com/github/damontecres/wholphin/ui/BasicUiTests.kt b/app/src/test/java/com/github/damontecres/wholphin/ui/BasicUiTests.kt index 027afb98..2e2c3a89 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/ui/BasicUiTests.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/ui/BasicUiTests.kt @@ -27,18 +27,17 @@ import com.github.damontecres.wholphin.ui.setup.SwitchServerContent import com.github.damontecres.wholphin.ui.setup.SwitchServerViewModel import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.util.LoadingState +import com.github.damontecres.wholphin.util.WholphinDispatchers +import com.github.damontecres.wholphin.util.configure +import com.github.damontecres.wholphin.util.reset import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication import io.mockk.coEvery import io.mockk.every import io.mockk.mockk -import io.mockk.mockkStatic -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.test.resetMain -import kotlinx.coroutines.test.setMain import org.jellyfin.sdk.Jellyfin import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.extensions.quickConnectApi @@ -105,11 +104,7 @@ class BasicUiTests { @OptIn(ExperimentalCoroutinesApi::class) @Before fun setup() { - Dispatchers.setMain(TestModule.testDispatcher) - mockkStatic(Dispatchers::class) - - every { Dispatchers.IO } returns TestModule.testDispatcher - every { Dispatchers.Default } returns TestModule.testDispatcher + WholphinDispatchers.configure(TestModule.testDispatcher) hiltRule.inject() screensaverService = mockk(relaxed = true) @@ -130,7 +125,7 @@ class BasicUiTests { @OptIn(ExperimentalCoroutinesApi::class) @After fun tearDown() { - Dispatchers.resetMain() + WholphinDispatchers.reset() } /** diff --git a/app/src/test/java/com/github/damontecres/wholphin/ui/TestModule.kt b/app/src/test/java/com/github/damontecres/wholphin/ui/TestModule.kt index e2026a4d..c4a54ec2 100644 --- a/app/src/test/java/com/github/damontecres/wholphin/ui/TestModule.kt +++ b/app/src/test/java/com/github/damontecres/wholphin/ui/TestModule.kt @@ -36,6 +36,7 @@ import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope import com.github.damontecres.wholphin.services.hilt.IoDispatcher import com.github.damontecres.wholphin.services.hilt.StandardOkHttpClient import com.github.damontecres.wholphin.util.CoroutineContextApiClientFactory +import com.github.damontecres.wholphin.util.WholphinDispatchers import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -46,7 +47,6 @@ import io.mockk.every import io.mockk.mockk import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.asExecutor import kotlinx.coroutines.test.StandardTestDispatcher @@ -225,7 +225,7 @@ object TestDatabaseModule { .allowMainThreadQueries() .setQueryCallback({ sqlQuery, args -> Timber.v("sqlQuery=$sqlQuery, args=$args") - }, Dispatchers.IO.asExecutor()) + }, WholphinDispatchers.IO.asExecutor()) .build() @Provides diff --git a/app/src/test/java/com/github/damontecres/wholphin/util/WholphinDispatchersTest.kt b/app/src/test/java/com/github/damontecres/wholphin/util/WholphinDispatchersTest.kt new file mode 100644 index 00000000..daeb934d --- /dev/null +++ b/app/src/test/java/com/github/damontecres/wholphin/util/WholphinDispatchersTest.kt @@ -0,0 +1,21 @@ +package com.github.damontecres.wholphin.util + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain + +@OptIn(ExperimentalCoroutinesApi::class) +fun WholphinDispatchers.configure(testDispatcher: TestDispatcher) { + Dispatchers.setMain(testDispatcher) + IO = testDispatcher + Default = testDispatcher +} + +@OptIn(ExperimentalCoroutinesApi::class) +fun WholphinDispatchers.reset() { + Dispatchers.resetMain() + IO = Dispatchers.IO + Default = Dispatchers.Default +}