Skip to content

Commit

Permalink
Add support for retrieving resume items in BaseRowAdapter using the SDK
Browse files Browse the repository at this point in the history
(cherry picked from commit 1d44c83)
  • Loading branch information
nielsvanvelzen committed Apr 30, 2023
1 parent e2ede5b commit b2b60bf
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ enum class QueryType {
LatestItems,
SeriesTimer,
Premieres,
Resume,
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.jellyfin.apiclient.model.querying.SeasonQuery;
import org.jellyfin.apiclient.model.querying.SimilarItemsQuery;
import org.jellyfin.apiclient.model.querying.UpcomingEpisodesQuery;
import org.jellyfin.sdk.model.api.request.GetResumeItemsRequest;

public class BrowseRowDef {
private String headerText;
Expand All @@ -33,6 +34,7 @@ public class BrowseRowDef {

private ArtistsQuery artistsQuery;
private SeasonQuery seasonQuery;
private GetResumeItemsRequest resumeQuery;
private QueryType queryType;

private int chunkSize = 0;
Expand Down Expand Up @@ -174,6 +176,16 @@ public BrowseRowDef(String header, ViewQuery query) {
this.queryType = QueryType.Views;
}

public BrowseRowDef(String header, GetResumeItemsRequest query, int chunkSize, boolean preferParentThumb, boolean staticHeight, ChangeTriggerType[] changeTriggers) {
headerText = header;
this.resumeQuery = query;
this.chunkSize = chunkSize;
this.queryType = QueryType.Resume;
this.staticHeight = staticHeight;
this.preferParentThumb = preferParentThumb;
this.changeTriggers = changeTriggers;
}

public int getChunkSize() {
return chunkSize;
}
Expand Down Expand Up @@ -230,6 +242,8 @@ public PersonsQuery getPersonsQuery() {

public SeriesTimerQuery getSeriesTimerQuery() { return seriesTimerQuery; }

public GetResumeItemsRequest getResumeQuery() { return resumeQuery; }

public ChangeTriggerType[] getChangeTriggers() {
return changeTriggers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class HomeFragmentBrowseRowDefRow(
QueryType.LiveTvChannel -> ItemRowAdapter(context, browseRowDef.tvChannelQuery, 40, cardPresenter, rowsAdapter)
QueryType.LiveTvProgram -> ItemRowAdapter(context, browseRowDef.programQuery, cardPresenter, rowsAdapter)
QueryType.LiveTvRecording -> ItemRowAdapter(context, browseRowDef.recordingQuery, browseRowDef.chunkSize, cardPresenter, rowsAdapter)
QueryType.Resume -> ItemRowAdapter(context, browseRowDef.resumeQuery, browseRowDef.chunkSize, browseRowDef.preferParentThumb, browseRowDef.isStaticHeight, cardPresenter, rowsAdapter)
else -> ItemRowAdapter(context, browseRowDef.query, browseRowDef.chunkSize, browseRowDef.preferParentThumb, browseRowDef.isStaticHeight, cardPresenter, rowsAdapter, browseRowDef.queryType)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import android.content.Context
import org.jellyfin.androidtv.R
import org.jellyfin.androidtv.auth.repository.UserRepository
import org.jellyfin.androidtv.constant.ChangeTriggerType
import org.jellyfin.androidtv.data.querying.StdItemQuery
import org.jellyfin.androidtv.data.querying.ViewQuery
import org.jellyfin.androidtv.data.repository.UserViewsRepository
import org.jellyfin.androidtv.ui.browsing.BrowseRowDef
import org.jellyfin.apiclient.model.entities.LocationType
import org.jellyfin.apiclient.model.entities.SortOrder
import org.jellyfin.apiclient.model.livetv.RecommendedProgramQuery
import org.jellyfin.apiclient.model.livetv.RecordingQuery
import org.jellyfin.apiclient.model.querying.ItemFields
import org.jellyfin.apiclient.model.querying.ItemFilter
import org.jellyfin.apiclient.model.querying.NextUpQuery
import org.jellyfin.sdk.model.constant.ItemSortBy
import org.jellyfin.sdk.model.api.request.GetResumeItemsRequest
import org.jellyfin.sdk.model.constant.MediaType
import org.jellyfin.sdk.model.api.ItemFields as SdkItemFields

class HomeFragmentHelper(
private val context: Context,
Expand All @@ -31,29 +28,31 @@ class HomeFragmentHelper(
return HomeFragmentBrowseRowDefRow(BrowseRowDef(context.getString(R.string.lbl_my_media), ViewQuery))
}

fun loadResume(title: String, includeMediaTypes: Array<String>): HomeFragmentRow {
val query = StdItemQuery().apply {
mediaTypes = includeMediaTypes
recursive = true
imageTypeLimit = 1
enableTotalRecordCount = false
collapseBoxSetItems = false
excludeLocationTypes = arrayOf(LocationType.Virtual)
limit = ITEM_LIMIT_RESUME
filters = arrayOf(ItemFilter.IsResumable)
sortBy = arrayOf(ItemSortBy.DatePlayed)
sortOrder = SortOrder.Descending
}
fun loadResume(title: String, includeMediaTypes: List<String>): HomeFragmentRow {
val query = GetResumeItemsRequest(
userId = userRepository.currentUser.value!!.id,
limit = ITEM_LIMIT_RESUME,
fields = listOf(
SdkItemFields.PRIMARY_IMAGE_ASPECT_RATIO,
SdkItemFields.OVERVIEW,
SdkItemFields.ITEM_COUNTS,
SdkItemFields.DISPLAY_PREFERENCES_ID,
SdkItemFields.CHILD_COUNT,
),
imageTypeLimit = 1,
enableTotalRecordCount = false,
mediaTypes = includeMediaTypes,
)

return HomeFragmentBrowseRowDefRow(BrowseRowDef(title, query, 0, false, true, arrayOf(ChangeTriggerType.VideoQueueChange, ChangeTriggerType.TvPlayback, ChangeTriggerType.MoviePlayback)))
}

fun loadResumeVideo(): HomeFragmentRow {
return loadResume(context.getString(R.string.lbl_continue_watching), arrayOf(MediaType.Video))
return loadResume(context.getString(R.string.lbl_continue_watching), listOf(MediaType.Video))
}

fun loadResumeAudio(): HomeFragmentRow {
return loadResume(context.getString(R.string.lbl_continue_watching), arrayOf(MediaType.Audio))
return loadResume(context.getString(R.string.lbl_continue_watching), listOf(MediaType.Audio))
}

fun loadLatestLiveTvRecordings(): HomeFragmentRow {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,16 @@ open class BaseRowItem protected constructor(
baseItem = item.asSdk(),
)

constructor(item: org.jellyfin.sdk.model.api.BaseItemDto) : this(
@JvmOverloads
constructor(
item: org.jellyfin.sdk.model.api.BaseItemDto,
index: Int = 0,
preferParentThumb: Boolean = false,
staticHeight: Boolean = false,
) : this(
index = index,
preferParentThumb = preferParentThumb,
staticHeight = staticHeight,
baseRowType = when (item.type) {
BaseItemKind.PROGRAM -> BaseRowType.LiveTvProgram
BaseItemKind.RECORDING -> BaseRowType.LiveTvRecording
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.jellyfin.sdk.model.api.BaseItemPerson;
import org.jellyfin.sdk.model.api.SortOrder;
import org.jellyfin.sdk.model.api.UserDto;
import org.jellyfin.sdk.model.api.request.GetResumeItemsRequest;
import org.jellyfin.sdk.model.constant.ItemSortBy;
import org.koin.java.KoinJavaComponent;

Expand Down Expand Up @@ -90,6 +91,7 @@ public class ItemRowAdapter extends MutableObjectAdapter<Object> {
private ArtistsQuery mArtistsQuery;
private LatestItemsQuery mLatestQuery;
private SeriesTimerQuery mSeriesTimerQuery;
private GetResumeItemsRequest resumeQuery;
private QueryType queryType;

private String mSortBy;
Expand Down Expand Up @@ -120,6 +122,7 @@ public class ItemRowAdapter extends MutableObjectAdapter<Object> {
private boolean staticHeight = false;

private final Lazy<ApiClient> apiClient = inject(ApiClient.class);
private final Lazy<org.jellyfin.sdk.api.client.ApiClient> api = inject(org.jellyfin.sdk.api.client.ApiClient.class);
private final Lazy<UserViewsRepository> userViewsRepository = inject(UserViewsRepository.class);
private Context context;

Expand Down Expand Up @@ -388,6 +391,17 @@ public ItemRowAdapter(Context context, ViewQuery query, Presenter presenter, Mut
staticHeight = true;
}

public ItemRowAdapter(Context context, GetResumeItemsRequest query, int chunkSize, boolean preferParentThumb, boolean staticHeight, Presenter presenter, MutableObjectAdapter<Row> parent) {
super(presenter);
this.context = context;
mParent = parent;
resumeQuery = query;
this.chunkSize = chunkSize;
this.preferParentThumb = preferParentThumb;
this.staticHeight = staticHeight;
this.queryType = QueryType.Resume;
}

public void setItemsLoaded(int itemsLoaded) {
this.itemsLoaded = itemsLoaded;
this.fullyLoaded = chunkSize == 0 || itemsLoaded >= totalItems;
Expand Down Expand Up @@ -707,6 +721,9 @@ public void Retrieve() {
case SeriesTimer:
retrieve(mSeriesTimerQuery);
break;
case Resume:
ItemRowAdapterHelperKt.retrieveResumeItems(this, api.getValue(), resumeQuery);
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package org.jellyfin.androidtv.ui.itemhandling

import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.itemsApi
import org.jellyfin.sdk.model.api.request.GetResumeItemsRequest
import timber.log.Timber

fun <T : Any> ItemRowAdapter.setItems(
Expand Down Expand Up @@ -29,3 +35,13 @@ fun <T : Any> ItemRowAdapter.setItems(
replaceAll(allItems)
itemsLoaded = allItems.size
}

fun ItemRowAdapter.retrieveResumeItems(api: ApiClient, query: GetResumeItemsRequest) {
ProcessLifecycleOwner.get().lifecycleScope.launch {
val response by api.itemsApi.getResumeItems(query)

setItems(
items = response.items.orEmpty().toTypedArray(),
transform = { item, i -> BaseRowItem(item, i, preferParentThumb, isStaticHeight) })
}
}

0 comments on commit b2b60bf

Please sign in to comment.