mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Show season extras row on series overview (#1286)
## Description Adds a row for season level extras on the series overview page below the people rows. The extras will update when switching between season tabs. Like elsewhere in the app, an single extra of a type is show inline and multiple extras of the same type open a grid when clicked. ### Related issues Closes #504 ### Testing Emulator ## Screenshots <img width="1280" height="720" alt="season_extras Large" src="https://github.com/user-attachments/assets/bc62bef4-66c8-4412-9eca-ec0105d0d0fa" /> ## AI or LLM usage None
This commit is contained in:
parent
8f98526558
commit
c9cab7a5c2
3 changed files with 41 additions and 3 deletions
|
|
@ -98,13 +98,15 @@ fun SeriesOverview(
|
|||
val episodeRowFocusRequester = remember { FocusRequester() }
|
||||
val castCrewRowFocusRequester = remember { FocusRequester() }
|
||||
val guestStarRowFocusRequester = remember { FocusRequester() }
|
||||
val extrasRowFocusRequester = remember { FocusRequester() }
|
||||
|
||||
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
|
||||
|
||||
val series by viewModel.item.observeAsState(null)
|
||||
val seasons by viewModel.seasons.observeAsState(listOf())
|
||||
val seasons by viewModel.seasons.observeAsState(emptyList())
|
||||
val episodes by viewModel.episodes.observeAsState(EpisodeList.Loading)
|
||||
val peopleInEpisode by viewModel.peopleInEpisode.map { it.people }.observeAsState(listOf())
|
||||
val seasonExtras by viewModel.extras.observeAsState(emptyList())
|
||||
val peopleInEpisode by viewModel.peopleInEpisode.map { it.people }.observeAsState(emptyList())
|
||||
val episodeList = (episodes as? EpisodeList.Success)?.episodes
|
||||
|
||||
val position by viewModel.position.collectAsState(SeriesOverviewPosition(0, 0))
|
||||
|
|
@ -164,6 +166,7 @@ fun SeriesOverview(
|
|||
EPISODE_ROW -> episodeRowFocusRequester
|
||||
CAST_AND_CREW_ROW -> castCrewRowFocusRequester
|
||||
GUEST_STAR_ROW -> guestStarRowFocusRequester
|
||||
EXTRAS_ROW -> extrasRowFocusRequester
|
||||
else -> episodeRowFocusRequester
|
||||
},
|
||||
"series_overview",
|
||||
|
|
@ -280,11 +283,13 @@ fun SeriesOverview(
|
|||
episodes = episodes,
|
||||
chosenStreams = chosenStreams,
|
||||
peopleInEpisode = peopleInEpisode,
|
||||
seasonExtras = seasonExtras,
|
||||
position = position,
|
||||
firstItemFocusRequester = firstItemFocusRequester,
|
||||
episodeRowFocusRequester = episodeRowFocusRequester,
|
||||
castCrewRowFocusRequester = castCrewRowFocusRequester,
|
||||
guestStarRowFocusRequester = guestStarRowFocusRequester,
|
||||
extrasRowFocusRequester = extrasRowFocusRequester,
|
||||
onChangeSeason = { index ->
|
||||
if (index != position.seasonTabIndex) {
|
||||
seasons.getOrNull(index)?.let { season ->
|
||||
|
|
@ -364,6 +369,10 @@ fun SeriesOverview(
|
|||
),
|
||||
)
|
||||
},
|
||||
onClickExtra = { _, extra ->
|
||||
rowFocused = EXTRAS_ROW
|
||||
viewModel.navigateTo(extra.destination)
|
||||
},
|
||||
canDelete = { viewModel.canDelete(it, preferences.appPreferences) },
|
||||
deleteOnClick = { showDeleteDialog = it },
|
||||
modifier = modifier,
|
||||
|
|
@ -435,3 +444,4 @@ fun SeriesOverview(
|
|||
private const val EPISODE_ROW = 0
|
||||
private const val CAST_AND_CREW_ROW = EPISODE_ROW + 1
|
||||
private const val GUEST_STAR_ROW = CAST_AND_CREW_ROW + 1
|
||||
private const val EXTRAS_ROW = GUEST_STAR_ROW + 1
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import androidx.compose.runtime.rememberUpdatedState
|
|||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.focusRestorer
|
||||
|
|
@ -47,11 +46,13 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.github.damontecres.wholphin.R
|
||||
import com.github.damontecres.wholphin.data.ChosenStreams
|
||||
import com.github.damontecres.wholphin.data.ExtrasItem
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.data.model.Person
|
||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||
import com.github.damontecres.wholphin.ui.cards.BannerCard
|
||||
import com.github.damontecres.wholphin.ui.cards.ExtrasRow
|
||||
import com.github.damontecres.wholphin.ui.cards.PersonRow
|
||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||
import com.github.damontecres.wholphin.ui.components.HeaderUtils
|
||||
|
|
@ -74,6 +75,7 @@ fun SeriesOverviewContent(
|
|||
series: BaseItem,
|
||||
seasons: List<BaseItem?>,
|
||||
episodes: EpisodeList,
|
||||
seasonExtras: List<ExtrasItem>,
|
||||
chosenStreams: ChosenStreams?,
|
||||
peopleInEpisode: List<Person>,
|
||||
position: SeriesOverviewPosition,
|
||||
|
|
@ -81,6 +83,7 @@ fun SeriesOverviewContent(
|
|||
episodeRowFocusRequester: FocusRequester,
|
||||
castCrewRowFocusRequester: FocusRequester,
|
||||
guestStarRowFocusRequester: FocusRequester,
|
||||
extrasRowFocusRequester: FocusRequester,
|
||||
onChangeSeason: (Int) -> Unit,
|
||||
onFocusEpisode: (Int) -> Unit,
|
||||
onClick: (BaseItem) -> Unit,
|
||||
|
|
@ -93,6 +96,7 @@ fun SeriesOverviewContent(
|
|||
personOnClick: (Person) -> Unit,
|
||||
canDelete: (BaseItem) -> Boolean,
|
||||
deleteOnClick: (BaseItem) -> Unit,
|
||||
onClickExtra: (Int, ExtrasItem) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
|
@ -365,6 +369,21 @@ fun SeriesOverviewContent(
|
|||
}
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = seasonExtras.isNotEmpty(),
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
) {
|
||||
ExtrasRow(
|
||||
extras = seasonExtras,
|
||||
onClickItem = onClickExtra,
|
||||
onLongClickItem = { _, _ -> },
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(extrasRowFocusRequester),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,6 +184,10 @@ class SeriesViewModel
|
|||
it.copy(seasonTabIndex = index.coerceAtLeast(0))
|
||||
}
|
||||
}
|
||||
viewModelScope.launchIO {
|
||||
val extras = extrasService.getExtras(seasonEpisodeIds.seasonId)
|
||||
this@SeriesViewModel.extras.setValueOnMain(extras)
|
||||
}
|
||||
}
|
||||
val remoteTrailers = trailerService.getRemoteTrailers(item)
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -388,6 +392,7 @@ class SeriesViewModel
|
|||
if (currentEpisodes == null || currentEpisodes.seasonId != seasonId) {
|
||||
this@SeriesViewModel.peopleInEpisode.value = PeopleInItem()
|
||||
this@SeriesViewModel.episodes.value = EpisodeList.Loading
|
||||
this@SeriesViewModel.extras.value = emptyList()
|
||||
}
|
||||
viewModelScope.launchIO(ExceptionHandler(true)) {
|
||||
val episodes =
|
||||
|
|
@ -401,6 +406,10 @@ class SeriesViewModel
|
|||
this@SeriesViewModel.episodes.value = episodes
|
||||
}
|
||||
}
|
||||
viewModelScope.launchIO {
|
||||
val extras = extrasService.getExtras(seasonId)
|
||||
this@SeriesViewModel.extras.setValueOnMain(extras)
|
||||
}
|
||||
}
|
||||
|
||||
fun setWatched(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue