Add item count to media items

This commit is contained in:
Jarne Demeulemeester 2021-06-18 14:56:32 +02:00
parent 6c220619ef
commit 930cf764ca
No known key found for this signature in database
GPG key ID: B61B7B150DB6A6D2
9 changed files with 62 additions and 41 deletions

View file

@ -28,16 +28,20 @@ fun bindViews(recyclerView: RecyclerView, data: List<View>?) {
} }
@BindingAdapter("items") @BindingAdapter("items")
fun bindItems(recyclerView: RecyclerView, data: List<ViewItem>?) { fun bindItems(recyclerView: RecyclerView, data: List<BaseItemDto>?) {
val adapter = recyclerView.adapter as ViewItemListAdapter val adapter = recyclerView.adapter as ViewItemListAdapter
adapter.submitList(data) adapter.submitList(data)
} }
@BindingAdapter("itemImage") @BindingAdapter("itemImage")
fun bindItemImage(imageView: ImageView, item: ViewItem) { fun bindItemImage(imageView: ImageView, item: BaseItemDto) {
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
val itemId = if (item.type == "Episode") item.seriesId else item.id
Glide Glide
.with(imageView.context) .with(imageView.context)
.load(item.primaryImageUrl) .load(jellyfinApi.api.baseUrl.plus("/items/${itemId}/Images/Primary"))
.transition(DrawableTransitionOptions.withCrossFade()) .transition(DrawableTransitionOptions.withCrossFade())
.placeholder(R.color.neutral_800) .placeholder(R.color.neutral_800)
.into(imageView) .into(imageView)

View file

@ -1,6 +1,7 @@
package dev.jdtech.jellyfin.adapters package dev.jdtech.jellyfin.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
@ -9,26 +10,37 @@ import dev.jdtech.jellyfin.databinding.BaseItemBinding
import dev.jdtech.jellyfin.models.ViewItem import dev.jdtech.jellyfin.models.ViewItem
import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemDto
class ViewItemListAdapter : ListAdapter<ViewItem, ViewItemListAdapter.ItemViewHolder>(DiffCallback) { class ViewItemListAdapter :
class ItemViewHolder(private var binding: BaseItemBinding) : RecyclerView.ViewHolder(binding.root) { ListAdapter<BaseItemDto, ViewItemListAdapter.ItemViewHolder>(DiffCallback) {
fun bind(view: ViewItem) { class ItemViewHolder(private var binding: BaseItemBinding) :
binding.item = view RecyclerView.ViewHolder(binding.root) {
fun bind(item: BaseItemDto) {
binding.item = item
binding.itemName.text = if (item.type == "Episode") item.seriesName else item.name
binding.itemCount.visibility =
if (item.userData?.unplayedItemCount != null) View.VISIBLE else View.GONE
binding.executePendingBindings() binding.executePendingBindings()
} }
} }
companion object DiffCallback : DiffUtil.ItemCallback<ViewItem>() { companion object DiffCallback : DiffUtil.ItemCallback<BaseItemDto>() {
override fun areItemsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean { override fun areItemsTheSame(oldItem: BaseItemDto, newItem: BaseItemDto): Boolean {
return oldItem.id == newItem.id return oldItem.id == newItem.id
} }
override fun areContentsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean { override fun areContentsTheSame(oldItem: BaseItemDto, newItem: BaseItemDto): Boolean {
return oldItem == newItem return oldItem == newItem
} }
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
return ItemViewHolder(BaseItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)) return ItemViewHolder(
BaseItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
} }
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {

View file

@ -12,6 +12,8 @@ class ViewListAdapter : ListAdapter<View, ViewListAdapter.ViewViewHolder>(DiffCa
class ViewViewHolder(private var binding: ViewItemBinding) : RecyclerView.ViewHolder(binding.root) { class ViewViewHolder(private var binding: ViewItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(view: View) { fun bind(view: View) {
binding.view = view binding.view = view
// TODO: Change to string placeholder
binding.viewName.text = "Latest ${view.name}"
binding.itemsRecyclerView.adapter = ViewItemListAdapter() binding.itemsRecyclerView.adapter = ViewItemListAdapter()
binding.executePendingBindings() binding.executePendingBindings()
} }

View file

@ -6,5 +6,5 @@ import java.util.*
data class View( data class View(
val id: UUID, val id: UUID,
val name: String?, val name: String?,
var items: List<ViewItem>? = null var items: List<BaseItemDto>? = null
) )

View file

@ -31,17 +31,10 @@ class HomeViewModel(
val views: MutableList<View> = mutableListOf() val views: MutableList<View> = mutableListOf()
val viewsResult = getViews(jellyfinApi.userId!!) val viewsResult = getViews(jellyfinApi.userId!!)
for (view in viewsResult.items!!) { for (view in viewsResult.items!!) {
val items: MutableList<ViewItem> = mutableListOf()
val latestItems = getLatestMedia(jellyfinApi.userId!!, view.id) val latestItems = getLatestMedia(jellyfinApi.userId!!, view.id)
if (latestItems.isEmpty()) continue if (latestItems.isEmpty()) continue
val v = view.toView() val v = view.toView()
for (item in latestItems) { v.items = latestItems
val i = jellyfinApi.api.baseUrl?.let { item.toViewItem(it) }
if (i != null) {
items.add(i)
}
}
v.items = items
views.add(v) views.add(v)
} }
@ -68,21 +61,6 @@ class HomeViewModel(
} }
private fun BaseItemDto.toViewItem(baseUrl: String): ViewItem {
return when (type) {
"Episode" -> ViewItem(
id = seriesId!!,
name = seriesName,
primaryImageUrl = baseUrl.plus("/items/${seriesId}/Images/Primary")
)
else -> ViewItem(
id = id,
name = name,
primaryImageUrl = baseUrl.plus("/items/${id}/Images/Primary")
)
}
}
private fun BaseItemDto.toView(): View { private fun BaseItemDto.toView(): View {
return View( return View(
id = id, id = id,

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/primary" />
</shape>

View file

@ -7,10 +7,10 @@
<variable <variable
name="item" name="item"
type="dev.jdtech.jellyfin.models.ViewItem" /> type="org.jellyfin.sdk.model.api.BaseItemDto" />
</data> </data>
<LinearLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="150dp" android:layout_width="150dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp" android:layout_marginHorizontal="12dp"
@ -20,19 +20,38 @@
android:id="@+id/item_image" android:id="@+id/item_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="220dp" android:layout_height="220dp"
android:layout_marginBottom="8dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
app:itemImage="@{item}" app:itemImage="@{item}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/roundedImageView" /> app:shapeAppearanceOverlay="@style/roundedImageView" />
<TextView <TextView
android:id="@+id/item_name" android:id="@+id/item_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:text="@{item.name}"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/item_image"
tools:text="Movie title" /> tools:text="Movie title" />
</LinearLayout>
<TextView
android:id="@+id/item_count"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/circle_background"
android:gravity="center"
android:text="@{item.userData.unplayedItemCount.toString()}"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:textColor="?attr/colorOnPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="9" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View file

@ -30,6 +30,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{collection.name}" android:text="@{collection.name}"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
android:textSize="18sp"
tools:text="Movies" /> tools:text="Movies" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View file

@ -20,8 +20,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:text="@{view.name}"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="Movies" /> tools:text="Movies" />