mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Revert "Use typed HomeRow in HomeRowLoadingState.Success"
This reverts commit 2c6e7a57f0.
This commit is contained in:
parent
2c6e7a57f0
commit
45e023d1b2
3 changed files with 79 additions and 176 deletions
|
|
@ -34,7 +34,6 @@ import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||||
import com.github.damontecres.wholphin.util.HomeRow
|
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
@ -62,16 +61,7 @@ abstract class RecommendedViewModel(
|
||||||
viewModelScope.launchIO {
|
viewModelScope.launchIO {
|
||||||
val row = rows.value.getOrNull(position.row)
|
val row = rows.value.getOrNull(position.row)
|
||||||
if (row is HomeRowLoadingState.Success) {
|
if (row is HomeRowLoadingState.Success) {
|
||||||
when (row.data) {
|
(row.items as? ApiRequestPager<*>)?.refreshItem(position.column, itemId)
|
||||||
is HomeRow.BaseItemHomeRow -> {
|
|
||||||
(row.data.items as? ApiRequestPager<*>)?.refreshItem(
|
|
||||||
position.column,
|
|
||||||
itemId,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is HomeRow.GenreHowRow -> {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
||||||
import com.github.damontecres.wholphin.ui.components.EpisodeName
|
import com.github.damontecres.wholphin.ui.components.EpisodeName
|
||||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||||
import com.github.damontecres.wholphin.ui.components.Genre
|
|
||||||
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
import com.github.damontecres.wholphin.ui.components.LoadingPage
|
||||||
import com.github.damontecres.wholphin.ui.components.QuickDetails
|
import com.github.damontecres.wholphin.ui.components.QuickDetails
|
||||||
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
||||||
|
|
@ -70,7 +69,6 @@ import com.github.damontecres.wholphin.ui.playback.playable
|
||||||
import com.github.damontecres.wholphin.ui.playback.scale
|
import com.github.damontecres.wholphin.ui.playback.scale
|
||||||
import com.github.damontecres.wholphin.ui.rememberPosition
|
import com.github.damontecres.wholphin.ui.rememberPosition
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.HomeRow
|
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
@ -184,13 +182,6 @@ fun HomePage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun HomeRowLoadingState.getItem(index: Int) =
|
|
||||||
when (val data = (this as? HomeRowLoadingState.Success)?.data) {
|
|
||||||
is HomeRow.BaseItemHomeRow -> data.items.getOrNull(index)
|
|
||||||
is HomeRow.GenreHowRow -> data.items.getOrNull(index)
|
|
||||||
null -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomePageContent(
|
fun HomePageContent(
|
||||||
homeRows: List<HomeRowLoadingState>,
|
homeRows: List<HomeRowLoadingState>,
|
||||||
|
|
@ -207,7 +198,7 @@ fun HomePageContent(
|
||||||
var position by rememberPosition()
|
var position by rememberPosition()
|
||||||
val focusedItem =
|
val focusedItem =
|
||||||
position.let {
|
position.let {
|
||||||
homeRows.getOrNull(it.row)?.getItem(it.column)
|
(homeRows.getOrNull(it.row) as? HomeRowLoadingState.Success)?.items?.getOrNull(it.column)
|
||||||
}
|
}
|
||||||
|
|
||||||
val rowFocusRequesters = remember(homeRows) { List(homeRows.size) { FocusRequester() } }
|
val rowFocusRequesters = remember(homeRows) { List(homeRows.size) { FocusRequester() } }
|
||||||
|
|
@ -220,7 +211,7 @@ fun HomePageContent(
|
||||||
} else {
|
} else {
|
||||||
// Waiting for the first home row to load, then focus on it
|
// Waiting for the first home row to load, then focus on it
|
||||||
homeRows
|
homeRows
|
||||||
.indexOfFirst { it is HomeRowLoadingState.Success && it.data.isNotEmpty() }
|
.indexOfFirst { it is HomeRowLoadingState.Success && it.items.isNotEmpty() }
|
||||||
.takeIf { it >= 0 }
|
.takeIf { it >= 0 }
|
||||||
?.let {
|
?.let {
|
||||||
rowFocusRequesters[it].tryRequestFocus()
|
rowFocusRequesters[it].tryRequestFocus()
|
||||||
|
|
@ -237,29 +228,17 @@ fun HomePageContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LaunchedEffect(onUpdateBackdrop, focusedItem) {
|
LaunchedEffect(onUpdateBackdrop, focusedItem) {
|
||||||
(focusedItem as? BaseItem)?.let { onUpdateBackdrop.invoke(it) }
|
focusedItem?.let { onUpdateBackdrop.invoke(it) }
|
||||||
}
|
}
|
||||||
Box(modifier = modifier) {
|
Box(modifier = modifier) {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
val headerModifier =
|
|
||||||
Modifier
|
|
||||||
.padding(top = 48.dp, bottom = 32.dp, start = 32.dp)
|
|
||||||
.fillMaxHeight(.33f)
|
|
||||||
when (focusedItem) {
|
|
||||||
is BaseItem -> {
|
|
||||||
HomePageHeader(
|
HomePageHeader(
|
||||||
item = focusedItem,
|
item = focusedItem,
|
||||||
modifier = headerModifier,
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.padding(top = 48.dp, bottom = 32.dp, start = 32.dp)
|
||||||
|
.fillMaxHeight(.33f),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
is Genre -> {
|
|
||||||
Text(
|
|
||||||
text = focusedItem.name,
|
|
||||||
modifier = headerModifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
|
@ -328,29 +307,52 @@ fun HomePageContent(
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowLoadingState.Success -> {
|
is HomeRowLoadingState.Success -> {
|
||||||
if (row.data.isNotEmpty()) {
|
if (row.items.isNotEmpty()) {
|
||||||
when (row.data) {
|
val viewOptions = row.viewOptions
|
||||||
is HomeRow.BaseItemHomeRow -> {
|
ItemRow(
|
||||||
BaseItemRow(
|
title = row.title,
|
||||||
row = row,
|
items = row.items,
|
||||||
rowData = row.data,
|
|
||||||
onClickItem = { index, item ->
|
onClickItem = { index, item ->
|
||||||
onClickItem.invoke(RowColumn(rowIndex, index), item)
|
onClickItem.invoke(RowColumn(rowIndex, index), item)
|
||||||
},
|
},
|
||||||
onLongClickItem = { index, item ->
|
onLongClickItem = { index, item ->
|
||||||
onLongClickItem.invoke(
|
onLongClickItem.invoke(RowColumn(rowIndex, index), item)
|
||||||
RowColumn(rowIndex, index),
|
|
||||||
item,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
onCardFocus = { index ->
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.focusGroup()
|
||||||
|
.focusRequester(rowFocusRequesters[rowIndex])
|
||||||
|
.animateItem(),
|
||||||
|
horizontalPadding = viewOptions.spacing.dp,
|
||||||
|
cardContent = { index, item, cardModifier, onClick, onLongClick ->
|
||||||
|
BannerCard(
|
||||||
|
name = item?.data?.seriesName ?: item?.name,
|
||||||
|
item = item,
|
||||||
|
aspectRatio = viewOptions.aspectRatio.ratio,
|
||||||
|
imageType = viewOptions.imageType.imageType,
|
||||||
|
imageContentScale = viewOptions.contentScale.scale,
|
||||||
|
cornerText = item?.ui?.episdodeUnplayedCornerText,
|
||||||
|
played = item?.data?.userData?.played ?: false,
|
||||||
|
favorite = item?.favorite ?: false,
|
||||||
|
playPercent =
|
||||||
|
item?.data?.userData?.playedPercentage
|
||||||
|
?: 0.0,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
modifier =
|
||||||
|
cardModifier
|
||||||
|
.onFocusChanged {
|
||||||
|
if (it.isFocused) {
|
||||||
position = RowColumn(rowIndex, index)
|
position = RowColumn(rowIndex, index)
|
||||||
if (onFocusPosition != null) {
|
// item?.let(onUpdateBackdrop)
|
||||||
|
}
|
||||||
|
if (it.isFocused && onFocusPosition != null) {
|
||||||
val nonEmptyRowBefore =
|
val nonEmptyRowBefore =
|
||||||
homeRows
|
homeRows
|
||||||
.subList(0, rowIndex)
|
.subList(0, rowIndex)
|
||||||
.count {
|
.count {
|
||||||
it is HomeRowLoadingState.Success && it.data.isEmpty()
|
it is HomeRowLoadingState.Success && it.items.isEmpty()
|
||||||
}
|
}
|
||||||
onFocusPosition.invoke(
|
onFocusPosition.invoke(
|
||||||
RowColumn(
|
RowColumn(
|
||||||
|
|
@ -359,25 +361,20 @@ fun HomePageContent(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}.onKeyEvent {
|
||||||
|
if (isPlayKeyUp(it) && item?.type?.playable == true) {
|
||||||
|
Timber.v("Clicked play on ${item.id}")
|
||||||
|
onClickPlay.invoke(position, item)
|
||||||
|
return@onKeyEvent true
|
||||||
|
}
|
||||||
|
return@onKeyEvent false
|
||||||
},
|
},
|
||||||
onClickPlay = { index ->
|
interactionSource = null,
|
||||||
row.data.items.get(index)?.let {
|
cardHeight = viewOptions.heightDp.dp,
|
||||||
onClickPlay.invoke(
|
|
||||||
RowColumn(rowIndex, index),
|
|
||||||
it,
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
},
|
},
|
||||||
modifier = Modifier,
|
|
||||||
focusRequester = rowFocusRequesters[rowIndex],
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRow.GenreHowRow -> {
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -478,62 +475,3 @@ fun HomePageHeader(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BaseItemRow(
|
|
||||||
row: HomeRowLoadingState.Success,
|
|
||||||
rowData: HomeRow.BaseItemHomeRow,
|
|
||||||
onClickItem: (Int, BaseItem) -> Unit,
|
|
||||||
onLongClickItem: (Int, BaseItem) -> Unit,
|
|
||||||
onClickPlay: (Int) -> Unit,
|
|
||||||
onCardFocus: (Int) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
focusRequester: FocusRequester = remember { FocusRequester() },
|
|
||||||
) {
|
|
||||||
val viewOptions = row.viewOptions
|
|
||||||
ItemRow(
|
|
||||||
title = row.title,
|
|
||||||
items = rowData.items,
|
|
||||||
onClickItem = onClickItem,
|
|
||||||
onLongClickItem = onLongClickItem,
|
|
||||||
modifier =
|
|
||||||
modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.focusGroup()
|
|
||||||
.focusRequester(focusRequester),
|
|
||||||
horizontalPadding = viewOptions.spacing.dp,
|
|
||||||
cardContent = { index, item, cardModifier, onClick, onLongClick ->
|
|
||||||
BannerCard(
|
|
||||||
name = item?.data?.seriesName ?: item?.name,
|
|
||||||
item = item,
|
|
||||||
aspectRatio = viewOptions.aspectRatio.ratio,
|
|
||||||
imageType = viewOptions.imageType.imageType,
|
|
||||||
imageContentScale = viewOptions.contentScale.scale,
|
|
||||||
cornerText = item?.ui?.episdodeUnplayedCornerText,
|
|
||||||
played = item?.data?.userData?.played ?: false,
|
|
||||||
favorite = item?.favorite ?: false,
|
|
||||||
playPercent =
|
|
||||||
item?.data?.userData?.playedPercentage
|
|
||||||
?: 0.0,
|
|
||||||
onClick = onClick,
|
|
||||||
onLongClick = onLongClick,
|
|
||||||
modifier =
|
|
||||||
cardModifier
|
|
||||||
.onFocusChanged {
|
|
||||||
if (it.isFocused) {
|
|
||||||
onCardFocus.invoke(index)
|
|
||||||
}
|
|
||||||
}.onKeyEvent {
|
|
||||||
if (isPlayKeyUp(it) && item?.type?.playable == true) {
|
|
||||||
Timber.v("Clicked play on ${item.id}")
|
|
||||||
onClickPlay.invoke(index)
|
|
||||||
return@onKeyEvent true
|
|
||||||
}
|
|
||||||
return@onKeyEvent false
|
|
||||||
},
|
|
||||||
interactionSource = null,
|
|
||||||
cardHeight = viewOptions.heightDp.dp,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.github.damontecres.wholphin.util
|
||||||
|
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
||||||
import com.github.damontecres.wholphin.ui.components.Genre
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic state for loading something from the API
|
* Generic state for loading something from the API
|
||||||
|
|
@ -60,15 +59,9 @@ sealed interface HomeRowLoadingState {
|
||||||
|
|
||||||
data class Success(
|
data class Success(
|
||||||
override val title: String,
|
override val title: String,
|
||||||
|
val items: List<BaseItem?>,
|
||||||
val viewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
val viewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
||||||
val data: HomeRow,
|
) : HomeRowLoadingState
|
||||||
) : HomeRowLoadingState {
|
|
||||||
constructor(
|
|
||||||
title: String,
|
|
||||||
items: List<BaseItem?>,
|
|
||||||
viewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
|
||||||
) : this(title, viewOptions, HomeRow.BaseItemHomeRow(items))
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Error(
|
data class Error(
|
||||||
override val title: String,
|
override val title: String,
|
||||||
|
|
@ -80,24 +73,6 @@ sealed interface HomeRowLoadingState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface HomeRow {
|
|
||||||
fun isEmpty(): Boolean
|
|
||||||
|
|
||||||
fun isNotEmpty(): Boolean = !isEmpty()
|
|
||||||
|
|
||||||
data class BaseItemHomeRow(
|
|
||||||
val items: List<BaseItem?>,
|
|
||||||
) : HomeRow {
|
|
||||||
override fun isEmpty(): Boolean = items.isEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
data class GenreHowRow(
|
|
||||||
val items: List<Genre>,
|
|
||||||
) : HomeRow {
|
|
||||||
override fun isEmpty(): Boolean = items.isEmpty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic state for loading something from the API
|
* Generic state for loading something from the API
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue