diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt index 475a726b84..727b66a500 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/home/HomeFragment.kt @@ -169,7 +169,7 @@ class HomeFragment : RowsSupportFragment(), AudioEventListener { //React to deletion val dataRefreshService = get(DataRefreshService::class.java) - if (activity != null && !requireActivity().isFinishing && currentRow != null && currentItem != null && currentItem!!.itemId != null && currentItem!!.itemId.equals(dataRefreshService.lastDeletedItemId)) { + if (activity != null && !requireActivity().isFinishing && currentRow != null && currentItem != null && currentItem!!.getItemId() != null && currentItem!!.getItemId().equals(dataRefreshService.lastDeletedItemId)) { (currentRow!!.adapter as ItemRowAdapter).remove(currentItem) dataRefreshService.lastDeletedItemId = null } @@ -203,7 +203,7 @@ class HomeFragment : RowsSupportFragment(), AudioEventListener { private fun refreshCurrentItem() { currentItem?.let { item -> - if (item.baseItemType == BaseItemKind.USER_VIEW || item.baseItemType == BaseItemKind.COLLECTION_FOLDER) return + if (item.getBaseItemType() == BaseItemKind.USER_VIEW || item.getBaseItemType() == BaseItemKind.COLLECTION_FOLDER) return Timber.d("Refresh item ${item.getFullName(requireContext())}") diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.java deleted file mode 100644 index 0966dc4ea6..0000000000 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.jellyfin.androidtv.ui.itemhandling; - -import org.jellyfin.apiclient.model.dto.BaseItemDto; - -public class AudioQueueItem extends BaseRowItem { - public AudioQueueItem(int index, BaseItemDto item) { - super(index, item); - this.staticHeight = true; - } -} diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.kt b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.kt new file mode 100644 index 0000000000..cbbe48de68 --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/AudioQueueItem.kt @@ -0,0 +1,12 @@ +package org.jellyfin.androidtv.ui.itemhandling + +import org.jellyfin.apiclient.model.dto.BaseItemDto + +class AudioQueueItem( + index: Int, + item: BaseItemDto, +) : BaseRowItem( + index = index, + item = item, + staticHeight = true +) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.java deleted file mode 100644 index 890ae12269..0000000000 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.java +++ /dev/null @@ -1,545 +0,0 @@ -package org.jellyfin.androidtv.ui.itemhandling; - -import static org.koin.java.KoinJavaComponent.inject; - -import android.content.Context; -import android.graphics.drawable.Drawable; - -import androidx.core.content.ContextCompat; - -import org.jellyfin.androidtv.R; -import org.jellyfin.androidtv.auth.repository.UserRepository; -import org.jellyfin.androidtv.data.model.ChapterItemInfo; -import org.jellyfin.androidtv.ui.GridButton; -import org.jellyfin.androidtv.util.ImageUtils; -import org.jellyfin.androidtv.util.TimeUtils; -import org.jellyfin.androidtv.util.Utils; -import org.jellyfin.androidtv.util.apiclient.BaseItemUtils; -import org.jellyfin.androidtv.util.sdk.BaseItemExtensionsKt; -import org.jellyfin.androidtv.util.sdk.compat.ModelCompat; -import org.jellyfin.apiclient.interaction.ApiClient; -import org.jellyfin.apiclient.interaction.EmptyResponse; -import org.jellyfin.apiclient.interaction.Response; -import org.jellyfin.apiclient.model.dto.BaseItemDto; -import org.jellyfin.apiclient.model.entities.ImageType; -import org.jellyfin.apiclient.model.livetv.ChannelInfoDto; -import org.jellyfin.apiclient.model.livetv.SeriesTimerInfoDto; -import org.jellyfin.sdk.model.api.BaseItemKind; -import org.jellyfin.sdk.model.api.BaseItemPerson; -import org.jellyfin.sdk.model.api.SearchHint; -import org.jellyfin.sdk.model.api.UserDto; -import org.koin.java.KoinJavaComponent; - -import java.text.SimpleDateFormat; -import java.util.Arrays; - -import kotlin.Lazy; -import timber.log.Timber; - -public class BaseRowItem { - private int index; - private BaseItemDto baseItem; - private BaseItemPerson person; - private ChapterItemInfo chapterInfo; - private SearchHint searchHint; - private ChannelInfoDto channelInfo; - private SeriesTimerInfoDto seriesTimerInfo; - private GridButton gridButton; - private ItemType type; - private boolean preferParentThumb = false; - protected boolean staticHeight = false; - private SelectAction selectAction = SelectAction.ShowDetails; - private boolean isPlaying; - - private Lazy apiClient = inject(ApiClient.class); - - public BaseRowItem(int index, BaseItemDto item) { - this(index, item, false, false); - } - - public BaseRowItem(int index, BaseItemDto item, boolean preferParentThumb, boolean staticHeight) { - this(index, item, preferParentThumb, staticHeight, SelectAction.ShowDetails); - } - - public BaseRowItem(int index, BaseItemDto item, boolean preferParentThumb, boolean staticHeight, SelectAction selectAction) { - this.index = index; - this.baseItem = item; - this.type = ModelCompat.asSdk(item).getType() == BaseItemKind.PROGRAM ? ItemType.LiveTvProgram : ModelCompat.asSdk(item).getType() == BaseItemKind.RECORDING ? ItemType.LiveTvRecording : ItemType.BaseItem; - this.preferParentThumb = preferParentThumb; - this.staticHeight = staticHeight; - this.selectAction = selectAction; - } - - public BaseRowItem(int index, ChannelInfoDto channel) { - this.index = index; - this.channelInfo = channel; - this.type = ItemType.LiveTvChannel; - } - - public BaseRowItem(BaseItemDto program, boolean staticHeight) { - this(0, program, false, staticHeight); - } - - public BaseRowItem(BaseItemDto program) { - this(0, program); - } - - public BaseRowItem(SeriesTimerInfoDto timer) { - this.seriesTimerInfo = timer; - this.type = ItemType.SeriesTimer; - } - - public BaseRowItem(BaseItemPerson person) { - this.person = person; - this.staticHeight = true; - this.type = ItemType.Person; - } - - public BaseRowItem(SearchHint hint) { - this.searchHint = hint; - type = ItemType.SearchHint; - } - - public BaseRowItem(ChapterItemInfo chapter) { - this.chapterInfo = chapter; - this.staticHeight = true; - this.type = ItemType.Chapter; - } - - public BaseRowItem(GridButton button) { - this.gridButton = button; - this.type = ItemType.GridButton; - this.staticHeight = true; - } - - public int getIndex() { - return index; - } - - public void setIndex(int ndx) { - index = ndx; - } - - public BaseItemDto getBaseItem() { - return baseItem; - } - - public BaseItemPerson getPerson() { - return person; - } - - public ChapterItemInfo getChapterInfo() { - return chapterInfo; - } - - public SearchHint getSearchHint() { - return searchHint; - } - - public ChannelInfoDto getChannelInfo() { - return channelInfo; - } - - public BaseItemDto getProgramInfo() { - return baseItem; - } - - public BaseItemDto getRecordingInfo() { - return baseItem; - } - - public SeriesTimerInfoDto getSeriesTimerInfo() { - return seriesTimerInfo; - } - - public GridButton getGridButton() { - return gridButton; - } - - public boolean isChapter() { - return type == ItemType.Chapter; - } - - public boolean isPerson() { - return type == ItemType.Person; - } - - public boolean isBaseItem() { - return type == ItemType.BaseItem; - } - - public boolean getPreferParentThumb() { - return preferParentThumb; - } - - public ItemType getItemType() { - return type; - } - - public boolean isFolder() { - return type == ItemType.BaseItem && baseItem != null && baseItem.getIsFolderItem(); - } - - public boolean showCardInfoOverlay() { - return type == ItemType.BaseItem && baseItem != null - && Arrays.asList(BaseItemKind.FOLDER, BaseItemKind.PHOTO_ALBUM, - BaseItemKind.USER_VIEW, BaseItemKind.COLLECTION_FOLDER, BaseItemKind.PHOTO, - BaseItemKind.VIDEO, BaseItemKind.PERSON, BaseItemKind.PLAYLIST, - BaseItemKind.MUSIC_ARTIST).contains(ModelCompat.asSdk(baseItem).getType()); - } - - public boolean isValid() { - switch (type) { - case BaseItem: - return baseItem != null; - case Person: - return person != null; - case Chapter: - return chapterInfo != null; - case SeriesTimer: - return seriesTimerInfo != null; - default: - // compatibility - return true; - } - } - - public String getImageUrl(Context context, org.jellyfin.androidtv.constant.ImageType imageType, int maxHeight) { - switch (type) { - case BaseItem: - case LiveTvProgram: - case LiveTvRecording: - switch (imageType) { - case BANNER: - return ImageUtils.getBannerImageUrl(baseItem, apiClient.getValue(), maxHeight); - case THUMB: - return ImageUtils.getThumbImageUrl(baseItem, apiClient.getValue(), maxHeight); - default: - return getPrimaryImageUrl(context, maxHeight); - } - default: - return getPrimaryImageUrl(context, maxHeight); - } - } - - public String getPrimaryImageUrl(Context context, int maxHeight) { - switch (type) { - case BaseItem: - case LiveTvProgram: - case LiveTvRecording: - return ImageUtils.getPrimaryImageUrl(baseItem, preferParentThumb, maxHeight); - case Person: - return ImageUtils.getPrimaryImageUrl(person, maxHeight); - case Chapter: - return chapterInfo.getImagePath(); - case LiveTvChannel: - return ImageUtils.getPrimaryImageUrl(channelInfo, apiClient.getValue()); - case GridButton: - return ImageUtils.getResourceUrl(context, gridButton.getImageRes()); - case SeriesTimer: - return ImageUtils.getResourceUrl(context, R.drawable.tile_land_series_timer); - case SearchHint: - if (Utils.isNonEmpty(searchHint.getPrimaryImageTag())) { - return ImageUtils.getImageUrl(searchHint.getItemId().toString(), ImageType.Primary, searchHint.getPrimaryImageTag()); - } else if (Utils.isNonEmpty(searchHint.getThumbImageItemId())) { - return ImageUtils.getImageUrl(searchHint.getThumbImageItemId(), ImageType.Thumb, searchHint.getThumbImageTag()); - } - } - return null; - } - - public boolean isFavorite() { - switch (type) { - case BaseItem: - case LiveTvRecording: - case LiveTvProgram: - return baseItem.getUserData() != null && baseItem.getUserData().getIsFavorite(); - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case GridButton: - break; - } - - return false; - } - - public boolean isPlayed() { - switch (type) { - case BaseItem: - case LiveTvRecording: - case LiveTvProgram: - return baseItem.getUserData() != null && baseItem.getUserData().getPlayed(); - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case GridButton: - break; - } - - return false; - } - - public String getCardName(Context context) { - switch (type) { - case BaseItem: - if (ModelCompat.asSdk(baseItem).getType() == BaseItemKind.AUDIO) { - return baseItem.getAlbumArtist() != null ? baseItem.getAlbumArtist() : baseItem.getAlbum() != null ? baseItem.getAlbum() : ""; - } - default: - return getFullName(context); - } - } - - public String getFullName(Context context) { - switch (type) { - case BaseItem: - case LiveTvProgram: - case LiveTvRecording: - return BaseItemExtensionsKt.getFullName(ModelCompat.asSdk(baseItem), context); - case Person: - return person.getName(); - case Chapter: - return chapterInfo.getName(); - case LiveTvChannel: - return channelInfo.getName(); - case GridButton: - return gridButton.getText(); - case SeriesTimer: - return seriesTimerInfo.getName(); - case SearchHint: - return (searchHint.getSeries() != null ? searchHint.getSeries() + " - " : "") + searchHint.getName(); - } - - return context.getString(R.string.lbl_bracket_unknown); - } - - public String getName(Context context) { - switch (type) { - case BaseItem: - case LiveTvRecording: - case LiveTvProgram: - return ModelCompat.asSdk(baseItem).getType() == BaseItemKind.AUDIO ? getFullName(context) : baseItem.getName(); - case Person: - return person.getName(); - case Chapter: - return chapterInfo.getName(); - case SearchHint: - return searchHint.getName(); - case LiveTvChannel: - return channelInfo.getName(); - case GridButton: - return gridButton.getText(); - case SeriesTimer: - return seriesTimerInfo.getName(); - } - - return context.getString(R.string.lbl_bracket_unknown); - } - - public String getItemId() { - switch (type) { - case BaseItem: - case LiveTvProgram: - case LiveTvRecording: - return baseItem.getId(); - case Person: - return person.getId().toString(); - case Chapter: - return chapterInfo.getItemId().toString(); - case LiveTvChannel: - return channelInfo.getId(); - case GridButton: - return null; - case SearchHint: - return searchHint.getItemId().toString(); - case SeriesTimer: - return seriesTimerInfo.getId(); - } - - return null; - } - - public String getSubText(Context context) { - switch (type) { - case BaseItem: - return BaseItemExtensionsKt.getSubName(ModelCompat.asSdk(baseItem), context); - case Person: - return person.getRole(); - case Chapter: - Long pos = chapterInfo.getStartPositionTicks() / 10000; - return TimeUtils.formatMillis(pos.intValue()); - case LiveTvChannel: - return channelInfo.getNumber(); - case LiveTvProgram: - return baseItem.getEpisodeTitle() != null ? baseItem.getEpisodeTitle() : baseItem.getChannelName(); - case LiveTvRecording: - return (baseItem.getChannelName() != null ? baseItem.getChannelName() + " - " : "") + (baseItem.getEpisodeTitle() != null ? baseItem.getEpisodeTitle() : "") + " " + - new SimpleDateFormat("d MMM").format(TimeUtils.convertToLocalDate(baseItem.getStartDate())) + " " + - (android.text.format.DateFormat.getTimeFormat(context).format(TimeUtils.convertToLocalDate(baseItem.getStartDate())) + "-" - + android.text.format.DateFormat.getTimeFormat(context).format(TimeUtils.convertToLocalDate(baseItem.getEndDate()))); - case SearchHint: - return searchHint.getType(); - case SeriesTimer: - return (Utils.isTrue(seriesTimerInfo.getRecordAnyChannel()) ? "All Channels" : seriesTimerInfo.getChannelName()) + " " + seriesTimerInfo.getDayPattern(); - } - - return ""; - } - - public BaseItemKind getBaseItemType() { - if (baseItem != null) - return ModelCompat.asSdk(baseItem).getType(); - else - return null; - } - - public String getSummary(Context context) { - switch (type) { - case BaseItem: - case LiveTvRecording: - case LiveTvProgram: - return baseItem.getOverview(); - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case GridButton: - break; - case SeriesTimer: - return BaseItemUtils.getSeriesOverview(seriesTimerInfo, context); - } - - return ""; - } - - public long getRuntimeTicks() { - switch (type) { - case LiveTvRecording: - case BaseItem: - return baseItem.getRunTimeTicks() != null ? baseItem.getRunTimeTicks() : 0; - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case GridButton: - break; - case LiveTvProgram: - return ((baseItem.getStartDate() != null) && (baseItem.getEndDate() != null)) ? (baseItem.getEndDate().getTime() - (baseItem.getStartDate().getTime() * 10000)) : 0; - } - - return 0; - } - - public int getChildCount() { - switch (type) { - case BaseItem: - return isFolder() && ModelCompat.asSdk(baseItem).getType() != BaseItemKind.MUSIC_ARTIST && baseItem.getChildCount() != null ? baseItem.getChildCount() : -1; - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case LiveTvRecording: - case GridButton: - case LiveTvProgram: - break; - } - - return -1; - } - - public String getChildCountStr() { - if (baseItem != null && ModelCompat.asSdk(baseItem).getType() == BaseItemKind.PLAYLIST && baseItem.getCumulativeRunTimeTicks() != null) { - return TimeUtils.formatMillis(baseItem.getCumulativeRunTimeTicks() / 10000); - } else { - Integer count = getChildCount(); - return count > 0 ? count.toString() : ""; - } - } - - public Drawable getBadgeImage(Context context) { - if (baseItem != null) { - switch (type) { - case BaseItem: - if (ModelCompat.asSdk(baseItem).getType() == BaseItemKind.MOVIE && baseItem.getCriticRating() != null) { - return baseItem.getCriticRating() > 59 ? ContextCompat.getDrawable(context, R.drawable.ic_rt_fresh) : ContextCompat.getDrawable(context, R.drawable.ic_rt_rotten); - } else if (ModelCompat.asSdk(baseItem).getType() == BaseItemKind.PROGRAM && baseItem.getTimerId() != null) { - return baseItem.getSeriesTimerId() != null ? ContextCompat.getDrawable(context, R.drawable.ic_record_series_red) : ContextCompat.getDrawable(context, R.drawable.ic_record_red); - } - break; - case Person: - case LiveTvProgram: - if (baseItem.getTimerId() != null) { - return baseItem.getSeriesTimerId() != null ? ContextCompat.getDrawable(context, R.drawable.ic_record_series_red) : ContextCompat.getDrawable(context, R.drawable.ic_record_red); - } - case Chapter: - break; - } - } - - return ContextCompat.getDrawable(context, R.drawable.blank10x10); - } - - public void refresh(final EmptyResponse outerResponse) { - switch (type) { - case BaseItem: - String id = getItemId(); - UserDto user = KoinJavaComponent.get(UserRepository.class).getCurrentUser().getValue(); - if (Utils.isNonEmpty(id) && user != null) { - apiClient.getValue().GetItemAsync(id, user.getId().toString(), new Response() { - @Override - public void onResponse(BaseItemDto response) { - baseItem = response; - outerResponse.onResponse(); - } - }); - } else { - Timber.w("BaseRowItem.refresh() failed!"); - } - break; - case Person: - case Chapter: - case SearchHint: - case LiveTvChannel: - case LiveTvRecording: - case GridButton: - case LiveTvProgram: - break; - } - } - - public SelectAction getSelectAction() { - return selectAction; - } - - public boolean isStaticHeight() { - return staticHeight; - } - - public boolean isPlaying() { - return isPlaying; - } - - public void setIsPlaying(boolean value) { - isPlaying = value; - } - - public enum ItemType { - BaseItem, - Person, - Chapter, - SearchHint, - LiveTvChannel, - LiveTvRecording, - GridButton, - SeriesTimer, - LiveTvProgram, - } - - public enum SelectAction { - ShowDetails, - Play - } -} diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.kt b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.kt new file mode 100644 index 0000000000..c1b9cc8ff2 --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItem.kt @@ -0,0 +1,342 @@ +package org.jellyfin.androidtv.ui.itemhandling + +import android.content.Context +import android.graphics.drawable.Drawable +import android.text.format.DateFormat +import androidx.core.content.ContextCompat +import org.jellyfin.androidtv.R +import org.jellyfin.androidtv.auth.repository.UserRepository +import org.jellyfin.androidtv.constant.ImageType +import org.jellyfin.androidtv.data.model.ChapterItemInfo +import org.jellyfin.androidtv.ui.GridButton +import org.jellyfin.androidtv.util.ImageUtils +import org.jellyfin.androidtv.util.TimeUtils +import org.jellyfin.androidtv.util.apiclient.getSeriesOverview +import org.jellyfin.androidtv.util.sdk.compat.asSdk +import org.jellyfin.androidtv.util.sdk.getFullName +import org.jellyfin.androidtv.util.sdk.getSubName +import org.jellyfin.apiclient.interaction.ApiClient +import org.jellyfin.apiclient.interaction.EmptyResponse +import org.jellyfin.apiclient.interaction.Response +import org.jellyfin.apiclient.model.dto.BaseItemDto +import org.jellyfin.apiclient.model.livetv.ChannelInfoDto +import org.jellyfin.apiclient.model.livetv.SeriesTimerInfoDto +import org.jellyfin.sdk.model.api.BaseItemKind +import org.jellyfin.sdk.model.api.BaseItemPerson +import org.jellyfin.sdk.model.api.SearchHint +import org.koin.java.KoinJavaComponent.get +import org.koin.java.KoinJavaComponent.inject +import timber.log.Timber +import java.text.SimpleDateFormat + +open class BaseRowItem private constructor( + val baseRowType: BaseRowType, + var index: Int = 0, + val staticHeight: Boolean = false, + val preferParentThumb: Boolean = false, + val selectAction: BaseRowItemSelectAction = BaseRowItemSelectAction.ShowDetails, + var playing: Boolean = false, + var baseItem: BaseItemDto? = null, + val basePerson: BaseItemPerson? = null, + val chapterInfo: ChapterItemInfo? = null, + val searchHint: SearchHint? = null, + val channelInfo: ChannelInfoDto? = null, + val seriesTimerInfo: SeriesTimerInfoDto? = null, + val gridButton: GridButton? = null, +) { + // Start of constructor hell + @JvmOverloads + constructor( + index: Int = 0, + item: BaseItemDto, + preferParentThumb: Boolean = false, + staticHeight: Boolean = false, + selectAction: BaseRowItemSelectAction = BaseRowItemSelectAction.ShowDetails, + ) : this( + baseRowType = when (item.asSdk().type) { + BaseItemKind.PROGRAM -> BaseRowType.LiveTvProgram + BaseItemKind.RECORDING -> BaseRowType.LiveTvRecording + else -> BaseRowType.BaseItem + }, + index = index, + staticHeight = staticHeight, + preferParentThumb = preferParentThumb, + selectAction = selectAction, + baseItem = item, + ) + + constructor( + index: Int, + item: ChannelInfoDto, + ) : this( + index = index, + baseRowType = BaseRowType.LiveTvChannel, + channelInfo = item, + ) + + constructor( + item: BaseItemDto, + staticHeight: Boolean, + ) : this( + index = 0, + item = item, + preferParentThumb = false, + staticHeight = staticHeight, + ) + + constructor( + item: SeriesTimerInfoDto, + ) : this( + baseRowType = BaseRowType.SeriesTimer, + seriesTimerInfo = item, + ) + + constructor( + item: BaseItemPerson, + ) : this( + baseRowType = BaseRowType.Person, + staticHeight = true, + basePerson = item, + ) + + constructor( + item: SearchHint, + ) : this( + baseRowType = BaseRowType.SearchHint, + searchHint = item, + ) + + constructor( + item: ChapterItemInfo, + ) : this( + baseRowType = BaseRowType.Chapter, + staticHeight = true, + chapterInfo = item, + ) + + constructor( + item: GridButton, + ) : this( + baseRowType = BaseRowType.GridButton, + staticHeight = true, + gridButton = item, + ) + // End of constructor hell + + fun showCardInfoOverlay() = baseRowType == BaseRowType.BaseItem && listOf( + BaseItemKind.FOLDER, + BaseItemKind.PHOTO_ALBUM, + BaseItemKind.USER_VIEW, + BaseItemKind.COLLECTION_FOLDER, + BaseItemKind.PHOTO, + BaseItemKind.VIDEO, + BaseItemKind.PERSON, + BaseItemKind.PLAYLIST, + BaseItemKind.MUSIC_ARTIST + ).contains(baseItem?.asSdk()?.type) + + fun getImageUrl(context: Context, imageType: ImageType, maxHeight: Int) = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvProgram, + BaseRowType.LiveTvRecording -> { + val apiClient by inject(ApiClient::class.java) + when (imageType) { + ImageType.BANNER -> ImageUtils.getBannerImageUrl(baseItem, apiClient, maxHeight) + ImageType.THUMB -> ImageUtils.getThumbImageUrl(baseItem, apiClient, maxHeight) + else -> getPrimaryImageUrl(context, maxHeight) + } + } + else -> getPrimaryImageUrl(context, maxHeight) + } + + fun getPrimaryImageUrl(context: Context, maxHeight: Int) = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvProgram, + BaseRowType.LiveTvRecording -> ImageUtils.getPrimaryImageUrl(baseItem!!, preferParentThumb, maxHeight) + BaseRowType.Person -> ImageUtils.getPrimaryImageUrl(basePerson!!, maxHeight) + BaseRowType.Chapter -> chapterInfo?.imagePath + BaseRowType.LiveTvChannel -> { + val apiClient by inject(ApiClient::class.java) + ImageUtils.getPrimaryImageUrl(channelInfo, apiClient) + } + BaseRowType.GridButton -> ImageUtils.getResourceUrl(context, gridButton!!.imageRes) + BaseRowType.SeriesTimer -> ImageUtils.getResourceUrl(context, R.drawable.tile_land_series_timer) + BaseRowType.SearchHint -> when { + !searchHint?.primaryImageTag.isNullOrBlank() -> ImageUtils.getImageUrl(searchHint!!.itemId.toString(), org.jellyfin.apiclient.model.entities.ImageType.Primary, searchHint.primaryImageTag!!) + !searchHint?.thumbImageItemId.isNullOrBlank() -> ImageUtils.getImageUrl(searchHint!!.thumbImageItemId!!, org.jellyfin.apiclient.model.entities.ImageType.Thumb, searchHint.thumbImageTag!!) + else -> null + } + } + + fun getBaseItemType() = baseItem?.asSdk()?.type + + fun isFavorite(): Boolean = baseItem?.userData?.isFavorite == true + fun isFolder(): Boolean = baseItem?.isFolderItem == true + fun isPlayed(): Boolean = baseItem?.userData?.played == true + + fun getCardName(context: Context): String? { + val item = baseItem?.asSdk() + return when { + item?.type == BaseItemKind.AUDIO && item.albumArtist != null -> item.albumArtist + item?.type == BaseItemKind.AUDIO && item.album != null -> item.album + else -> getFullName(context) + } + } + + fun getFullName(context: Context) = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvProgram, + BaseRowType.LiveTvRecording -> baseItem?.asSdk()?.getFullName(context) + BaseRowType.Person -> basePerson?.name + BaseRowType.Chapter -> chapterInfo?.name + BaseRowType.LiveTvChannel -> channelInfo?.name + BaseRowType.GridButton -> gridButton?.text + BaseRowType.SeriesTimer -> seriesTimerInfo?.name + BaseRowType.SearchHint -> listOfNotNull(searchHint?.series, searchHint?.name).joinToString(" - ") + } + + fun getName(context: Context) = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvRecording, + BaseRowType.LiveTvProgram -> when (baseItem?.asSdk()?.type) { + BaseItemKind.AUDIO -> getFullName(context) + else -> baseItem?.name + } + BaseRowType.Person -> basePerson?.name + BaseRowType.Chapter -> chapterInfo?.name + BaseRowType.SearchHint -> searchHint?.name + BaseRowType.LiveTvChannel -> channelInfo?.name + BaseRowType.GridButton -> gridButton?.text + BaseRowType.SeriesTimer -> seriesTimerInfo?.name + } + + fun getItemId() = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvProgram, + BaseRowType.LiveTvRecording -> baseItem?.id + BaseRowType.Person -> basePerson?.id?.toString() + BaseRowType.Chapter -> chapterInfo?.itemId?.toString() + BaseRowType.LiveTvChannel -> channelInfo?.id + BaseRowType.GridButton -> null + BaseRowType.SearchHint -> searchHint?.itemId?.toString() + BaseRowType.SeriesTimer -> seriesTimerInfo?.id + } + + fun getSubText(context: Context) = when (baseRowType) { + BaseRowType.BaseItem -> baseItem?.asSdk()?.getSubName(context) + BaseRowType.Person -> basePerson?.role + BaseRowType.Chapter -> chapterInfo?.startPositionTicks?.div(10000)?.let(TimeUtils::formatMillis) + BaseRowType.LiveTvChannel -> channelInfo?.number + BaseRowType.LiveTvProgram -> baseItem?.episodeTitle ?: baseItem?.channelName + BaseRowType.LiveTvRecording -> { + val title = listOfNotNull( + baseItem?.channelName, + baseItem?.episodeTitle + ).joinToString(" - ") + + val timestamp = buildString { + append(SimpleDateFormat("d MMM").format(TimeUtils.convertToLocalDate(baseItem!!.startDate))) + append(" ") + append((DateFormat.getTimeFormat(context).format(TimeUtils.convertToLocalDate(baseItem!!.startDate)))) + append(" - ") + append(DateFormat.getTimeFormat(context).format(TimeUtils.convertToLocalDate(baseItem!!.endDate))) + } + + "$title $timestamp" + } + BaseRowType.SearchHint -> searchHint?.type + BaseRowType.SeriesTimer -> { + val channelName = if (seriesTimerInfo?.recordAnyChannel == true) "All Channels" + else seriesTimerInfo?.channelName + + listOfNotNull(channelName, seriesTimerInfo?.dayPattern).joinToString(" ") + } + BaseRowType.GridButton -> "" + } + + fun getSummary(context: Context) = when (baseRowType) { + BaseRowType.BaseItem, + BaseRowType.LiveTvRecording, + BaseRowType.LiveTvProgram -> baseItem?.overview + BaseRowType.SeriesTimer -> seriesTimerInfo?.getSeriesOverview(context) + else -> null + }.orEmpty() + + fun getRuntimeTicks() = when (baseRowType) { + BaseRowType.LiveTvRecording, + BaseRowType.BaseItem -> baseItem?.runTimeTicks ?: 0 + BaseRowType.LiveTvProgram -> { + val start = baseItem?.startDate + val end = baseItem?.endDate + + if (start != null && end != null) (end.time - start.time) * 10000 + else 0 + } + else -> 0 + } + + fun getChildCountStr(): String? { + // Playlist + if (baseItem?.asSdk()?.type == BaseItemKind.PLAYLIST) { + val childCount = baseItem?.cumulativeRunTimeTicks?.let { + TimeUtils.formatMillis(it / 10000) + } + if (childCount != null) return childCount + } + + // Folder + if (isFolder() && baseItem?.asSdk()?.type != BaseItemKind.MUSIC_ARTIST) { + val childCount = baseItem?.childCount + if (childCount != null && childCount > 0) return childCount.toString() + } + + // Default + return null + } + + fun getBadgeImage(context: Context): Drawable? { + val item = baseItem?.asSdk() + + return when (baseRowType) { + BaseRowType.BaseItem -> when { + item?.type == BaseItemKind.MOVIE && item.criticRating != null -> when { + item.criticRating!! > 59f -> R.drawable.ic_rt_fresh + else -> R.drawable.ic_rt_rotten + } + item?.type == BaseItemKind.PROGRAM && item.timerId != null -> when { + item.seriesTimerId != null -> R.drawable.ic_record_series_red + else -> R.drawable.ic_record_red + } + else -> R.drawable.blank10x10 + } + BaseRowType.Person, + BaseRowType.LiveTvProgram -> when { + item?.seriesTimerId != null -> R.drawable.ic_record_series_red + item?.timerId != null -> R.drawable.ic_record_red + else -> R.drawable.blank10x10 + } + else -> R.drawable.blank10x10 + }.let { ContextCompat.getDrawable(context, it) } + } + + // TODO rewrite with SDK (requires type change for [baseItem]) + fun refresh(outerResponse: EmptyResponse) { + if (baseRowType == BaseRowType.BaseItem) { + val id = getItemId() + val apiClient by inject(ApiClient::class.java) + val user = get(UserRepository::class.java).currentUser.value + + if (id.isNullOrBlank() || user == null) { + Timber.w("Skipping call to BaseRowItem.refresh()") + return + } + + apiClient.GetItemAsync(id, user.id.toString(), object : Response() { + override fun onResponse(response: BaseItemDto) { + baseItem = response + outerResponse.onResponse() + } + }) + } + } +} diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItemSelectAction.kt b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItemSelectAction.kt new file mode 100644 index 0000000000..53eb3341b1 --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowItemSelectAction.kt @@ -0,0 +1,6 @@ +package org.jellyfin.androidtv.ui.itemhandling + +enum class BaseRowItemSelectAction { + ShowDetails, + Play, +} diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowType.kt b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowType.kt new file mode 100644 index 0000000000..97f26a6411 --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/BaseRowType.kt @@ -0,0 +1,13 @@ +package org.jellyfin.androidtv.ui.itemhandling + +enum class BaseRowType { + BaseItem, + Person, + Chapter, + SearchHint, + LiveTvChannel, + LiveTvRecording, + GridButton, + SeriesTimer, + LiveTvProgram, +} diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemLauncher.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemLauncher.java index 4bcbf90ecd..8d56034c67 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemLauncher.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemLauncher.java @@ -95,7 +95,7 @@ public static void launchUserView(final org.jellyfin.sdk.model.api.BaseItemDto b public static void launch(final BaseRowItem rowItem, ItemRowAdapter adapter, int pos, final Activity activity, final boolean noHistory) { KoinJavaComponent.get(MediaManager.class).setCurrentMediaAdapter(adapter); - switch (rowItem.getItemType()) { + switch (rowItem.getBaseRowType()) { case BaseItem: final BaseItemDto baseItem = rowItem.getBaseItem(); @@ -251,7 +251,7 @@ public void onResponse(List response) { case Person: //Start details fragment Intent intent = new Intent(activity, FullDetailsActivity.class); - intent.putExtra("ItemId", rowItem.getPerson().getId().toString()); + intent.putExtra("ItemId", rowItem.getBasePerson().getId().toString()); if (noHistory) { intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); } @@ -319,7 +319,7 @@ public void onError(Exception exception) { }); break; case LiveTvProgram: - BaseItemDto program = rowItem.getProgramInfo(); + BaseItemDto program = rowItem.getBaseItem(); switch (rowItem.getSelectAction()) { case ShowDetails: @@ -385,14 +385,14 @@ public void onResponse(List response) { case ShowDetails: //Start details fragment for display and playback Intent recIntent = new Intent(activity, FullDetailsActivity.class); - recIntent.putExtra("ItemId", rowItem.getRecordingInfo().getId()); + recIntent.putExtra("ItemId", rowItem.getBaseItem().getId()); activity.startActivity(recIntent); break; case Play: - if (rowItem.getRecordingInfo().getPlayAccess() == PlayAccess.Full) { + if (rowItem.getBaseItem().getPlayAccess() == PlayAccess.Full) { //Just play it directly but need to retrieve as base item - KoinJavaComponent.get(ApiClient.class).GetItemAsync(rowItem.getRecordingInfo().getId(), KoinJavaComponent.get(UserRepository.class).getCurrentUser().getValue().getId().toString(), new Response() { + KoinJavaComponent.get(ApiClient.class).GetItemAsync(rowItem.getBaseItem().getId(), KoinJavaComponent.get(UserRepository.class).getCurrentUser().getValue().getId().toString(), new Response() { @Override public void onResponse(BaseItemDto response) { Class newActivity = KoinJavaComponent.get(PlaybackLauncher.class).getPlaybackActivityClass(rowItem.getBaseItemType()); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemRowAdapter.java b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemRowAdapter.java index a2e09283e0..138859a65d 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemRowAdapter.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/itemhandling/ItemRowAdapter.java @@ -1348,7 +1348,7 @@ public void onResponse(BaseItemDto[] response) { } for (BaseItemDto item : response) { item.setName(context.getString(R.string.lbl_trailer) + (i + 1)); - adapter.add(new BaseRowItem(i++, item, preferParentThumb, false, BaseRowItem.SelectAction.Play)); + adapter.add(new BaseRowItem(i++, item, preferParentThumb, false, BaseRowItemSelectAction.Play)); } totalItems = response.length; setItemsLoaded(itemsLoaded + i); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java index 63bd23c836..9160e10800 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/CustomPlaybackOverlayFragment.java @@ -382,7 +382,7 @@ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof BaseRowItem) { BaseRowItem rowItem = (BaseRowItem) item; - switch (rowItem.getItemType()) { + switch (rowItem.getBaseRowType()) { case Chapter: Long start = rowItem.getChapterInfo().getStartPositionTicks() / 10000; mPlaybackController.seek(start); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/MediaManager.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/MediaManager.java index 4401107e76..ead5efc90f 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/MediaManager.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/MediaManager.java @@ -180,7 +180,7 @@ public void createManagedAudioQueue() { mManagedAudioQueue.Retrieve(); } if (mManagedAudioQueue.size() > 0 && isPlayingAudio()) { - ((BaseRowItem)mManagedAudioQueue.get(0)).setIsPlaying(true); + ((BaseRowItem)mManagedAudioQueue.get(0)).setPlaying(true); } else if (mManagedAudioQueue.size() < 1) { Timber.d("error creating managed audio queue from size of: %s", mCurrentAudioQueue.size()); } @@ -868,11 +868,11 @@ public void updateCurrentAudioItemPlaying(boolean playing) { if (mCurrentAudioQueuePosition < 0) return; BaseRowItem rowItem = (BaseRowItem) mCurrentAudioQueue.get(mCurrentAudioQueuePosition); if (rowItem != null) { - rowItem.setIsPlaying(playing); + rowItem.setPlaying(playing); mCurrentAudioQueue.notifyItemRangeChanged(mCurrentAudioQueuePosition, 1); if (mManagedAudioQueue != null && mManagedAudioQueue.size() > 0) { BaseRowItem managedItem = (BaseRowItem) mManagedAudioQueue.get(0); - managedItem.setIsPlaying(playing); + managedItem.setPlaying(playing); mManagedAudioQueue.notifyItemRangeChanged(0, 1); } } diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/presentation/CardPresenter.java b/app/src/main/java/org/jellyfin/androidtv/ui/presentation/CardPresenter.java index 6b6e77c23c..e7de0fa9f2 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/presentation/CardPresenter.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/presentation/CardPresenter.java @@ -97,7 +97,7 @@ public void setItem(BaseRowItem m) { public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight, int sHeight) { mItem = m; isUserView = false; - switch (mItem.getItemType()) { + switch (mItem.getBaseRowType()) { case BaseItem: BaseItemDto itemDto = mItem.getBaseItem(); @@ -193,7 +193,7 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight aspect = ImageUtils.ASPECT_RATIO_2_3; break; } - cardHeight = !m.isStaticHeight() ? (aspect > 1 ? lHeight : pHeight) : sHeight; + cardHeight = !m.getStaticHeight() ? (aspect > 1 ? lHeight : pHeight) : sHeight; cardWidth = (int) (aspect * cardHeight); if (cardWidth < 10) { cardWidth = 230; //Guard against zero size images causing picasso to barf @@ -233,7 +233,7 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight double tvAspect = imageType.equals(ImageType.BANNER) ? ASPECT_RATIO_BANNER : imageType.equals(ImageType.THUMB) ? ImageUtils.ASPECT_RATIO_16_9 : Utils.getSafeValue(channel.getPrimaryImageAspectRatio(), 1.0); - cardHeight = !m.isStaticHeight() ? tvAspect > 1 ? lHeight : pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? tvAspect > 1 ? lHeight : pHeight : sHeight; cardWidth = (int) ((tvAspect) * cardHeight); if (cardWidth < 10) { cardWidth = 230; //Guard against zero size images causing picasso to barf @@ -244,7 +244,7 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_tv); break; case LiveTvProgram: - BaseItemDto program = mItem.getProgramInfo(); + BaseItemDto program = mItem.getBaseItem(); Double programAspect = program.getPrimaryImageAspectRatio(); if (Utils.isTrue(program.getIsMovie())) { // The server reports the incorrect image aspect ratio for movies, so we are overriding it here @@ -252,7 +252,7 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight } else if (programAspect == null) { programAspect = ImageUtils.ASPECT_RATIO_16_9; } - cardHeight = !m.isStaticHeight() ? programAspect > 1 ? lHeight : pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? programAspect > 1 ? lHeight : pHeight : sHeight; cardWidth = (int) ((programAspect) * cardHeight); if (cardWidth < 10) { cardWidth = 230; //Guard against zero size images causing picasso to barf @@ -274,9 +274,9 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight mCardView.setCardType(BaseCardView.CARD_TYPE_INFO_UNDER); break; case LiveTvRecording: - BaseItemDto recording = mItem.getRecordingInfo(); + BaseItemDto recording = mItem.getBaseItem(); double recordingAspect = imageType.equals(ImageType.BANNER) ? ASPECT_RATIO_BANNER : (imageType.equals(ImageType.THUMB) ? ImageUtils.ASPECT_RATIO_16_9 : Utils.getSafeValue(recording.getPrimaryImageAspectRatio(), ImageUtils.ASPECT_RATIO_7_9)); - cardHeight = !m.isStaticHeight() ? recordingAspect > 1 ? lHeight : pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? recordingAspect > 1 ? lHeight : pHeight : sHeight; cardWidth = (int) ((recordingAspect) * cardHeight); if (cardWidth < 10) { cardWidth = 230; //Guard against zero size images causing picasso to barf @@ -285,13 +285,13 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_port_tv); break; case Person: - cardHeight = !m.isStaticHeight() ? pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? pHeight : sHeight; cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight); mCardView.setMainImageDimensions(cardWidth, cardHeight); mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_port_person); break; case Chapter: - cardHeight = !m.isStaticHeight() ? pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? pHeight : sHeight; cardWidth = (int) (ImageUtils.ASPECT_RATIO_16_9 * cardHeight); mCardView.setMainImageDimensions(cardWidth, cardHeight); mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_chapter); @@ -316,13 +316,13 @@ public void setItem(BaseRowItem m, ImageType imageType, int lHeight, int pHeight } break; case GridButton: - cardHeight = !m.isStaticHeight() ? pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? pHeight : sHeight; cardWidth = (int) (ImageUtils.ASPECT_RATIO_7_9 * cardHeight); mCardView.setMainImageDimensions(cardWidth, cardHeight); mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_port_video); break; case SeriesTimer: - cardHeight = !m.isStaticHeight() ? pHeight : sHeight; + cardHeight = !m.getStaticHeight() ? pHeight : sHeight; cardWidth = (int) (ImageUtils.ASPECT_RATIO_16_9 * cardHeight); mCardView.setMainImageDimensions(cardWidth, cardHeight); mDefaultCardImage = ContextCompat.getDrawable(mCardView.getContext(), R.drawable.tile_land_series_timer); @@ -372,9 +372,6 @@ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { return; } BaseRowItem rowItem = (BaseRowItem) item; - if (!rowItem.isValid()) { - return; - } ViewHolder holder = (ViewHolder) viewHolder; holder.setItem(rowItem, mImageType, 260, 300, mStaticHeight); @@ -385,7 +382,7 @@ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { holder.mCardView.setOverlayInfo(rowItem); } holder.mCardView.showFavIcon(rowItem.isFavorite()); - if (rowItem.isPlaying()) { + if (rowItem.getPlaying()) { holder.mCardView.setPlayingIndicator(true); } else { holder.mCardView.setPlayingIndicator(false); diff --git a/app/src/main/java/org/jellyfin/androidtv/util/InfoLayoutHelper.java b/app/src/main/java/org/jellyfin/androidtv/util/InfoLayoutHelper.java index 85175cb197..e5c72ea8ed 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/InfoLayoutHelper.java +++ b/app/src/main/java/org/jellyfin/androidtv/util/InfoLayoutHelper.java @@ -36,7 +36,7 @@ public class InfoLayoutHelper { private static NumberFormat nfp = NumberFormat.getPercentInstance(); public static void addInfoRow(Context context, BaseRowItem item, LinearLayout layout, boolean includeRuntime, boolean includeEndtime) { - switch (item.getItemType()) { + switch (item.getBaseRowType()) { case BaseItem: addInfoRow(context, ModelCompat.asSdk(item.getBaseItem()), layout, includeRuntime, includeEndtime); diff --git a/app/src/main/java/org/jellyfin/androidtv/util/KeyProcessor.java b/app/src/main/java/org/jellyfin/androidtv/util/KeyProcessor.java index 15db12a0e5..670e861c9c 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/KeyProcessor.java +++ b/app/src/main/java/org/jellyfin/androidtv/util/KeyProcessor.java @@ -16,6 +16,7 @@ import org.jellyfin.androidtv.ui.itemdetail.PhotoPlayerActivity; import org.jellyfin.androidtv.ui.itemhandling.AudioQueueItem; import org.jellyfin.androidtv.ui.itemhandling.BaseRowItem; +import org.jellyfin.androidtv.ui.itemhandling.BaseRowType; import org.jellyfin.androidtv.ui.playback.AudioNowPlayingActivity; import org.jellyfin.androidtv.ui.playback.MediaManager; import org.jellyfin.androidtv.ui.shared.BaseActivity; @@ -65,12 +66,12 @@ public static boolean HandleKey(int key, BaseRowItem rowItem, Activity activity) switch (key) { case KeyEvent.KEYCODE_MEDIA_PLAY: case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - if (KoinJavaComponent.get(MediaManager.class).isPlayingAudio() && (!rowItem.isBaseItem() || rowItem.getBaseItemType() != BaseItemKind.PHOTO)) { + if (KoinJavaComponent.get(MediaManager.class).isPlayingAudio() && (rowItem.getBaseRowType() != BaseRowType.BaseItem || rowItem.getBaseItemType() != BaseItemKind.PHOTO)) { KoinJavaComponent.get(MediaManager.class).pauseAudio(); return true; } - switch (rowItem.getItemType()) { + switch (rowItem.getBaseRowType()) { case BaseItem: BaseItemDto item = ModelCompat.asSdk(rowItem.getBaseItem()); @@ -139,7 +140,7 @@ public static boolean HandleKey(int key, BaseRowItem rowItem, Activity activity) return true; case LiveTvProgram: // retrieve channel this program belongs to and play - PlaybackHelper.retrieveAndPlay(rowItem.getProgramInfo().getChannelId(), false, activity); + PlaybackHelper.retrieveAndPlay(rowItem.getBaseItem().getChannelId(), false, activity); return true; case GridButton: break; @@ -156,7 +157,7 @@ public static boolean HandleKey(int key, BaseRowItem rowItem, Activity activity) Timber.d("Menu for: %s", rowItem.getFullName(activity)); //Create a contextual menu based on item - switch (rowItem.getItemType()) { + switch (rowItem.getBaseRowType()) { case BaseItem: BaseItemDto item = ModelCompat.asSdk(rowItem.getBaseItem());