mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Bump dependency versions (#170)
Also tries out using assisted injection for item IDs No user facing changes
This commit is contained in:
parent
bdc475e7b6
commit
18556b5058
3 changed files with 106 additions and 70 deletions
|
|
@ -39,6 +39,7 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
import androidx.lifecycle.compose.LifecycleResumeEffect
|
||||||
import androidx.lifecycle.compose.LifecycleStartEffect
|
import androidx.lifecycle.compose.LifecycleStartEffect
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
|
|
@ -89,12 +90,16 @@ fun MovieDetails(
|
||||||
preferences: UserPreferences,
|
preferences: UserPreferences,
|
||||||
destination: Destination.MediaItem,
|
destination: Destination.MediaItem,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
viewModel: MovieViewModel = hiltViewModel(),
|
viewModel: MovieViewModel =
|
||||||
|
hiltViewModel<MovieViewModel, MovieViewModel.Factory>(
|
||||||
|
creationCallback = { it.create(destination.itemId) },
|
||||||
|
),
|
||||||
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
playlistViewModel: AddPlaylistViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
LaunchedEffect(Unit) {
|
LifecycleResumeEffect(Unit) {
|
||||||
viewModel.init(destination.itemId)
|
viewModel.init()
|
||||||
|
onPauseOrDispose { }
|
||||||
}
|
}
|
||||||
val item by viewModel.item.observeAsState()
|
val item by viewModel.item.observeAsState()
|
||||||
val people by viewModel.people.observeAsState(listOf())
|
val people by viewModel.people.observeAsState(listOf())
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.github.damontecres.wholphin.ui.detail.movie
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.ChosenStreams
|
import com.github.damontecres.wholphin.data.ChosenStreams
|
||||||
|
|
@ -16,7 +17,6 @@ import com.github.damontecres.wholphin.data.model.RemoteTrailer
|
||||||
import com.github.damontecres.wholphin.data.model.Trailer
|
import com.github.damontecres.wholphin.data.model.Trailer
|
||||||
import com.github.damontecres.wholphin.preferences.ThemeSongVolume
|
import com.github.damontecres.wholphin.preferences.ThemeSongVolume
|
||||||
import com.github.damontecres.wholphin.ui.SlimItemFields
|
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||||
import com.github.damontecres.wholphin.ui.detail.LoadingItemViewModel
|
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.letNotEmpty
|
import com.github.damontecres.wholphin.ui.letNotEmpty
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
|
@ -26,10 +26,15 @@ import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import com.github.damontecres.wholphin.util.LoadingExceptionHandler
|
import com.github.damontecres.wholphin.util.LoadingExceptionHandler
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import com.github.damontecres.wholphin.util.ThemeSongPlayer
|
import com.github.damontecres.wholphin.util.ThemeSongPlayer
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.Deferred
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
|
|
@ -39,26 +44,53 @@ import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
||||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||||
import org.jellyfin.sdk.model.api.request.GetSimilarItemsRequest
|
import org.jellyfin.sdk.model.api.request.GetSimilarItemsRequest
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel(assistedFactory = MovieViewModel.Factory::class)
|
||||||
class MovieViewModel
|
class MovieViewModel
|
||||||
@Inject
|
@AssistedInject
|
||||||
constructor(
|
constructor(
|
||||||
api: ApiClient,
|
private val api: ApiClient,
|
||||||
@param:ApplicationContext private val context: Context,
|
@param:ApplicationContext private val context: Context,
|
||||||
private val navigationManager: NavigationManager,
|
private val navigationManager: NavigationManager,
|
||||||
val serverRepository: ServerRepository,
|
val serverRepository: ServerRepository,
|
||||||
val itemPlaybackRepository: ItemPlaybackRepository,
|
val itemPlaybackRepository: ItemPlaybackRepository,
|
||||||
private val themeSongPlayer: ThemeSongPlayer,
|
private val themeSongPlayer: ThemeSongPlayer,
|
||||||
) : LoadingItemViewModel(api) {
|
@Assisted val itemId: UUID,
|
||||||
|
) : ViewModel() {
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory {
|
||||||
|
fun create(itemId2: UUID): MovieViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
val loading = MutableLiveData<LoadingState>(LoadingState.Pending)
|
||||||
|
val item = MutableLiveData<BaseItem?>(null)
|
||||||
val trailers = MutableLiveData<List<Trailer>>(listOf())
|
val trailers = MutableLiveData<List<Trailer>>(listOf())
|
||||||
val people = MutableLiveData<List<Person>>(listOf())
|
val people = MutableLiveData<List<Person>>(listOf())
|
||||||
val chapters = MutableLiveData<List<Chapter>>(listOf())
|
val chapters = MutableLiveData<List<Chapter>>(listOf())
|
||||||
val similar = MutableLiveData<List<BaseItem>>()
|
val similar = MutableLiveData<List<BaseItem>>()
|
||||||
val chosenStreams = MutableLiveData<ChosenStreams?>(null)
|
val chosenStreams = MutableLiveData<ChosenStreams?>(null)
|
||||||
|
|
||||||
fun init(itemId: UUID): Job? =
|
init {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchAndSetItem(): Deferred<BaseItem> =
|
||||||
|
viewModelScope.async(
|
||||||
|
Dispatchers.IO +
|
||||||
|
LoadingExceptionHandler(
|
||||||
|
loading,
|
||||||
|
"Error fetching movie",
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
val item =
|
||||||
|
api.userLibraryApi.getItem(itemId).content.let {
|
||||||
|
BaseItem.from(it, api)
|
||||||
|
}
|
||||||
|
this@MovieViewModel.item.setValueOnMain(item)
|
||||||
|
item
|
||||||
|
}
|
||||||
|
|
||||||
|
fun init(): Job =
|
||||||
viewModelScope.launch(
|
viewModelScope.launch(
|
||||||
Dispatchers.IO +
|
Dispatchers.IO +
|
||||||
LoadingExceptionHandler(
|
LoadingExceptionHandler(
|
||||||
|
|
@ -66,10 +98,10 @@ class MovieViewModel
|
||||||
"Error fetching movie",
|
"Error fetching movie",
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
fetchAndSetItem(itemId)
|
val item = fetchAndSetItem().await()
|
||||||
item.value?.let { item ->
|
|
||||||
val result = itemPlaybackRepository.getSelectedTracks(item.id, item)
|
val result = itemPlaybackRepository.getSelectedTracks(item.id, item)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
this@MovieViewModel.item.value = item
|
||||||
chosenStreams.value = result
|
chosenStreams.value = result
|
||||||
loading.value = LoadingState.Success
|
loading.value = LoadingState.Success
|
||||||
}
|
}
|
||||||
|
|
@ -124,26 +156,25 @@ class MovieViewModel
|
||||||
this@MovieViewModel.similar.setValueOnMain(similar)
|
this@MovieViewModel.similar.setValueOnMain(similar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun setWatched(played: Boolean) =
|
fun setWatched(played: Boolean) =
|
||||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||||
if (played) {
|
if (played) {
|
||||||
api.playStateApi.markPlayedItem(itemUuid)
|
api.playStateApi.markPlayedItem(itemId)
|
||||||
} else {
|
} else {
|
||||||
api.playStateApi.markUnplayedItem(itemUuid)
|
api.playStateApi.markUnplayedItem(itemId)
|
||||||
}
|
}
|
||||||
fetchAndSetItem(itemUuid)
|
fetchAndSetItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setFavorite(favorite: Boolean) =
|
fun setFavorite(favorite: Boolean) =
|
||||||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||||
if (favorite) {
|
if (favorite) {
|
||||||
api.userLibraryApi.markFavoriteItem(itemUuid)
|
api.userLibraryApi.markFavoriteItem(itemId)
|
||||||
} else {
|
} else {
|
||||||
api.userLibraryApi.unmarkFavoriteItem(itemUuid)
|
api.userLibraryApi.unmarkFavoriteItem(itemId)
|
||||||
}
|
}
|
||||||
fetchAndSetItem(itemUuid)
|
fetchAndSetItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun savePlayVersion(
|
fun savePlayVersion(
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ kotlin = "2.2.21"
|
||||||
ksp = "2.3.0"
|
ksp = "2.3.0"
|
||||||
coreKtx = "1.17.0"
|
coreKtx = "1.17.0"
|
||||||
appcompat = "1.7.1"
|
appcompat = "1.7.1"
|
||||||
composeBom = "2025.10.01"
|
composeBom = "2025.11.00"
|
||||||
compose-runtime = "1.9.4"
|
compose-runtime = "1.9.4"
|
||||||
multiplatformMarkdownRenderer = "0.37.0"
|
multiplatformMarkdownRenderer = "0.38.1"
|
||||||
programguide = "1.6.0"
|
programguide = "1.6.0"
|
||||||
slf4j2Timber = "1.2"
|
slf4j2Timber = "1.2"
|
||||||
timber = "5.0.1"
|
timber = "5.0.1"
|
||||||
|
|
@ -23,8 +23,8 @@ activityCompose = "1.11.0"
|
||||||
androidx-media3 = "1.8.0"
|
androidx-media3 = "1.8.0"
|
||||||
coil = "3.3.0"
|
coil = "3.3.0"
|
||||||
jellyfin-sdk = "1.7.1"
|
jellyfin-sdk = "1.7.1"
|
||||||
nav3Core = "1.0.0-beta01"
|
nav3Core = "1.0.0-rc01"
|
||||||
lifecycleViewmodelNav3 = "2.10.0-beta01"
|
lifecycleViewmodelNav3 = "2.10.0-rc01"
|
||||||
material3AdaptiveNav3 = "1.0.0-alpha03"
|
material3AdaptiveNav3 = "1.0.0-alpha03"
|
||||||
protobuf = "0.9.5"
|
protobuf = "0.9.5"
|
||||||
datastore = "1.1.7"
|
datastore = "1.1.7"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue