package dev.jdtech.jellyfin.viewmodels import android.os.Build import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dev.jdtech.jellyfin.repository.JellyfinRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemPerson import org.jellyfin.sdk.model.api.MediaSourceInfo import java.util.* import javax.inject.Inject @HiltViewModel class MediaInfoViewModel @Inject constructor(private val jellyfinRepository: JellyfinRepository) : ViewModel() { private val _item = MutableLiveData() val item: LiveData = _item private val _actors = MutableLiveData>() val actors: LiveData> = _actors private val _director = MutableLiveData() val director: LiveData = _director private val _writers = MutableLiveData>() val writers: LiveData> = _writers private val _writersString = MutableLiveData() val writersString: LiveData = _writersString private val _genresString = MutableLiveData() val genresString: LiveData = _genresString private val _runTime = MutableLiveData() val runTime: LiveData = _runTime private val _dateString = MutableLiveData() val dateString: LiveData = _dateString private val _nextUp = MutableLiveData() val nextUp: LiveData = _nextUp private val _seasons = MutableLiveData>() val seasons: LiveData> = _seasons private val _mediaSources = MutableLiveData>() val mediaSources: LiveData> = _mediaSources private val _navigateToPlayer = MutableLiveData() val navigateToPlayer: LiveData = _navigateToPlayer private val _played = MutableLiveData() val played: LiveData = _played private val _favorite = MutableLiveData() val favorite: LiveData = _favorite fun loadData(itemId: UUID, itemType: String) { viewModelScope.launch { _item.value = jellyfinRepository.getItem(itemId) _actors.value = getActors(_item.value!!) _director.value = getDirector(_item.value!!) _writers.value = getWriters(_item.value!!) _writersString.value = _writers.value?.joinToString(separator = ", ") { it.name.toString() } _genresString.value = _item.value?.genres?.joinToString(separator = ", ") _runTime.value = "${_item.value?.runTimeTicks?.div(600000000)} min" _dateString.value = getDateString(_item.value!!) _played.value = _item.value?.userData?.played _favorite.value = _item.value?.userData?.isFavorite if (itemType == "Series") { _nextUp.value = getNextUp(itemId) _seasons.value = jellyfinRepository.getSeasons(itemId) } if (itemType == "Movie") { _mediaSources.value = jellyfinRepository.getMediaSources(itemId) } } } private suspend fun getActors(item: BaseItemDto): List? { val actors: List? withContext(Dispatchers.Default) { actors = item.people?.filter { it.type == "Actor" } } return actors } private suspend fun getDirector(item: BaseItemDto): BaseItemPerson? { val director: BaseItemPerson? withContext(Dispatchers.Default) { director = item.people?.firstOrNull { it.type == "Director" } } return director } private suspend fun getWriters(item: BaseItemDto): List? { val writers: List? withContext(Dispatchers.Default) { writers = item.people?.filter { it.type == "Writer" } } return writers } private suspend fun getNextUp(seriesId: UUID): BaseItemDto? { val nextUpItems = jellyfinRepository.getNextUp(seriesId) return if (nextUpItems.isNotEmpty()) { nextUpItems[0] } else { null } } fun markAsPlayed(itemId: UUID) { viewModelScope.launch { jellyfinRepository.markAsPlayed(itemId) } _played.value = true } fun markAsUnplayed(itemId: UUID) { viewModelScope.launch { jellyfinRepository.markAsUnplayed(itemId) } _played.value = false } fun markAsFavorite(itemId: UUID) { viewModelScope.launch { jellyfinRepository.markAsFavorite(itemId) } _favorite.value = true } fun unmarkAsFavorite(itemId: UUID) { viewModelScope.launch { jellyfinRepository.unmarkAsFavorite(itemId) } _favorite.value = false } private fun getDateString(item: BaseItemDto): String { val dateString: String = item.productionYear.toString() return when (item.status) { "Continuing" -> dateString.plus(" - Present") "Ended" -> { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return if (item.productionYear == item.endDate?.year) { dateString } else { dateString.plus(" - ${item.endDate?.year}") } } else { // TODO: Implement a way to get the year from LocalDateTime in Android < O dateString } } else -> dateString } } fun navigateToPlayer(mediaSource: MediaSourceInfo) { _navigateToPlayer.value = mediaSource } }