Fix InfoRow not using requested media source

(cherry picked from commit b0cd0c5b37)
This commit is contained in:
Niels van Velzen 2024-08-09 22:28:03 +02:00
parent dbf6dc0f9a
commit 2a122803c2
4 changed files with 81 additions and 45 deletions

View File

@ -26,6 +26,8 @@ import org.jellyfin.androidtv.util.sdk.getSeasonEpisodeName
import org.jellyfin.androidtv.util.sdk.isNew
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.MediaSourceInfo
import org.jellyfin.sdk.model.api.MediaStream
import org.jellyfin.sdk.model.api.MediaStreamType
import org.jellyfin.sdk.model.api.SeriesStatus
import org.jellyfin.sdk.model.api.VideoRangeType
@ -135,13 +137,23 @@ fun InfoRowSeasonEpisode(item: BaseItemDto) {
}
}
private fun List<MediaStream>.getDefault(type: MediaStreamType, defaultIndex: Int? = null): MediaStream? {
if (defaultIndex != null) {
val byIndex = get(defaultIndex)
if (byIndex.type == type) return byIndex
}
return firstOrNull { it.type == type }
}
@Composable
fun InfoRowMediaDetails(item: BaseItemDto) {
val videoStream = item.mediaStreams?.firstOrNull { it.type == MediaStreamType.VIDEO }
val audioStream = item.mediaStreams?.firstOrNull { it.type == MediaStreamType.AUDIO }
fun InfoRowMediaDetails(mediaSource: MediaSourceInfo) {
val videoStream = mediaSource.mediaStreams?.getDefault(MediaStreamType.VIDEO)
val audioStream = mediaSource.mediaStreams?.getDefault(MediaStreamType.AUDIO, mediaSource.defaultAudioStreamIndex)
val subtitleStream = mediaSource.mediaStreams?.getDefault(MediaStreamType.SUBTITLE, mediaSource.defaultSubtitleStreamIndex)
// Subtitles
if (item.hasSubtitles == true) {
if (subtitleStream != null) {
InfoRowItem(
contentDescription = null,
colors = InfoRowColors.Default,
@ -219,6 +231,7 @@ fun InfoRowMediaDetails(item: BaseItemDto) {
@Composable
fun BaseItemInfoRow(
item: BaseItemDto,
mediaSource: MediaSourceInfo?,
includeRuntime: Boolean,
) {
val userPreferences = koinInject<UserPreferences>()
@ -239,7 +252,7 @@ fun BaseItemInfoRow(
InfoRowDate(item)
if (includeRuntime) item.runTimeTicks?.ticks?.let { BaseItemInfoRowRuntime(it) }
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
BaseItemKind.BOX_SET -> {
@ -257,7 +270,7 @@ fun BaseItemInfoRow(
val runtime = item.cumulativeRunTimeTicks ?: item.runTimeTicks
if (includeRuntime) runtime?.ticks?.let { BaseItemInfoRowRuntime(it) }
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
BaseItemKind.SERIES -> {
@ -265,7 +278,7 @@ fun BaseItemInfoRow(
if (includeRuntime) item.runTimeTicks?.ticks?.let { BaseItemInfoRowRuntime(it) }
InfoRowSeriesStatus(item)
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
BaseItemKind.PROGRAM -> {
@ -303,7 +316,7 @@ fun BaseItemInfoRow(
if (includeRuntime) item.runTimeTicks?.ticks?.let { BaseItemInfoRowRuntime(it) }
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
BaseItemKind.MUSIC_ARTIST -> {
@ -343,14 +356,14 @@ fun BaseItemInfoRow(
val runtime = item.cumulativeRunTimeTicks ?: item.runTimeTicks
if (includeRuntime) runtime?.ticks?.let { BaseItemInfoRowRuntime(it) }
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
else -> {
InfoRowDate(item)
if (includeRuntime) item.runTimeTicks?.ticks?.let { BaseItemInfoRowRuntime(it) }
item.officialRating?.let { InfoRowParentalRating(it) }
InfoRowMediaDetails(item)
mediaSource?.let { InfoRowMediaDetails(it) }
}
}
}
@ -364,6 +377,7 @@ class BaseItemInfoRowView @JvmOverloads constructor(
attrs: AttributeSet? = null,
) : AbstractComposeView(context, attrs) {
private val _item = MutableStateFlow<BaseItemDto?>(null)
private val _mediaSource = MutableStateFlow<MediaSourceInfo?>(null)
private val _includeRuntime = MutableStateFlow(false)
var item: BaseItemDto?
@ -372,6 +386,12 @@ class BaseItemInfoRowView @JvmOverloads constructor(
_item.value = value
}
var mediaSource: MediaSourceInfo?
get() = _mediaSource.value
set(value) {
_mediaSource.value = value
}
var includeRuntime: Boolean
get() = _includeRuntime.value
set(value) {
@ -386,8 +406,9 @@ class BaseItemInfoRowView @JvmOverloads constructor(
@Composable
override fun Content() {
val item by _item.collectAsState()
val mediaSource by _mediaSource.collectAsState()
val includeRuntime by _includeRuntime.collectAsState()
item?.let { BaseItemInfoRow(it, includeRuntime) }
item?.let { BaseItemInfoRow(it, mediaSource, includeRuntime) }
}
}

View File

@ -21,7 +21,7 @@ class MyDetailsOverviewRowPresenter(
fun setItem(row: MyDetailsOverviewRow) {
setTitle(row.item.name)
InfoLayoutHelper.addInfoRow(view.context, row.item, binding.fdMainInfoRow, false)
InfoLayoutHelper.addInfoRow(view.context, row.item, row.item.mediaSources?.getOrNull(row.selectedMediaSourceIndex), binding.fdMainInfoRow, false)
binding.fdGenreRow.text = row.item.genres?.joinToString(" / ")
binding.infoTitle1.text = row.infoItem1?.label

View File

@ -1,33 +0,0 @@
package org.jellyfin.androidtv.util;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
import org.jellyfin.androidtv.ui.browsing.composable.inforow.BaseItemInfoRowView;
import org.jellyfin.sdk.model.api.BaseItemDto;
public class InfoLayoutHelper {
public static void addInfoRow(Context context, BaseItemDto item, LinearLayout layout, boolean includeRuntime) {
// Find existing BaseItemInfoRowView or create a new one
BaseItemInfoRowView baseItemInfoRowView = null;
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof BaseItemInfoRowView) {
baseItemInfoRowView = (BaseItemInfoRowView) child;
break;
}
}
if (baseItemInfoRowView == null) {
baseItemInfoRowView = new BaseItemInfoRowView(context);
layout.addView(baseItemInfoRowView);
}
// Update item info
baseItemInfoRowView.setItem(item);
baseItemInfoRowView.setIncludeRuntime(includeRuntime);
}
}

View File

@ -0,0 +1,48 @@
package org.jellyfin.androidtv.util
import android.content.Context
import android.widget.LinearLayout
import org.jellyfin.androidtv.ui.browsing.composable.inforow.BaseItemInfoRowView
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.MediaSourceInfo
object InfoLayoutHelper {
@JvmStatic
fun addInfoRow(
context: Context,
item: BaseItemDto?,
mediaSource: MediaSourceInfo?,
layout: LinearLayout,
includeRuntime: Boolean
) {
// Find existing BaseItemInfoRowView or create a new one
var baseItemInfoRowView: BaseItemInfoRowView? = null
for (i in 0 until layout.childCount) {
val child = layout.getChildAt(i)
if (child is BaseItemInfoRowView) {
baseItemInfoRowView = child
break
}
}
if (baseItemInfoRowView == null) {
baseItemInfoRowView = BaseItemInfoRowView(context)
layout.addView(baseItemInfoRowView)
}
// Update item info
baseItemInfoRowView.item = item
baseItemInfoRowView.mediaSource = mediaSource ?: item?.mediaSources?.firstOrNull()
baseItemInfoRowView.includeRuntime = includeRuntime
}
@JvmStatic
fun addInfoRow(
context: Context,
item: BaseItemDto?,
layout: LinearLayout,
includeRuntime: Boolean
) = addInfoRow(context, item, null, layout, includeRuntime)
}