Add dependency injection to MediaInfoViewModel

This commit is contained in:
Jarne Demeulemeester 2021-07-06 15:21:13 +02:00
parent beb7c6f838
commit 2c8ddaad24
No known key found for this signature in database
GPG key ID: 60884A0C1EBA43E5
5 changed files with 60 additions and 75 deletions

View file

@ -15,13 +15,13 @@ import dev.jdtech.jellyfin.adapters.PersonListAdapter
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModelFactory
import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemDto
@AndroidEntryPoint @AndroidEntryPoint
class MediaInfoFragment : Fragment() { class MediaInfoFragment : Fragment() {
private lateinit var binding: FragmentMediaInfoBinding private lateinit var binding: FragmentMediaInfoBinding
private val viewModel: MediaInfoViewModel by viewModels()
private val args: MediaInfoFragmentArgs by navArgs() private val args: MediaInfoFragmentArgs by navArgs()
@ -39,10 +39,6 @@ class MediaInfoFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
val viewModelFactory =
MediaInfoViewModelFactory(requireNotNull(this.activity).application, args.itemId)
val viewModel: MediaInfoViewModel by viewModels { viewModelFactory }
binding.viewModel = viewModel binding.viewModel = viewModel
viewModel.item.observe(viewLifecycleOwner, { item -> viewModel.item.observe(viewLifecycleOwner, { item ->
@ -69,17 +65,12 @@ class MediaInfoFragment : Fragment() {
} }
binding.seasonsRecyclerView.adapter = binding.seasonsRecyclerView.adapter =
ViewItemListAdapter(ViewItemListAdapter.OnClickListener { ViewItemListAdapter(ViewItemListAdapter.OnClickListener { season ->
findNavController().navigate( navigateToSeasonFragment(season)
MediaInfoFragmentDirections.actionMediaInfoFragmentToSeasonFragment(
it.seriesId!!,
it.id,
it.seriesName,
it.name
)
)
}, fixedWidth = true) }, fixedWidth = true)
binding.peopleRecyclerView.adapter = PersonListAdapter() binding.peopleRecyclerView.adapter = PersonListAdapter()
viewModel.loadData(args.itemId)
} }
private fun navigateToEpisodeBottomSheetFragment(episode: BaseItemDto) { private fun navigateToEpisodeBottomSheetFragment(episode: BaseItemDto) {
@ -89,4 +80,15 @@ class MediaInfoFragment : Fragment() {
) )
) )
} }
private fun navigateToSeasonFragment(season: BaseItemDto) {
findNavController().navigate(
MediaInfoFragmentDirections.actionMediaInfoFragmentToSeasonFragment(
season.seriesId!!,
season.id,
season.seriesName,
season.name
)
)
}
} }

View file

@ -7,4 +7,8 @@ interface JellyfinRepository {
suspend fun getItem(itemId: UUID): BaseItemDto suspend fun getItem(itemId: UUID): BaseItemDto
suspend fun getItems(parentId: UUID): List<BaseItemDto> suspend fun getItems(parentId: UUID): List<BaseItemDto>
suspend fun getSeasons(seriesId: UUID): List<BaseItemDto>
suspend fun getNextUp(seriesId: UUID): List<BaseItemDto>
} }

View file

@ -18,8 +18,31 @@ class JellyfinRepositoryImpl(private val jellyfinApi: JellyfinApi) : JellyfinRep
override suspend fun getItems(parentId: UUID): List<BaseItemDto> { override suspend fun getItems(parentId: UUID): List<BaseItemDto> {
val items: List<BaseItemDto> val items: List<BaseItemDto>
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
items = jellyfinApi.itemsApi.getItems(jellyfinApi.userId!!, parentId = parentId).content.items ?: listOf() items = jellyfinApi.itemsApi.getItems(
jellyfinApi.userId!!,
parentId = parentId
).content.items ?: listOf()
} }
return items return items
} }
override suspend fun getSeasons(seriesId: UUID): List<BaseItemDto> {
val seasons: List<BaseItemDto>
withContext(Dispatchers.IO) {
seasons = jellyfinApi.showsApi.getSeasons(seriesId, jellyfinApi.userId!!).content.items
?: listOf()
}
return seasons
}
override suspend fun getNextUp(seriesId: UUID): List<BaseItemDto> {
val nextUpItems: List<BaseItemDto>
withContext(Dispatchers.IO) {
nextUpItems = jellyfinApi.showsApi.getNextUp(
jellyfinApi.userId!!,
seriesId = seriesId.toString()
).content.items ?: listOf()
}
return nextUpItems
}
} }

View file

@ -1,22 +1,24 @@
package dev.jdtech.jellyfin.viewmodels package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import android.os.Build import android.os.Build
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dev.jdtech.jellyfin.api.JellyfinApi import dagger.hilt.android.lifecycle.HiltViewModel
import dev.jdtech.jellyfin.repository.JellyfinRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemPerson import org.jellyfin.sdk.model.api.BaseItemPerson
import java.util.* import java.util.*
import javax.inject.Inject
class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewModel(application) { @HiltViewModel
private val jellyfinApi = JellyfinApi.getInstance(application, "") class MediaInfoViewModel
@Inject
constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() {
private val _item = MutableLiveData<BaseItemDto>() private val _item = MutableLiveData<BaseItemDto>()
val item: LiveData<BaseItemDto> = _item val item: LiveData<BaseItemDto> = _item
@ -47,9 +49,9 @@ class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewMo
private val _seasons = MutableLiveData<List<BaseItemDto>>() private val _seasons = MutableLiveData<List<BaseItemDto>>()
val seasons: LiveData<List<BaseItemDto>> = _seasons val seasons: LiveData<List<BaseItemDto>> = _seasons
init { fun loadData(itemId: UUID) {
viewModelScope.launch { viewModelScope.launch {
_item.value = getItemDetails(itemId) _item.value = jellyfinRepository.getItem(itemId)
_actors.value = getActors(_item.value!!) _actors.value = getActors(_item.value!!)
_director.value = getDirector(_item.value!!) _director.value = getDirector(_item.value!!)
_writers.value = getWriters(_item.value!!) _writers.value = getWriters(_item.value!!)
@ -58,30 +60,13 @@ class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewMo
_genresString.value = _item.value?.genres?.joinToString(separator = ", ") _genresString.value = _item.value?.genres?.joinToString(separator = ", ")
_runTime.value = "${_item.value?.runTimeTicks?.div(600000000)} min" _runTime.value = "${_item.value?.runTimeTicks?.div(600000000)} min"
_dateString.value = getDateString(_item.value!!) _dateString.value = getDateString(_item.value!!)
_item.value!!.status?.let { Log.i("MediaInfoViewModel", it) }
if (_item.value!!.type == "Series") { if (_item.value!!.type == "Series") {
_nextUp.value = getNextUp(itemId) _nextUp.value = getNextUp(itemId)
_seasons.value = getSeasons(itemId) _seasons.value = jellyfinRepository.getSeasons(itemId)
} }
} }
} }
private suspend fun getItemDetails(itemId: UUID): BaseItemDto {
val item: BaseItemDto
withContext(Dispatchers.IO) {
item = jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, itemId).content
}
return item
}
private suspend fun getSeasons(itemId: UUID): List<BaseItemDto>? {
val seasons: List<BaseItemDto>?
withContext(Dispatchers.IO) {
seasons = jellyfinApi.showsApi.getSeasons(itemId, jellyfinApi.userId!!).content.items
}
return seasons
}
private suspend fun getActors(item: BaseItemDto): List<BaseItemPerson>? { private suspend fun getActors(item: BaseItemDto): List<BaseItemPerson>? {
val actors: List<BaseItemPerson>? val actors: List<BaseItemPerson>?
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
@ -107,21 +92,12 @@ class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewMo
} }
private suspend fun getNextUp(seriesId: UUID): BaseItemDto? { private suspend fun getNextUp(seriesId: UUID): BaseItemDto? {
val nextUpItems: List<BaseItemDto>? val nextUpItems = jellyfinRepository.getNextUp(seriesId)
withContext(Dispatchers.IO) { return if (nextUpItems.isNotEmpty()) {
nextUpItems = jellyfinApi.showsApi.getNextUp( nextUpItems[0]
jellyfinApi.userId!!, } else {
seriesId = seriesId.toString() null
).content.items
} }
if (nextUpItems != null) {
return if (nextUpItems.isNotEmpty()) {
nextUpItems[0]
} else {
null
}
}
return null
} }
private fun getDateString(item: BaseItemDto): String { private fun getDateString(item: BaseItemDto): String {

View file

@ -1,20 +0,0 @@
package dev.jdtech.jellyfin.viewmodels
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.IllegalArgumentException
import java.util.*
class MediaInfoViewModelFactory(
private val application: Application,
private val itemId: UUID
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MediaInfoViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return MediaInfoViewModel(application, itemId) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}