Fix showing live tv programs on home page (#1504)

## Description
Fixes the inconsistent live tv programs shown on the home page by using
a different API endpoint & filtering.

Also some UI fixes:
- Use the "Watch live" string consistently for the row instead of it
sometimes switching to "Live TV"
- Adjust the "Ends at" in the home page header to show the actual end
time
- Show the channel name in "quick details"
- Show season & episode number, if applicable, in "quick details"

### Related issues
Fixes #1080

### Testing
Nvidia shield w/ fake EPG data

## Screenshots
N/A, just UI fixes, nothing new

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-06-03 12:40:53 -04:00 • committed by GitHub
parent 6c64470c28
commit 5ae452155e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 88 additions and 25 deletions

View file

@ -13,6 +13,7 @@ import com.github.damontecres.wholphin.data.model.createStudioDestination
import com.github.damontecres.wholphin.preferences.DefaultUserConfiguration
import com.github.damontecres.wholphin.preferences.HomePagePreferences
import com.github.damontecres.wholphin.ui.DefaultItemFields
import com.github.damontecres.wholphin.ui.ProgramItemFields
import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.components.getGenreImageMap
import com.github.damontecres.wholphin.ui.main.settings.Library
@ -30,6 +31,7 @@ import com.github.damontecres.wholphin.util.GetGenresRequestHandler
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
import com.github.damontecres.wholphin.util.GetLiveTvChannelsRequestHandler
import com.github.damontecres.wholphin.util.GetPersonsHandler
import com.github.damontecres.wholphin.util.GetProgramsDtoHandler
import com.github.damontecres.wholphin.util.GetRecordingsRequestHandler
import com.github.damontecres.wholphin.util.GetStudiosRequestHandler
import com.github.damontecres.wholphin.util.HomeRowLoadingState
@ -54,9 +56,11 @@ import org.jellyfin.sdk.api.client.extensions.liveTvApi
import org.jellyfin.sdk.api.client.extensions.userApi
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
import org.jellyfin.sdk.api.client.extensions.userViewsApi
import org.jellyfin.sdk.model.DateTime
import org.jellyfin.sdk.model.UUID
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.GetProgramsDto
import org.jellyfin.sdk.model.api.ImageType
import org.jellyfin.sdk.model.api.ItemSortBy
import org.jellyfin.sdk.model.api.SortOrder
@ -66,7 +70,6 @@ import org.jellyfin.sdk.model.api.request.GetItemsRequest
import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest
import org.jellyfin.sdk.model.api.request.GetLiveTvChannelsRequest
import org.jellyfin.sdk.model.api.request.GetPersonsRequest
import org.jellyfin.sdk.model.api.request.GetRecommendedProgramsRequest
import org.jellyfin.sdk.model.api.request.GetRecordingsRequest
import org.jellyfin.sdk.model.api.request.GetStudiosRequest
import timber.log.Timber
@ -281,7 +284,7 @@ class HomeSettingsService
if (it.collectionType == CollectionType.LIVETV) {
HomeRowConfigDisplay(
id = index,
title = ResStringProvider(R.string.live_tv),
title = ResStringProvider(R.string.watch_live),
config = HomeRowConfig.TvPrograms(),
)
} else {
@ -367,7 +370,7 @@ class HomeSettingsService
if (userDto.tvAccess) {
HomeRowConfigDisplay(
id = id++,
title = ResStringProvider(R.string.live_tv),
title = ResStringProvider(R.string.watch_live),
config = HomeRowConfig.TvPrograms(),
)
} else {
@ -520,7 +523,7 @@ class HomeSettingsService
is HomeRowConfig.TvPrograms -> {
HomeRowConfigDisplay(
id = id,
title = ResStringProvider(R.string.live_tv),
title = ResStringProvider(R.string.watch_live),
config,
)
}
@ -1037,29 +1040,39 @@ class HomeSettingsService
is HomeRowConfig.TvPrograms -> {
val request =
GetRecommendedProgramsRequest(
GetProgramsDto(
userId = userDto.id,
fields = DefaultItemFields,
fields = ProgramItemFields,
limit = limit,
enableUserData = true,
enableImages = true,
enableImageTypes = listOf(ImageType.PRIMARY, ImageType.LOGO),
imageTypeLimit = 1,
isAiring = true,
minEndDate = DateTime.now().plusMinutes(1),
)
// paging not supported
api.liveTvApi
.getRecommendedPrograms(request)
.content.items
.map { BaseItem(it, row.viewOptions.useSeries) }
.let {
Success(
ResStringProvider(R.string.live_tv),
it,
row.viewOptions,
rowType = row,
showViewMore = it.size >= limit,
)
}
if (usePaging) {
ApiRequestPager(
api,
request,
GetProgramsDtoHandler,
scope,
useSeriesForPrimary = row.viewOptions.useSeries,
).init()
} else {
api.liveTvApi
.getPrograms(request)
.content.items
.map { BaseItem(it, row.viewOptions.useSeries) }
}.let {
Success(
ResStringProvider(R.string.watch_live),
it,
row.viewOptions,
rowType = row,
showViewMore = it.size >= limit,
)
}
}
is HomeRowConfig.TvChannels -> {