Improve EpisodeBottomSheet
This commit is contained in:
parent
a3cfe35c13
commit
7c3640fa5f
11 changed files with 112 additions and 46 deletions
|
@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import dev.jdtech.jellyfin.databinding.EpisodeItemBinding
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
|
||||
class EpisodeListAdapter :
|
||||
class EpisodeListAdapter(private val onClickListener: OnClickListener) :
|
||||
ListAdapter<BaseItemDto, EpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
|
||||
|
||||
class EpisodeViewHolder(private var binding: EpisodeItemBinding) :
|
||||
|
@ -41,6 +41,13 @@ class EpisodeListAdapter :
|
|||
|
||||
override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) {
|
||||
val item = getItem(position)
|
||||
holder.itemView.setOnClickListener {
|
||||
onClickListener.onClick(item)
|
||||
}
|
||||
holder.bind(item)
|
||||
}
|
||||
|
||||
class OnClickListener(val clickListener: (item: BaseItemDto) -> Unit) {
|
||||
fun onClick(item: BaseItemDto) = clickListener(item)
|
||||
}
|
||||
}
|
|
@ -40,11 +40,24 @@ class HomeFragment : Fragment() {
|
|||
)
|
||||
)
|
||||
}, HomeEpisodeListAdapter.OnClickListener {
|
||||
findNavController().navigate(
|
||||
HomeFragmentDirections.actionNavigationHomeToEpisodeBottomSheetFragment(
|
||||
it.id
|
||||
)
|
||||
)
|
||||
when (it.type) {
|
||||
"Episode" -> {
|
||||
findNavController().navigate(
|
||||
HomeFragmentDirections.actionNavigationHomeToEpisodeBottomSheetFragment(
|
||||
it.id
|
||||
)
|
||||
)
|
||||
}
|
||||
"Movie" -> {
|
||||
findNavController().navigate(
|
||||
HomeFragmentDirections.actionNavigationHomeToMediaInfoFragment(
|
||||
it.id,
|
||||
it.name
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
binding.errorLayout.findViewById<View>(R.id.retry_button).setOnClickListener {
|
||||
|
|
|
@ -58,6 +58,10 @@ class MediaInfoFragment : Fragment() {
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.nextUp.setOnClickListener {
|
||||
findNavController().navigate(MediaInfoFragmentDirections.actionMediaInfoFragmentToEpisodeBottomSheetFragment(viewModel.nextUp.value!!.id))
|
||||
}
|
||||
|
||||
binding.seasonsRecyclerView.adapter =
|
||||
ViewItemListAdapter(ViewItemListAdapter.OnClickListener {
|
||||
findNavController().navigate(
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.fragment.app.Fragment
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import dev.jdtech.jellyfin.adapters.EpisodeListAdapter
|
||||
import dev.jdtech.jellyfin.databinding.FragmentSeasonBinding
|
||||
|
@ -37,7 +38,14 @@ class SeasonFragment : Fragment() {
|
|||
)
|
||||
viewModel = ViewModelProvider(this, viewModelFactory).get(SeasonViewModel::class.java)
|
||||
binding.viewModel = viewModel
|
||||
binding.episodesRecyclerView.adapter = EpisodeListAdapter()
|
||||
binding.episodesRecyclerView.adapter =
|
||||
EpisodeListAdapter(EpisodeListAdapter.OnClickListener {
|
||||
findNavController().navigate(
|
||||
SeasonFragmentDirections.actionSeasonFragmentToEpisodeBottomSheetFragment(
|
||||
it.id
|
||||
)
|
||||
)
|
||||
})
|
||||
binding.seriesName.text = args.seriesName
|
||||
binding.seasonName.text = args.seasonName
|
||||
binding.seriesId = args.seriesId
|
||||
|
|
|
@ -11,6 +11,8 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
import java.text.DateFormat
|
||||
import java.time.ZoneOffset
|
||||
import java.util.*
|
||||
|
||||
class EpisodeBottomSheetViewModel(application: Application, episodeId: UUID) : AndroidViewModel(application) {
|
||||
|
@ -42,23 +44,13 @@ class EpisodeBottomSheetViewModel(application: Application, episodeId: UUID) : A
|
|||
}
|
||||
|
||||
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
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val instant = item.premiereDate?.toInstant(ZoneOffset.UTC)
|
||||
val date = Date.from(instant)
|
||||
DateFormat.getDateInstance(DateFormat.SHORT).format(date)
|
||||
} else {
|
||||
// TODO: Implement a way to get the year from LocalDateTime in Android < O
|
||||
item.premiereDate.toString()
|
||||
}
|
||||
}
|
||||
}
|
13
app/src/main/res/drawable/ic_star.xml
Normal file
13
app/src/main/res/drawable/ic_star.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,2l3.09,6.26l6.91,1.01l-5,4.87l1.18,6.88l-6.18,-3.25l-6.18,3.25l1.18,-6.88l-5,-4.87l6.91,-1.01l3.09,-6.26z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="@android:color/white"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
|
@ -13,7 +13,8 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="24dp">
|
||||
android:paddingBottom="24dp"
|
||||
android:background="?android:attr/colorBackgroundFloating">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/episode_image"
|
||||
|
@ -22,10 +23,10 @@
|
|||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:itemPrimaryImage="@{viewModel.item}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:shapeAppearance="@style/roundedImageView"
|
||||
app:itemPrimaryImage="@{viewModel.item}"/>
|
||||
app:shapeAppearance="@style/roundedImageView" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/episode_name"
|
||||
|
@ -33,8 +34,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:text="@{String.format(@string/episode_name_extended, viewModel.item.parentIndexNumber, viewModel.item.indexNumber, viewModel.item.name)}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:text="@{viewModel.item.name}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/episode_image"
|
||||
app:layout_constraintTop_toTopOf="@id/episode_image"
|
||||
|
@ -45,6 +46,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:gravity="bottom"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/episode_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/episode_name">
|
||||
|
@ -55,8 +57,8 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:text="@{viewModel.dateString}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="4/6/2013" />
|
||||
|
||||
<TextView
|
||||
|
@ -64,16 +66,23 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:text="@{viewModel.runTime}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="26 min" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_star"
|
||||
app:tint="#F2C94C" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/community_rating"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:text="@{viewModel.item.communityRating.toString()}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="8.8" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -124,8 +133,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:text="@{viewModel.item.overview}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/buttons"
|
||||
|
|
|
@ -73,7 +73,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="bottom">
|
||||
|
||||
|
||||
<TextView
|
||||
|
@ -103,6 +104,13 @@
|
|||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="PG-13" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_star"
|
||||
app:tint="#F2C94C" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/community_rating"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -279,8 +287,8 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="@{viewModel.nextUp != null ? View.VISIBLE : View.GONE}">
|
||||
|
||||
<TextView
|
||||
|
@ -292,22 +300,29 @@
|
|||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
<LinearLayout
|
||||
android:id="@+id/next_up"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:itemPrimaryImage="@{viewModel.nextUp}"
|
||||
app:shapeAppearance="@style/roundedImageView" />
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:text="@{String.format(@string/episode_name_extended, viewModel.nextUp.parentIndexNumber, viewModel.nextUp.indexNumber, viewModel.nextUp.name)}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="The Girl Flautist" />
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:adjustViewBounds="true"
|
||||
app:itemPrimaryImage="@{viewModel.nextUp}"
|
||||
app:shapeAppearance="@style/roundedImageView" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{String.format(@string/episode_name_extended, viewModel.nextUp.parentIndexNumber, viewModel.nextUp.indexNumber, viewModel.nextUp.name)}"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
tools:text="The Girl Flautist" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
<action
|
||||
android:id="@+id/action_mediaInfoFragment_to_seasonFragment"
|
||||
app:destination="@id/seasonFragment" />
|
||||
<action
|
||||
android:id="@+id/action_mediaInfoFragment_to_episodeBottomSheetFragment"
|
||||
app:destination="@id/episodeBottomSheetFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/seasonFragment"
|
||||
|
|
|
@ -13,5 +13,6 @@
|
|||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowBackground">@color/neutral_900</item>
|
||||
<item name="android:colorBackgroundFloating">@color/neutral_900</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -13,5 +13,6 @@
|
|||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowBackground">@color/neutral_100</item>
|
||||
<item name="android:colorBackgroundFloating">@color/neutral_100</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in a new issue