Implement more dynamic data to MediaInfoFragment

This commit is contained in:
Jarne Demeulemeester 2021-06-23 13:55:12 +02:00
parent e254709f91
commit c95ea3b586
No known key found for this signature in database
GPG key ID: 60884A0C1EBA43E5
3 changed files with 102 additions and 8 deletions

View file

@ -35,6 +35,14 @@ class MediaInfoFragment : Fragment() {
val viewModelFactory = MediaInfoViewModelFactory(requireNotNull(this.activity).application, args.itemId) val viewModelFactory = MediaInfoViewModelFactory(requireNotNull(this.activity).application, args.itemId)
viewModel = ViewModelProvider(this, viewModelFactory).get(MediaInfoViewModel::class.java) viewModel = ViewModelProvider(this, viewModelFactory).get(MediaInfoViewModel::class.java)
binding.viewModel = viewModel binding.viewModel = viewModel
viewModel.item.observe(viewLifecycleOwner, {
if (it.originalTitle != it.name) {
binding.originalTitle.visibility = View.VISIBLE
} else {
binding.originalTitle.visibility = View.GONE
}
})
} }
} }

View file

@ -1,6 +1,8 @@
package dev.jdtech.jellyfin.viewmodels package dev.jdtech.jellyfin.viewmodels
import android.app.Application import android.app.Application
import android.os.Build
import android.util.Log
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
@ -10,6 +12,8 @@ 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.PersonLookupInfo
import java.util.* import java.util.*
class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewModel(application) { class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewModel(application) {
@ -18,17 +22,90 @@ class MediaInfoViewModel(application: Application, itemId: UUID) : AndroidViewMo
private val _item = MutableLiveData<BaseItemDto>() private val _item = MutableLiveData<BaseItemDto>()
val item: LiveData<BaseItemDto> = _item val item: LiveData<BaseItemDto> = _item
private val _actors = MutableLiveData<List<BaseItemPerson>>()
val actors: LiveData<List<BaseItemPerson>> = _actors
private val _director = MutableLiveData<BaseItemPerson>()
val director: LiveData<BaseItemPerson> = _director
private val _writers = MutableLiveData<List<BaseItemPerson>>()
val writers: LiveData<List<BaseItemPerson>> = _writers
private val _writersString = MutableLiveData<String>()
val writersString: LiveData<String> = _writersString
private val _genresString = MutableLiveData<String>()
val genresString: LiveData<String> = _genresString
private val _runTime = MutableLiveData<String>()
val runTime: LiveData<String> = _runTime
private val _dateString = MutableLiveData<String>()
val dateString: LiveData<String> = _dateString
init { init {
viewModelScope.launch { viewModelScope.launch {
_item.value = getItemDetails(itemId) _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 val item: BaseItemDto
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
item = jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, itemId).content item = jellyfinApi.userLibraryApi.getItem(jellyfinApi.userId!!, itemId).content
} }
return item return item
} }
private suspend fun getActors(item: BaseItemDto): List<BaseItemPerson>? {
val actors: List<BaseItemPerson>?
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<BaseItemPerson>? {
val writers: List<BaseItemPerson>?
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
}
}
} }

View file

@ -5,6 +5,8 @@
<data> <data>
<import type="android.view.View" />
<variable <variable
name="viewModel" name="viewModel"
type="dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel" /> type="dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel" />
@ -18,6 +20,7 @@
tools:context=".fragments.MediaInfoFragment"> tools:context=".fragments.MediaInfoFragment">
<TextView <TextView
android:id="@+id/original_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
@ -35,7 +38,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:text="@{viewModel.item.productionYear.toString()}" android:text="@{viewModel.dateString}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="2019" /> tools:text="2019" />
@ -44,7 +47,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:text="@{viewModel.item.runTimeTicks.toString()}" android:text="@{viewModel.runTime}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
tools:text="122 min" /> tools:text="122 min" />
@ -70,14 +73,15 @@
android:id="@+id/info" android:id="@+id/info"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="24dp" android:layout_marginBottom="12dp"
android:orientation="vertical"> android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/genres_layout" android:id="@+id/genres_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp"> android:layout_marginBottom="12dp"
android:visibility="@{viewModel.item.genres.size() &lt; 1 ? View.GONE : View.VISIBLE}">
<TextView <TextView
android:id="@+id/genres_title" android:id="@+id/genres_title"
@ -93,6 +97,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
android:text="@{viewModel.genresString}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -104,7 +109,8 @@
android:id="@+id/director_layout" android:id="@+id/director_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp"> android:layout_marginBottom="12dp"
android:visibility="@{viewModel.director == null ? View.GONE : View.VISIBLE}">
<TextView <TextView
android:id="@+id/director_title" android:id="@+id/director_title"
@ -120,6 +126,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
android:text="@{viewModel.director.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -130,7 +137,9 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/writers_layout" android:id="@+id/writers_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:visibility="@{viewModel.writers.size() &lt; 1 ? View.GONE : View.VISIBLE}">
<TextView <TextView
android:id="@+id/writers_title" android:id="@+id/writers_title"
@ -138,7 +147,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/writers" android:text="@string/writers"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -147,6 +155,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
android:text="@{viewModel.writersString}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"