Add Next Up items to HomeFragment
Can use some cleanup :)
This commit is contained in:
parent
5ff4ec7e42
commit
7605eb4158
9 changed files with 268 additions and 37 deletions
|
@ -8,8 +8,6 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
import dev.jdtech.jellyfin.adapters.*
|
import dev.jdtech.jellyfin.adapters.*
|
||||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||||
import dev.jdtech.jellyfin.database.Server
|
import dev.jdtech.jellyfin.database.Server
|
||||||
import dev.jdtech.jellyfin.models.View
|
|
||||||
import dev.jdtech.jellyfin.models.ViewItem
|
|
||||||
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.BaseItemPerson
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -21,7 +19,7 @@ fun bindServers(recyclerView: RecyclerView, data: List<Server>?) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("views")
|
@BindingAdapter("views")
|
||||||
fun bindViews(recyclerView: RecyclerView, data: List<View>?) {
|
fun bindViews(recyclerView: RecyclerView, data: List<HomeItem>?) {
|
||||||
val adapter = recyclerView.adapter as ViewListAdapter
|
val adapter = recyclerView.adapter as ViewListAdapter
|
||||||
adapter.submitList(data)
|
adapter.submitList(data)
|
||||||
}
|
}
|
||||||
|
@ -65,15 +63,13 @@ fun bindItemBackdropImage(imageView: ImageView, item: BaseItemDto?) {
|
||||||
|
|
||||||
@BindingAdapter("itemBackdropById")
|
@BindingAdapter("itemBackdropById")
|
||||||
fun bindItemBackdropById(imageView: ImageView, itemId: UUID) {
|
fun bindItemBackdropById(imageView: ImageView, itemId: UUID) {
|
||||||
if (itemId != null) {
|
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
|
||||||
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
|
|
||||||
|
|
||||||
Glide
|
Glide
|
||||||
.with(imageView.context)
|
.with(imageView.context)
|
||||||
.load(jellyfinApi.api.baseUrl.plus("/items/${itemId}/Images/Backdrop"))
|
.load(jellyfinApi.api.baseUrl.plus("/items/${itemId}/Images/Backdrop"))
|
||||||
.transition(DrawableTransitionOptions.withCrossFade())
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
.into(imageView)
|
.into(imageView)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("collections")
|
@BindingAdapter("collections")
|
||||||
|
@ -122,6 +118,12 @@ fun bindEpisodes(recyclerView: RecyclerView, data: List<BaseItemDto>?) {
|
||||||
adapter.submitList(data)
|
adapter.submitList(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("homeEpisodes")
|
||||||
|
fun bindHomeEpisodes(recyclerView: RecyclerView, data: List<BaseItemDto>?) {
|
||||||
|
val adapter = recyclerView.adapter as HomeEpisodeListAdapter
|
||||||
|
adapter.submitList(data)
|
||||||
|
}
|
||||||
|
|
||||||
@BindingAdapter("episodeImage")
|
@BindingAdapter("episodeImage")
|
||||||
fun bindEpisodeImage(imageView: ImageView, episode: BaseItemDto) {
|
fun bindEpisodeImage(imageView: ImageView, episode: BaseItemDto) {
|
||||||
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
|
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dev.jdtech.jellyfin.databinding.HomeEpisodeItemBinding
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
|
|
||||||
|
class HomeEpisodeListAdapter : ListAdapter<BaseItemDto, HomeEpisodeListAdapter.EpisodeViewHolder>(DiffCallback) {
|
||||||
|
class EpisodeViewHolder(private var binding: HomeEpisodeItemBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(episode: BaseItemDto) {
|
||||||
|
binding.episode = episode
|
||||||
|
binding.executePendingBindings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object DiffCallback : DiffUtil.ItemCallback<BaseItemDto>() {
|
||||||
|
override fun areItemsTheSame(oldItem: BaseItemDto, newItem: BaseItemDto): Boolean {
|
||||||
|
return oldItem.id == newItem.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: BaseItemDto, newItem: BaseItemDto): Boolean {
|
||||||
|
return oldItem == newItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpisodeViewHolder {
|
||||||
|
return EpisodeViewHolder(
|
||||||
|
HomeEpisodeItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) {
|
||||||
|
val item = getItem(position)
|
||||||
|
holder.bind(item)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,19 +5,34 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dev.jdtech.jellyfin.databinding.NextUpSectionBinding
|
||||||
import dev.jdtech.jellyfin.databinding.ViewItemBinding
|
import dev.jdtech.jellyfin.databinding.ViewItemBinding
|
||||||
|
import dev.jdtech.jellyfin.models.NextUp
|
||||||
import dev.jdtech.jellyfin.models.View
|
import dev.jdtech.jellyfin.models.View
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
|
import java.lang.ClassCastException
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
private const val ITEM_VIEW_TYPE_NEXT_UP = 0
|
||||||
|
private const val ITEM_VIEW_TYPE_VIEW = 1
|
||||||
|
|
||||||
class ViewListAdapter(
|
class ViewListAdapter(
|
||||||
private val onClickListener: OnClickListener,
|
private val onClickListener: OnClickListener,
|
||||||
private val onItemClickListener: ViewItemListAdapter.OnClickListener
|
private val onItemClickListener: ViewItemListAdapter.OnClickListener
|
||||||
) : ListAdapter<View, ViewListAdapter.ViewViewHolder>(DiffCallback) {
|
) : ListAdapter<HomeItem, RecyclerView.ViewHolder>(DiffCallback) {
|
||||||
class ViewViewHolder(private var binding: ViewItemBinding) : RecyclerView.ViewHolder(binding.root) {
|
class ViewViewHolder(private var binding: ViewItemBinding) :
|
||||||
fun bind(view: View, onClickListener: OnClickListener, onItemClickListener: ViewItemListAdapter.OnClickListener) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(
|
||||||
|
dataItem: HomeItem.ViewItem,
|
||||||
|
onClickListener: OnClickListener,
|
||||||
|
onItemClickListener: ViewItemListAdapter.OnClickListener
|
||||||
|
) {
|
||||||
|
val view = dataItem.view
|
||||||
binding.view = view
|
binding.view = view
|
||||||
// TODO: Change to string placeholder
|
// TODO: Change to string placeholder
|
||||||
binding.viewName.text = "Latest ${view.name}"
|
binding.viewName.text = "Latest ${view.name}"
|
||||||
binding.itemsRecyclerView.adapter = ViewItemListAdapter(onItemClickListener, fixedWidth = true)
|
binding.itemsRecyclerView.adapter =
|
||||||
|
ViewItemListAdapter(onItemClickListener, fixedWidth = true)
|
||||||
binding.viewAll.setOnClickListener {
|
binding.viewAll.setOnClickListener {
|
||||||
onClickListener.onClick(view)
|
onClickListener.onClick(view)
|
||||||
}
|
}
|
||||||
|
@ -25,26 +40,78 @@ class ViewListAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object DiffCallback : DiffUtil.ItemCallback<View>() {
|
class NextUpViewHolder(private var binding: NextUpSectionBinding) :
|
||||||
override fun areItemsTheSame(oldItem: View, newItem: View): Boolean {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(section: HomeItem.NextUpSection) {
|
||||||
|
binding.section = section.nextUp
|
||||||
|
binding.itemsRecyclerView.adapter = HomeEpisodeListAdapter()
|
||||||
|
binding.executePendingBindings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object DiffCallback : DiffUtil.ItemCallback<HomeItem>() {
|
||||||
|
override fun areItemsTheSame(oldItem: HomeItem, newItem: HomeItem): Boolean {
|
||||||
return oldItem.id == newItem.id
|
return oldItem.id == newItem.id
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: View, newItem: View): Boolean {
|
override fun areContentsTheSame(oldItem: HomeItem, newItem: HomeItem): Boolean {
|
||||||
return oldItem == newItem
|
return oldItem == newItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return ViewViewHolder(ViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
|
return when (viewType) {
|
||||||
|
ITEM_VIEW_TYPE_NEXT_UP -> NextUpViewHolder(
|
||||||
|
NextUpSectionBinding.inflate(
|
||||||
|
LayoutInflater.from(
|
||||||
|
parent.context
|
||||||
|
), parent, false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ITEM_VIEW_TYPE_VIEW -> ViewViewHolder(
|
||||||
|
ViewItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else -> throw ClassCastException("Unknown viewType $viewType")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
val view = getItem(position)
|
when (holder.itemViewType) {
|
||||||
holder.bind(view, onClickListener, onItemClickListener)
|
ITEM_VIEW_TYPE_NEXT_UP -> {
|
||||||
|
val view = getItem(position) as HomeItem.NextUpSection
|
||||||
|
(holder as NextUpViewHolder).bind(view)
|
||||||
|
}
|
||||||
|
ITEM_VIEW_TYPE_VIEW -> {
|
||||||
|
val view = getItem(position) as HomeItem.ViewItem
|
||||||
|
(holder as ViewViewHolder).bind(view, onClickListener, onItemClickListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return when (getItem(position)) {
|
||||||
|
is HomeItem.NextUpSection -> ITEM_VIEW_TYPE_NEXT_UP
|
||||||
|
is HomeItem.ViewItem -> ITEM_VIEW_TYPE_VIEW
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OnClickListener(val clickListener: (view: View) -> Unit) {
|
class OnClickListener(val clickListener: (view: View) -> Unit) {
|
||||||
fun onClick(view: View) = clickListener(view)
|
fun onClick(view: View) = clickListener(view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class HomeItem {
|
||||||
|
data class NextUpSection(val nextUp: NextUp) : HomeItem() {
|
||||||
|
override val id = nextUp.id
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ViewItem(val view: View) : HomeItem() {
|
||||||
|
override val id = view.id
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract val id: UUID
|
||||||
|
}
|
10
app/src/main/java/dev/jdtech/jellyfin/models/NextUp.kt
Normal file
10
app/src/main/java/dev/jdtech/jellyfin/models/NextUp.kt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.jdtech.jellyfin.models
|
||||||
|
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
data class NextUp(
|
||||||
|
val id: UUID,
|
||||||
|
val name: String?,
|
||||||
|
var items: List<BaseItemDto>? = null
|
||||||
|
)
|
|
@ -1,9 +0,0 @@
|
||||||
package dev.jdtech.jellyfin.models
|
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
data class ViewItem(
|
|
||||||
val id: UUID,
|
|
||||||
val name: String?,
|
|
||||||
val primaryImageUrl: String
|
|
||||||
)
|
|
|
@ -2,7 +2,10 @@ package dev.jdtech.jellyfin.viewmodels
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.*
|
||||||
|
import dev.jdtech.jellyfin.R
|
||||||
|
import dev.jdtech.jellyfin.adapters.HomeItem
|
||||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||||
|
import dev.jdtech.jellyfin.models.NextUp
|
||||||
import dev.jdtech.jellyfin.models.View
|
import dev.jdtech.jellyfin.models.View
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -16,8 +19,10 @@ class HomeViewModel(
|
||||||
) : AndroidViewModel(application) {
|
) : AndroidViewModel(application) {
|
||||||
private val jellyfinApi = JellyfinApi.getInstance(application, "")
|
private val jellyfinApi = JellyfinApi.getInstance(application, "")
|
||||||
|
|
||||||
private val _views = MutableLiveData<List<View>>()
|
private val nextUpString = application.resources.getString(R.string.next_up)
|
||||||
val views: LiveData<List<View>> = _views
|
|
||||||
|
private val _views = MutableLiveData<List<HomeItem>>()
|
||||||
|
val views: LiveData<List<HomeItem>> = _views
|
||||||
|
|
||||||
private val _items = MutableLiveData<List<BaseItemDto>>()
|
private val _items = MutableLiveData<List<BaseItemDto>>()
|
||||||
val items: LiveData<List<BaseItemDto>> = _items
|
val items: LiveData<List<BaseItemDto>> = _items
|
||||||
|
@ -47,7 +52,14 @@ class HomeViewModel(
|
||||||
views.add(v)
|
views.add(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
_views.value = views
|
val nextUpItems = getNextUp()
|
||||||
|
val nextUp = NextUp(UUID.randomUUID(), nextUpString, nextUpItems)
|
||||||
|
|
||||||
|
_views.value = when (nextUpItems) {
|
||||||
|
null -> views.map { HomeItem.ViewItem(it) }
|
||||||
|
else -> listOf(HomeItem.NextUpSection(nextUp)) + views.map { HomeItem.ViewItem(it) }
|
||||||
|
}
|
||||||
|
|
||||||
_finishedLoading.value = true
|
_finishedLoading.value = true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
_finishedLoading.value = true
|
_finishedLoading.value = true
|
||||||
|
@ -72,6 +84,14 @@ class HomeViewModel(
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getNextUp(): List<BaseItemDto>? {
|
||||||
|
val items: List<BaseItemDto>?
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
items = jellyfinApi.showsApi.getNextUp(jellyfinApi.userId!!).content.items
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BaseItemDto.toView(): View {
|
private fun BaseItemDto.toView(): View {
|
||||||
|
|
54
app/src/main/res/layout/home_episode_item.xml
Normal file
54
app/src/main/res/layout/home_episode_item.xml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="episode"
|
||||||
|
type="org.jellyfin.sdk.model.api.BaseItemDto" />
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="240dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="12dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/episode_image"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintDimensionRatio="H,16:9"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:episodeImage="@{episode}"
|
||||||
|
app:shapeAppearanceOverlay="@style/roundedImageView" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/series_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@{episode.seriesName}"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/episode_image"
|
||||||
|
tools:text="Wonder Egg Priority" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@{String.format(@string/episode_name_extended, episode.parentIndexNumber, episode.indexNumber, episode.name)}"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/series_name"
|
||||||
|
tools:text="The Girl Flautist" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</layout>
|
42
app/src/main/res/layout/next_up_section.xml
Normal file
42
app/src/main/res/layout/next_up_section.xml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="section"
|
||||||
|
type="dev.jdtech.jellyfin.models.NextUp" />
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/section_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:text="@{section.name}"
|
||||||
|
tools:text="Next Up" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/items_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layoutAnimation="@anim/overview_media_animation"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="12dp"
|
||||||
|
app:homeEpisodes="@{section.items}"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
tools:listitem="@layout/home_episode_item" />
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
|
@ -33,6 +33,7 @@
|
||||||
<string name="favorite_button_description">Favorite</string>
|
<string name="favorite_button_description">Favorite</string>
|
||||||
<string name="episode_watched_indicator">Episode watched indicator</string>
|
<string name="episode_watched_indicator">Episode watched indicator</string>
|
||||||
<string name="episode_name">%1$d. %2$s</string>
|
<string name="episode_name">%1$d. %2$s</string>
|
||||||
<string name="episode_name_extended">S%1$dE%2$d - %3$s</string>
|
<string name="episode_name_extended">S%1$d:E%2$d - %3$s</string>
|
||||||
<string name="next_up">Next up</string>
|
<string name="next_up">Next Up</string>
|
||||||
|
<string name="latest_library">Latest %1$s</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue