Fix some threading issues (#364)

Fixes thread used by changes from #359 

Also create the device direct play profile lazily-ish off of the main
thread because this can take some time to create.

Should help address some of the "too much work" reported in #363, and
also fixes the network-on-main exception in the logs on #363
This commit is contained in:
damontecres 2025-12-02 19:17:28 -05:00 committed by GitHub
parent 56bf3cb7a0
commit bddf51e076
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 123 additions and 45 deletions

View file

@ -84,7 +84,7 @@ class RecommendedTvShowViewModel
?: AppPreference.HomePageItems.defaultValue.toInt()
try {
val resumeItemsDeferred =
viewModelScope.async {
viewModelScope.async(Dispatchers.IO) {
val resumeItemsRequest =
GetResumeItemsRequest(
parentId = parentId,
@ -101,7 +101,7 @@ class RecommendedTvShowViewModel
}
val nextUpItemsDeferred =
viewModelScope.async {
viewModelScope.async(Dispatchers.IO) {
val nextUpRequest =
GetNextUpRequest(
parentId = parentId,

View file

@ -12,7 +12,6 @@ import com.github.damontecres.wholphin.data.model.JellyfinUser
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.ui.components.ErrorMessage
import org.jellyfin.sdk.model.api.DeviceProfile
/**
* This is generally the root composable of the of the app
@ -25,7 +24,6 @@ fun ApplicationContent(
user: JellyfinUser?,
navigationManager: NavigationManager,
preferences: UserPreferences,
deviceProfile: DeviceProfile,
modifier: Modifier = Modifier,
) {
NavDisplay(
@ -44,14 +42,12 @@ fun ApplicationContent(
DestinationContent(
destination = key,
preferences = preferences,
deviceProfile = deviceProfile,
modifier = modifier.fillMaxSize(),
)
} else if (user != null && server != null) {
NavDrawer(
destination = key,
preferences = preferences,
deviceProfile = deviceProfile,
user = user,
server = server,
modifier = modifier,

View file

@ -32,7 +32,6 @@ import com.github.damontecres.wholphin.ui.setup.SwitchServerContent
import com.github.damontecres.wholphin.ui.setup.SwitchUserContent
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.DeviceProfile
import timber.log.Timber
/**
@ -42,7 +41,6 @@ import timber.log.Timber
fun DestinationContent(
destination: Destination,
preferences: UserPreferences,
deviceProfile: DeviceProfile,
modifier: Modifier = Modifier,
) {
when (destination) {
@ -56,7 +54,6 @@ fun DestinationContent(
->
PlaybackPage(
preferences = preferences,
deviceProfile = deviceProfile,
destination = destination,
modifier = modifier,
)

View file

@ -95,7 +95,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.DeviceProfile
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
@ -211,7 +210,6 @@ fun NavDrawer(
preferences: UserPreferences,
user: JellyfinUser,
server: JellyfinServer,
deviceProfile: DeviceProfile,
modifier: Modifier = Modifier,
viewModel: NavDrawerViewModel =
hiltViewModel(
@ -526,7 +524,6 @@ fun NavDrawer(
DestinationContent(
destination = destination,
preferences = preferences,
deviceProfile = deviceProfile,
modifier =
Modifier
.fillMaxSize(),

View file

@ -81,7 +81,6 @@ import com.github.damontecres.wholphin.util.LoadingState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.DeviceProfile
import org.jellyfin.sdk.model.extensions.ticks
import java.util.UUID
import kotlin.time.Duration.Companion.milliseconds
@ -94,7 +93,6 @@ import kotlin.time.Duration.Companion.seconds
@Composable
fun PlaybackPage(
preferences: UserPreferences,
deviceProfile: DeviceProfile,
destination: Destination,
modifier: Modifier = Modifier,
viewModel: PlaybackViewModel = hiltViewModel(),
@ -105,7 +103,7 @@ fun PlaybackPage(
}
}
LaunchedEffect(destination) {
viewModel.init(destination, deviceProfile, preferences)
viewModel.init(destination, preferences)
}
val loading by viewModel.loading.observeAsState(LoadingState.Loading)

View file

@ -37,6 +37,7 @@ import com.github.damontecres.wholphin.preferences.ShowNextUpWhen
import com.github.damontecres.wholphin.preferences.SkipSegmentBehavior
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.services.DatePlayedService
import com.github.damontecres.wholphin.services.DeviceProfileService
import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.PlayerFactory
import com.github.damontecres.wholphin.services.PlaylistCreationResult
@ -84,7 +85,6 @@ import org.jellyfin.sdk.api.client.extensions.videosApi
import org.jellyfin.sdk.api.sockets.subscribe
import org.jellyfin.sdk.model.DeviceInfo
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.DeviceProfile
import org.jellyfin.sdk.model.api.MediaSegmentDto
import org.jellyfin.sdk.model.api.MediaSegmentType
import org.jellyfin.sdk.model.api.MediaStreamType
@ -120,6 +120,7 @@ class PlaybackViewModel
private val playerFactory: PlayerFactory,
private val datePlayedService: DatePlayedService,
private val deviceInfo: DeviceInfo,
private val deviceProfileService: DeviceProfileService,
) : ViewModel(),
Player.Listener,
AnalyticsListener {
@ -145,7 +146,6 @@ class PlaybackViewModel
val subtitleCues = MutableLiveData<List<Cue>>(listOf())
private lateinit var preferences: UserPreferences
private lateinit var deviceProfile: DeviceProfile
internal lateinit var itemId: UUID
internal lateinit var item: BaseItem
internal var forceTranscoding: Boolean = false
@ -180,14 +180,12 @@ class PlaybackViewModel
*/
fun init(
destination: Destination,
deviceProfile: DeviceProfile,
preferences: UserPreferences,
) {
nextUp.value = null
this.preferences = preferences
controllerViewState.hideMilliseconds =
preferences.appPreferences.playbackPreferences.controllerTimeoutMs
this.deviceProfile = deviceProfile
this.forceTranscoding =
(destination as? Destination.Playback)?.forceTranscoding ?: false
val positionMs: Long
@ -500,7 +498,10 @@ class PlaybackViewModel
startTimeTicks = null,
deviceProfile =
if (playerBackend == PlayerBackend.EXO_PLAYER) {
deviceProfile
deviceProfileService.getOrCreateDeviceProfile(
preferences.appPreferences.playbackPreferences,
serverRepository.currentServer.value?.serverVersion,
)
} else {
mpvDeviceProfile
},