diff --git a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt index 5c2f9b4a..bbf65bee 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/fragments/MediaInfoFragment.kt @@ -35,6 +35,14 @@ class MediaInfoFragment : Fragment() { val viewModelFactory = MediaInfoViewModelFactory(requireNotNull(this.activity).application, args.itemId) viewModel = ViewModelProvider(this, viewModelFactory).get(MediaInfoViewModel::class.java) binding.viewModel = viewModel + + viewModel.item.observe(viewLifecycleOwner, { + if (it.originalTitle != it.name) { + binding.originalTitle.visibility = View.VISIBLE + } else { + binding.originalTitle.visibility = View.GONE + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt index 9f20e561..dd23c074 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/viewmodels/MediaInfoViewModel.kt @@ -1,6 +1,8 @@ package dev.jdtech.jellyfin.viewmodels import android.app.Application +import android.os.Build +import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData @@ -10,6 +12,8 @@ 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.PersonLookupInfo import java.util.* class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewModel(application) { @@ -18,17 +22,90 @@ class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewMo 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 + init { viewModelScope.launch { _item.value = getItemDetails(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!!) + _item.value!!.status?.let { Log.i("MediaInfoViewModel", it) } } } - private suspend fun getItemDetails(itemId: UUID) : BaseItemDto { + 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 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 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 + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media_info.xml b/app/src/main/res/layout/fragment_media_info.xml index 239e5b36..2db80f3b 100644 --- a/app/src/main/res/layout/fragment_media_info.xml +++ b/app/src/main/res/layout/fragment_media_info.xml @@ -5,6 +5,8 @@ + + @@ -18,6 +20,7 @@ tools:context=".fragments.MediaInfoFragment"> @@ -44,7 +47,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" - android:text="@{viewModel.item.runTimeTicks.toString()}" + android:text="@{viewModel.runTime}" android:textAppearance="@style/TextAppearance.AppCompat.Body1" tools:text="122 min" /> @@ -70,14 +73,15 @@ android:id="@+id/info" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="24dp" + android:layout_marginBottom="12dp" android:orientation="vertical"> + android:layout_marginBottom="12dp" + android:visibility="@{viewModel.item.genres.size() < 1 ? View.GONE : View.VISIBLE}"> + android:layout_marginBottom="12dp" + android:visibility="@{viewModel.director == null ? View.GONE : View.VISIBLE}"> + android:layout_height="wrap_content" + android:layout_marginBottom="12dp" + android:visibility="@{viewModel.writers.size() < 1 ? View.GONE : View.VISIBLE}"> @@ -147,6 +155,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="64dp" + android:text="@{viewModel.writersString}" android:textAppearance="@style/TextAppearance.AppCompat.Body1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"