mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-23 19:26:50 +00:00
refactor: simplify navigation
This commit is contained in:
@@ -20,9 +20,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
|
||||||
import androidx.compose.ui.focus.focusProperties
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.TransformOrigin
|
import androidx.compose.ui.graphics.TransformOrigin
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
@@ -42,9 +39,6 @@ import org.jellyfin.sdk.model.api.BaseItemKind
|
|||||||
fun PosterCard(
|
fun PosterCard(
|
||||||
item: PosterItem,
|
item: PosterItem,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
focusRequester: FocusRequester? = null,
|
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
onMovieSelected: (UUID) -> Unit,
|
onMovieSelected: (UUID) -> Unit,
|
||||||
onSeriesSelected: (UUID) -> Unit,
|
onSeriesSelected: (UUID) -> Unit,
|
||||||
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
||||||
@@ -67,19 +61,6 @@ fun PosterCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageFocusModifier = Modifier
|
|
||||||
.then(if (focusRequester != null) Modifier.focusRequester(focusRequester) else Modifier)
|
|
||||||
.then(
|
|
||||||
if (upFocusRequester != null || downFocusRequester != null) {
|
|
||||||
Modifier.focusProperties {
|
|
||||||
upFocusRequester?.let { up = it }
|
|
||||||
downFocusRequester?.let { down = it }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Modifier
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.width(posterWidth)
|
.width(posterWidth)
|
||||||
@@ -93,7 +74,7 @@ fun PosterCard(
|
|||||||
PurefinAsyncImage(
|
PurefinAsyncImage(
|
||||||
model = item.imageUrl,
|
model = item.imageUrl,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = imageFocusModifier
|
modifier = Modifier
|
||||||
.aspectRatio(2f / 3f)
|
.aspectRatio(2f / 3f)
|
||||||
.clip(RoundedCornerShape(14.dp))
|
.clip(RoundedCornerShape(14.dp))
|
||||||
.border(
|
.border(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package hu.bbara.purefin.tv.home.ui
|
package hu.bbara.purefin.tv.home.ui
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -8,10 +9,13 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory.component1
|
||||||
|
import androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory.component2
|
||||||
|
import androidx.compose.ui.focus.focusProperties
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
|
import hu.bbara.purefin.feature.shared.home.ContinueWatchingItem
|
||||||
import hu.bbara.purefin.feature.shared.home.LibraryItem
|
import hu.bbara.purefin.feature.shared.home.LibraryItem
|
||||||
@@ -19,6 +23,7 @@ import hu.bbara.purefin.feature.shared.home.NextUpItem
|
|||||||
import hu.bbara.purefin.feature.shared.home.PosterItem
|
import hu.bbara.purefin.feature.shared.home.PosterItem
|
||||||
import org.jellyfin.sdk.model.UUID
|
import org.jellyfin.sdk.model.UUID
|
||||||
|
|
||||||
|
@SuppressLint("RememberInComposition")
|
||||||
@Composable
|
@Composable
|
||||||
fun TvHomeContent(
|
fun TvHomeContent(
|
||||||
libraries: List<LibraryItem>,
|
libraries: List<LibraryItem>,
|
||||||
@@ -33,36 +38,12 @@ fun TvHomeContent(
|
|||||||
val visibleLibraries = remember(libraries, libraryContent) {
|
val visibleLibraries = remember(libraries, libraryContent) {
|
||||||
libraries.filter { libraryContent[it.id]?.isEmpty() != true }
|
libraries.filter { libraryContent[it.id]?.isEmpty() != true }
|
||||||
}
|
}
|
||||||
val continueWatchingSectionFocusRequester = remember { FocusRequester() }
|
|
||||||
val continueWatchingFirstItemFocusRequester = remember { FocusRequester() }
|
val ( nextUpRef, continueWatchingRef ) = remember { FocusRequester.createRefs() }
|
||||||
val nextUpSectionFocusRequester = remember { FocusRequester() }
|
val libraryRefs = remember(libraryContent) {
|
||||||
val nextUpFirstItemFocusRequester = remember { FocusRequester() }
|
libraryContent.keys.associateWith { FocusRequester() }
|
||||||
val librarySectionFocusRequesters = remember(visibleLibraries.map { it.id }) {
|
|
||||||
visibleLibraries.associate { library -> library.id to FocusRequester() }
|
|
||||||
}
|
|
||||||
val libraryFirstItemFocusRequesters = remember(visibleLibraries.map { it.id }) {
|
|
||||||
visibleLibraries.associate { library -> library.id to FocusRequester() }
|
|
||||||
}
|
|
||||||
val firstSectionFocusRequester = when {
|
|
||||||
continueWatching.isNotEmpty() -> continueWatchingSectionFocusRequester
|
|
||||||
nextUp.isNotEmpty() -> nextUpSectionFocusRequester
|
|
||||||
else -> visibleLibraries.firstOrNull()?.let { librarySectionFocusRequesters[it.id] }
|
|
||||||
}
|
|
||||||
val firstVisibleLibrarySectionFocusRequester = visibleLibraries.firstOrNull()
|
|
||||||
?.let { librarySectionFocusRequesters[it.id] }
|
|
||||||
val firstHomeRowBelowContinueWatching = when {
|
|
||||||
nextUp.isNotEmpty() -> nextUpSectionFocusRequester
|
|
||||||
else -> firstVisibleLibrarySectionFocusRequester
|
|
||||||
}
|
|
||||||
val firstHomeRowAboveLibraries = when {
|
|
||||||
nextUp.isNotEmpty() -> nextUpSectionFocusRequester
|
|
||||||
continueWatching.isNotEmpty() -> continueWatchingSectionFocusRequester
|
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(firstSectionFocusRequester) {
|
|
||||||
firstSectionFocusRequester?.requestFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
@@ -75,11 +56,12 @@ fun TvHomeContent(
|
|||||||
item {
|
item {
|
||||||
TvContinueWatchingSection(
|
TvContinueWatchingSection(
|
||||||
items = continueWatching,
|
items = continueWatching,
|
||||||
sectionFocusRequester = continueWatchingSectionFocusRequester,
|
|
||||||
firstItemFocusRequester = continueWatchingFirstItemFocusRequester,
|
|
||||||
downFocusRequester = firstHomeRowBelowContinueWatching,
|
|
||||||
onMovieSelected = onMovieSelected,
|
onMovieSelected = onMovieSelected,
|
||||||
onEpisodeSelected = onEpisodeSelected
|
onEpisodeSelected = onEpisodeSelected,
|
||||||
|
modifier = Modifier.focusRequester(continueWatchingRef)
|
||||||
|
.focusProperties{
|
||||||
|
down = nextUpRef
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
@@ -88,12 +70,12 @@ fun TvHomeContent(
|
|||||||
item {
|
item {
|
||||||
TvNextUpSection(
|
TvNextUpSection(
|
||||||
items = nextUp,
|
items = nextUp,
|
||||||
sectionFocusRequester = nextUpSectionFocusRequester,
|
onEpisodeSelected = onEpisodeSelected,
|
||||||
firstItemFocusRequester = nextUpFirstItemFocusRequester,
|
modifier = Modifier.focusRequester(nextUpRef)
|
||||||
upFocusRequester = continueWatching.takeIf { it.isNotEmpty() }
|
.focusProperties{
|
||||||
?.let { continueWatchingSectionFocusRequester },
|
up = continueWatchingRef
|
||||||
downFocusRequester = firstVisibleLibrarySectionFocusRequester,
|
libraryRefs.values.firstOrNull()?.let { down = it }
|
||||||
onEpisodeSelected = onEpisodeSelected
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
@@ -103,29 +85,19 @@ fun TvHomeContent(
|
|||||||
items = visibleLibraries,
|
items = visibleLibraries,
|
||||||
key = { it.id }
|
key = { it.id }
|
||||||
) { item ->
|
) { item ->
|
||||||
val libraryIndex = visibleLibraries.indexOfFirst { it.id == item.id }
|
val ref = libraryRefs[item.id]
|
||||||
val previousLibrarySectionFocusRequester = visibleLibraries
|
|
||||||
.getOrNull(libraryIndex - 1)
|
|
||||||
?.let { librarySectionFocusRequesters[it.id] }
|
|
||||||
val nextLibrarySectionFocusRequester = visibleLibraries
|
|
||||||
.getOrNull(libraryIndex + 1)
|
|
||||||
?.let { librarySectionFocusRequesters[it.id] }
|
|
||||||
|
|
||||||
TvLibraryPosterSection(
|
TvLibraryPosterSection(
|
||||||
title = item.name,
|
title = item.name,
|
||||||
items = libraryContent[item.id] ?: emptyList(),
|
items = libraryContent[item.id] ?: emptyList(),
|
||||||
action = "See All",
|
action = "See All",
|
||||||
sectionFocusRequester = librarySectionFocusRequesters.getValue(item.id),
|
|
||||||
firstItemFocusRequester = libraryFirstItemFocusRequesters.getValue(item.id),
|
|
||||||
upFocusRequester = if (libraryIndex == 0) {
|
|
||||||
firstHomeRowAboveLibraries
|
|
||||||
} else {
|
|
||||||
previousLibrarySectionFocusRequester
|
|
||||||
},
|
|
||||||
downFocusRequester = nextLibrarySectionFocusRequester,
|
|
||||||
onMovieSelected = onMovieSelected,
|
onMovieSelected = onMovieSelected,
|
||||||
onSeriesSelected = onSeriesSelected,
|
onSeriesSelected = onSeriesSelected,
|
||||||
onEpisodeSelected = onEpisodeSelected
|
onEpisodeSelected = onEpisodeSelected,
|
||||||
|
modifier = if (ref != null) Modifier.focusRequester(ref) else Modifier
|
||||||
|
.focusProperties {
|
||||||
|
up = nextUpRef
|
||||||
|
libraryRefs.values.dropWhile { it != ref }.drop(1).firstOrNull()?.let { down = it }
|
||||||
|
}
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,16 +28,10 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
|
||||||
import androidx.compose.ui.focus.focusProperties
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
|
||||||
import androidx.compose.ui.focus.focusRestorer
|
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.TransformOrigin
|
import androidx.compose.ui.graphics.TransformOrigin
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -55,10 +49,6 @@ import kotlin.math.nextUp
|
|||||||
@Composable
|
@Composable
|
||||||
fun TvContinueWatchingSection(
|
fun TvContinueWatchingSection(
|
||||||
items: List<ContinueWatchingItem>,
|
items: List<ContinueWatchingItem>,
|
||||||
sectionFocusRequester: FocusRequester,
|
|
||||||
firstItemFocusRequester: FocusRequester? = null,
|
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
onMovieSelected: (UUID) -> Unit,
|
onMovieSelected: (UUID) -> Unit,
|
||||||
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
@@ -70,20 +60,15 @@ fun TvContinueWatchingSection(
|
|||||||
)
|
)
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth(),
|
||||||
.focusRequester(sectionFocusRequester)
|
|
||||||
.focusRestorer(firstItemFocusRequester ?: FocusRequester.Default),
|
|
||||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
itemsIndexed(items = items) { index, item ->
|
itemsIndexed(items = items) { index, item ->
|
||||||
TvContinueWatchingCard(
|
TvContinueWatchingCard(
|
||||||
item = item,
|
item = item,
|
||||||
focusRequester = if (index == 0) firstItemFocusRequester else null,
|
|
||||||
isFirstItem = index == 0,
|
isFirstItem = index == 0,
|
||||||
isLastItem = index == items.lastIndex,
|
isLastItem = index == items.lastIndex,
|
||||||
upFocusRequester = upFocusRequester,
|
|
||||||
downFocusRequester = downFocusRequester,
|
|
||||||
onMovieSelected = onMovieSelected,
|
onMovieSelected = onMovieSelected,
|
||||||
onEpisodeSelected = onEpisodeSelected
|
onEpisodeSelected = onEpisodeSelected
|
||||||
)
|
)
|
||||||
@@ -95,18 +80,13 @@ fun TvContinueWatchingSection(
|
|||||||
fun TvContinueWatchingCard(
|
fun TvContinueWatchingCard(
|
||||||
item: ContinueWatchingItem,
|
item: ContinueWatchingItem,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
focusRequester: FocusRequester? = null,
|
|
||||||
isFirstItem: Boolean = false,
|
isFirstItem: Boolean = false,
|
||||||
isLastItem: Boolean = false,
|
isLastItem: Boolean = false,
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
onMovieSelected: (UUID) -> Unit,
|
onMovieSelected: (UUID) -> Unit,
|
||||||
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
||||||
) {
|
) {
|
||||||
val scheme = MaterialTheme.colorScheme
|
val scheme = MaterialTheme.colorScheme
|
||||||
|
|
||||||
val context = LocalContext.current
|
|
||||||
val density = LocalDensity.current
|
|
||||||
var isFocused by remember { mutableStateOf(false) }
|
var isFocused by remember { mutableStateOf(false) }
|
||||||
val scale by animateFloatAsState(targetValue = if (isFocused) 1.07f else 1.0f, label = "scale")
|
val scale by animateFloatAsState(targetValue = if (isFocused) 1.07f else 1.0f, label = "scale")
|
||||||
|
|
||||||
@@ -130,32 +110,6 @@ fun TvContinueWatchingCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageFocusModifier = Modifier
|
|
||||||
.then(if (focusRequester != null) Modifier.focusRequester(focusRequester) else Modifier)
|
|
||||||
.then(
|
|
||||||
if (upFocusRequester != null || downFocusRequester != null) {
|
|
||||||
Modifier.focusProperties {
|
|
||||||
upFocusRequester?.let { up = it }
|
|
||||||
downFocusRequester?.let { down = it }
|
|
||||||
if (isFirstItem) {
|
|
||||||
left = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
if (isLastItem) {
|
|
||||||
right = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Modifier.focusProperties {
|
|
||||||
if (isFirstItem) {
|
|
||||||
left = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
if (isLastItem) {
|
|
||||||
right = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.width(cardWidth)
|
.width(cardWidth)
|
||||||
@@ -181,7 +135,7 @@ fun TvContinueWatchingCard(
|
|||||||
PurefinAsyncImage(
|
PurefinAsyncImage(
|
||||||
model = imageUrl,
|
model = imageUrl,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = imageFocusModifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.onFocusChanged { isFocused = it.isFocused }
|
.onFocusChanged { isFocused = it.isFocused }
|
||||||
.clickable {
|
.clickable {
|
||||||
@@ -220,10 +174,6 @@ fun TvContinueWatchingCard(
|
|||||||
@Composable
|
@Composable
|
||||||
fun TvNextUpSection(
|
fun TvNextUpSection(
|
||||||
items: List<NextUpItem>,
|
items: List<NextUpItem>,
|
||||||
sectionFocusRequester: FocusRequester,
|
|
||||||
firstItemFocusRequester: FocusRequester? = null,
|
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -234,9 +184,7 @@ fun TvNextUpSection(
|
|||||||
)
|
)
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth(),
|
||||||
.focusRequester(sectionFocusRequester)
|
|
||||||
.focusRestorer(firstItemFocusRequester ?: FocusRequester.Default),
|
|
||||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
@@ -246,11 +194,8 @@ fun TvNextUpSection(
|
|||||||
) { index, item ->
|
) { index, item ->
|
||||||
TvNextUpCard(
|
TvNextUpCard(
|
||||||
item = item,
|
item = item,
|
||||||
focusRequester = if (index == 0) firstItemFocusRequester else null,
|
|
||||||
isFirstItem = index == 0,
|
isFirstItem = index == 0,
|
||||||
isLastItem = index == items.lastIndex,
|
isLastItem = index == items.lastIndex,
|
||||||
upFocusRequester = upFocusRequester,
|
|
||||||
downFocusRequester = downFocusRequester,
|
|
||||||
onEpisodeSelected = onEpisodeSelected
|
onEpisodeSelected = onEpisodeSelected
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -261,11 +206,8 @@ fun TvNextUpSection(
|
|||||||
fun TvNextUpCard(
|
fun TvNextUpCard(
|
||||||
item: NextUpItem,
|
item: NextUpItem,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
focusRequester: FocusRequester? = null,
|
|
||||||
isFirstItem: Boolean = false,
|
isFirstItem: Boolean = false,
|
||||||
isLastItem: Boolean = false,
|
isLastItem: Boolean = false,
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
onEpisodeSelected: (UUID, UUID, UUID) -> Unit,
|
||||||
) {
|
) {
|
||||||
val scheme = MaterialTheme.colorScheme
|
val scheme = MaterialTheme.colorScheme
|
||||||
@@ -282,32 +224,6 @@ fun TvNextUpCard(
|
|||||||
onEpisodeSelected(episode.seriesId, episode.seasonId, episode.id)
|
onEpisodeSelected(episode.seriesId, episode.seasonId, episode.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageFocusModifier = Modifier
|
|
||||||
.then(if (focusRequester != null) Modifier.focusRequester(focusRequester) else Modifier)
|
|
||||||
.then(
|
|
||||||
if (upFocusRequester != null || downFocusRequester != null) {
|
|
||||||
Modifier.focusProperties {
|
|
||||||
upFocusRequester?.let { up = it }
|
|
||||||
downFocusRequester?.let { down = it }
|
|
||||||
if (isFirstItem) {
|
|
||||||
left = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
if (isLastItem) {
|
|
||||||
right = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Modifier.focusProperties {
|
|
||||||
if (isFirstItem) {
|
|
||||||
left = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
if (isLastItem) {
|
|
||||||
right = FocusRequester.Cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.width(cardWidth)
|
.width(cardWidth)
|
||||||
@@ -333,7 +249,7 @@ fun TvNextUpCard(
|
|||||||
PurefinAsyncImage(
|
PurefinAsyncImage(
|
||||||
model = imageUrl,
|
model = imageUrl,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = imageFocusModifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.onFocusChanged { isFocused = it.isFocused }
|
.onFocusChanged { isFocused = it.isFocused }
|
||||||
.clickable {
|
.clickable {
|
||||||
@@ -367,10 +283,6 @@ fun TvLibraryPosterSection(
|
|||||||
title: String,
|
title: String,
|
||||||
items: List<PosterItem>,
|
items: List<PosterItem>,
|
||||||
action: String?,
|
action: String?,
|
||||||
sectionFocusRequester: FocusRequester,
|
|
||||||
firstItemFocusRequester: FocusRequester? = null,
|
|
||||||
upFocusRequester: FocusRequester? = null,
|
|
||||||
downFocusRequester: FocusRequester? = null,
|
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onMovieSelected: (UUID) -> Unit,
|
onMovieSelected: (UUID) -> Unit,
|
||||||
onSeriesSelected: (UUID) -> Unit,
|
onSeriesSelected: (UUID) -> Unit,
|
||||||
@@ -382,9 +294,7 @@ fun TvLibraryPosterSection(
|
|||||||
)
|
)
|
||||||
LazyRow(
|
LazyRow(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth(),
|
||||||
.focusRequester(sectionFocusRequester)
|
|
||||||
.focusRestorer(firstItemFocusRequester ?: FocusRequester.Default),
|
|
||||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
@@ -394,9 +304,6 @@ fun TvLibraryPosterSection(
|
|||||||
) { index, item ->
|
) { index, item ->
|
||||||
PosterCard(
|
PosterCard(
|
||||||
item = item,
|
item = item,
|
||||||
focusRequester = if (index == 0) firstItemFocusRequester else null,
|
|
||||||
upFocusRequester = upFocusRequester,
|
|
||||||
downFocusRequester = downFocusRequester,
|
|
||||||
onMovieSelected = onMovieSelected,
|
onMovieSelected = onMovieSelected,
|
||||||
onSeriesSelected = onSeriesSelected,
|
onSeriesSelected = onSeriesSelected,
|
||||||
onEpisodeSelected = onEpisodeSelected
|
onEpisodeSelected = onEpisodeSelected
|
||||||
|
|||||||
Reference in New Issue
Block a user