mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Apply view options to preview
This commit is contained in:
parent
5dcdde36c3
commit
1ce380f3b5
9 changed files with 275 additions and 26 deletions
|
|
@ -2,10 +2,16 @@
|
||||||
|
|
||||||
package com.github.damontecres.wholphin.data.model
|
package com.github.damontecres.wholphin.data.model
|
||||||
|
|
||||||
|
import com.github.damontecres.wholphin.R
|
||||||
|
import com.github.damontecres.wholphin.preferences.AppChoicePreference
|
||||||
|
import com.github.damontecres.wholphin.preferences.AppClickablePreference
|
||||||
|
import com.github.damontecres.wholphin.preferences.AppSliderPreference
|
||||||
|
import com.github.damontecres.wholphin.preferences.AppSwitchPreference
|
||||||
import com.github.damontecres.wholphin.preferences.PrefContentScale
|
import com.github.damontecres.wholphin.preferences.PrefContentScale
|
||||||
import com.github.damontecres.wholphin.ui.AspectRatio
|
import com.github.damontecres.wholphin.ui.AspectRatio
|
||||||
import com.github.damontecres.wholphin.ui.Cards
|
import com.github.damontecres.wholphin.ui.Cards
|
||||||
import com.github.damontecres.wholphin.ui.components.ViewOptionImageType
|
import com.github.damontecres.wholphin.ui.components.ViewOptionImageType
|
||||||
|
import com.github.damontecres.wholphin.ui.components.ViewOptions
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||||
|
|
@ -16,33 +22,43 @@ sealed class HomeRowConfig {
|
||||||
abstract val id: UUID
|
abstract val id: UUID
|
||||||
abstract val viewOptions: HomeRowViewOptions
|
abstract val viewOptions: HomeRowViewOptions
|
||||||
|
|
||||||
|
abstract fun updateViewOptions(viewOptions: HomeRowViewOptions): HomeRowConfig
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ContinueWatching(
|
data class ContinueWatching(
|
||||||
override val id: UUID,
|
override val id: UUID,
|
||||||
val combined: Boolean,
|
val combined: Boolean,
|
||||||
override val viewOptions: HomeRowViewOptions,
|
override val viewOptions: HomeRowViewOptions,
|
||||||
) : HomeRowConfig()
|
) : HomeRowConfig() {
|
||||||
|
override fun updateViewOptions(viewOptions: HomeRowViewOptions): HomeRowConfig = this.copy(viewOptions = viewOptions)
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RecentlyAdded(
|
data class RecentlyAdded(
|
||||||
override val id: UUID,
|
override val id: UUID,
|
||||||
val parentId: UUID,
|
val parentId: UUID,
|
||||||
override val viewOptions: HomeRowViewOptions,
|
override val viewOptions: HomeRowViewOptions,
|
||||||
) : HomeRowConfig()
|
) : HomeRowConfig() {
|
||||||
|
override fun updateViewOptions(viewOptions: HomeRowViewOptions): HomeRowConfig = this.copy(viewOptions = viewOptions)
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RecentlyReleased(
|
data class RecentlyReleased(
|
||||||
override val id: UUID,
|
override val id: UUID,
|
||||||
val parentId: UUID,
|
val parentId: UUID,
|
||||||
override val viewOptions: HomeRowViewOptions,
|
override val viewOptions: HomeRowViewOptions,
|
||||||
) : HomeRowConfig()
|
) : HomeRowConfig() {
|
||||||
|
override fun updateViewOptions(viewOptions: HomeRowViewOptions): HomeRowConfig = this.copy(viewOptions = viewOptions)
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Genres(
|
data class Genres(
|
||||||
override val id: UUID,
|
override val id: UUID,
|
||||||
val parentId: UUID,
|
val parentId: UUID,
|
||||||
override val viewOptions: HomeRowViewOptions,
|
override val viewOptions: HomeRowViewOptions,
|
||||||
) : HomeRowConfig()
|
) : HomeRowConfig() {
|
||||||
|
override fun updateViewOptions(viewOptions: HomeRowViewOptions): HomeRowConfig = this.copy(viewOptions = viewOptions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class HomeRowConfigDisplay(
|
data class HomeRowConfigDisplay(
|
||||||
|
|
@ -59,4 +75,101 @@ data class HomeRowViewOptions(
|
||||||
val imageType: ViewOptionImageType = ViewOptionImageType.PRIMARY,
|
val imageType: ViewOptionImageType = ViewOptionImageType.PRIMARY,
|
||||||
val showTitles: Boolean = true,
|
val showTitles: Boolean = true,
|
||||||
val useSeries: Boolean = true,
|
val useSeries: Boolean = true,
|
||||||
)
|
) {
|
||||||
|
companion object {
|
||||||
|
val ViewOptionsColumns =
|
||||||
|
AppSliderPreference<HomeRowViewOptions>(
|
||||||
|
title = R.string.height,
|
||||||
|
defaultValue = Cards.HEIGHT_2X3_DP.toLong(),
|
||||||
|
min = Cards.HEIGHT_2X3_DP / 2L,
|
||||||
|
max = Cards.HEIGHT_2X3_DP + 64L,
|
||||||
|
interval = 4,
|
||||||
|
getter = { it.heightDp.toLong() },
|
||||||
|
setter = { prefs, value -> prefs.copy(heightDp = value.toInt()) },
|
||||||
|
)
|
||||||
|
val ViewOptionsSpacing =
|
||||||
|
AppSliderPreference<HomeRowViewOptions>(
|
||||||
|
title = R.string.spacing,
|
||||||
|
defaultValue = 16,
|
||||||
|
min = 0,
|
||||||
|
max = 32,
|
||||||
|
interval = 2,
|
||||||
|
getter = { it.spacing.toLong() },
|
||||||
|
setter = { prefs, value -> prefs.copy(spacing = value.toInt()) },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsContentScale =
|
||||||
|
AppChoicePreference<HomeRowViewOptions, PrefContentScale>(
|
||||||
|
title = R.string.global_content_scale,
|
||||||
|
defaultValue = PrefContentScale.FIT,
|
||||||
|
displayValues = R.array.content_scale,
|
||||||
|
getter = { it.contentScale },
|
||||||
|
setter = { viewOptions, value -> viewOptions.copy(contentScale = value) },
|
||||||
|
indexToValue = { PrefContentScale.forNumber(it) },
|
||||||
|
valueToIndex = { it.number },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsAspectRatio =
|
||||||
|
AppChoicePreference<HomeRowViewOptions, AspectRatio>(
|
||||||
|
title = R.string.aspect_ratio,
|
||||||
|
defaultValue = AspectRatio.TALL,
|
||||||
|
displayValues = R.array.aspect_ratios,
|
||||||
|
getter = { it.aspectRatio },
|
||||||
|
setter = { viewOptions, value -> viewOptions.copy(aspectRatio = value) },
|
||||||
|
indexToValue = { AspectRatio.entries[it] },
|
||||||
|
valueToIndex = { it.ordinal },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsShowTitles =
|
||||||
|
AppSwitchPreference<HomeRowViewOptions>(
|
||||||
|
title = R.string.show_titles,
|
||||||
|
defaultValue = true,
|
||||||
|
getter = { it.showTitles },
|
||||||
|
setter = { vo, value -> vo.copy(showTitles = value) },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsUseSeries =
|
||||||
|
AppSwitchPreference<HomeRowViewOptions>(
|
||||||
|
title = R.string.go_to_series, // TODO
|
||||||
|
defaultValue = true,
|
||||||
|
getter = { it.useSeries },
|
||||||
|
setter = { vo, value -> vo.copy(useSeries = value) },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsImageType =
|
||||||
|
AppChoicePreference<HomeRowViewOptions, ViewOptionImageType>(
|
||||||
|
title = R.string.image_type,
|
||||||
|
defaultValue = ViewOptionImageType.PRIMARY,
|
||||||
|
displayValues = R.array.image_types,
|
||||||
|
getter = { it.imageType },
|
||||||
|
setter = { viewOptions, value ->
|
||||||
|
val aspectRatio =
|
||||||
|
when (value) {
|
||||||
|
ViewOptionImageType.PRIMARY -> AspectRatio.TALL
|
||||||
|
ViewOptionImageType.THUMB -> AspectRatio.WIDE
|
||||||
|
}
|
||||||
|
viewOptions.copy(imageType = value, aspectRatio = aspectRatio)
|
||||||
|
},
|
||||||
|
indexToValue = { ViewOptionImageType.entries[it] },
|
||||||
|
valueToIndex = { it.ordinal },
|
||||||
|
)
|
||||||
|
|
||||||
|
val ViewOptionsReset =
|
||||||
|
AppClickablePreference<ViewOptions>(
|
||||||
|
title = R.string.reset,
|
||||||
|
)
|
||||||
|
|
||||||
|
val OPTIONS =
|
||||||
|
listOf(
|
||||||
|
ViewOptionsImageType,
|
||||||
|
ViewOptionsAspectRatio,
|
||||||
|
// TODO
|
||||||
|
// ViewOptionsShowTitles,
|
||||||
|
// ViewOptionsUseSeries,
|
||||||
|
ViewOptionsColumns,
|
||||||
|
ViewOptionsSpacing,
|
||||||
|
ViewOptionsContentScale,
|
||||||
|
ViewOptionsReset,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ fun BannerCard(
|
||||||
cardHeight: Dp = 120.dp,
|
cardHeight: Dp = 120.dp,
|
||||||
aspectRatio: Float = AspectRatios.WIDE,
|
aspectRatio: Float = AspectRatios.WIDE,
|
||||||
interactionSource: MutableInteractionSource? = null,
|
interactionSource: MutableInteractionSource? = null,
|
||||||
|
imageType: ImageType = ImageType.PRIMARY,
|
||||||
|
imageContentScale: ContentScale = ContentScale.FillBounds,
|
||||||
) {
|
) {
|
||||||
val imageUrlService = LocalImageUrlService.current
|
val imageUrlService = LocalImageUrlService.current
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
|
|
@ -74,11 +76,11 @@ fun BannerCard(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val imageUrl =
|
val imageUrl =
|
||||||
remember(item, fillHeight) {
|
remember(item, fillHeight, imageType) {
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
imageUrlService.getItemImageUrl(
|
imageUrlService.getItemImageUrl(
|
||||||
item,
|
item,
|
||||||
ImageType.PRIMARY,
|
imageType,
|
||||||
fillWidth = null,
|
fillWidth = null,
|
||||||
fillHeight = fillHeight,
|
fillHeight = fillHeight,
|
||||||
)
|
)
|
||||||
|
|
@ -107,7 +109,7 @@ fun BannerCard(
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = imageUrl,
|
model = imageUrl,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
contentScale = ContentScale.FillBounds,
|
contentScale = imageContentScale,
|
||||||
onError = { imageError = true },
|
onError = { imageError = true },
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
|
||||||
import com.github.damontecres.wholphin.ui.Cards
|
import com.github.damontecres.wholphin.ui.Cards
|
||||||
import com.github.damontecres.wholphin.ui.cards.BannerCard
|
import com.github.damontecres.wholphin.ui.cards.BannerCard
|
||||||
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||||
|
|
@ -67,6 +66,7 @@ import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
||||||
import com.github.damontecres.wholphin.ui.playback.playable
|
import com.github.damontecres.wholphin.ui.playback.playable
|
||||||
|
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.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
|
|
@ -308,6 +308,7 @@ fun HomePageContent(
|
||||||
|
|
||||||
is HomeRowLoadingState.Success -> {
|
is HomeRowLoadingState.Success -> {
|
||||||
if (row.items.isNotEmpty()) {
|
if (row.items.isNotEmpty()) {
|
||||||
|
val viewOptions = row.viewOptions
|
||||||
ItemRow(
|
ItemRow(
|
||||||
title = row.title,
|
title = row.title,
|
||||||
items = row.items,
|
items = row.items,
|
||||||
|
|
@ -323,11 +324,14 @@ fun HomePageContent(
|
||||||
.focusGroup()
|
.focusGroup()
|
||||||
.focusRequester(rowFocusRequesters[rowIndex])
|
.focusRequester(rowFocusRequesters[rowIndex])
|
||||||
.animateItem(),
|
.animateItem(),
|
||||||
|
horizontalPadding = viewOptions.spacing.dp,
|
||||||
cardContent = { index, item, cardModifier, onClick, onLongClick ->
|
cardContent = { index, item, cardModifier, onClick, onLongClick ->
|
||||||
BannerCard(
|
BannerCard(
|
||||||
name = item?.data?.seriesName ?: item?.name,
|
name = item?.data?.seriesName ?: item?.name,
|
||||||
item = item,
|
item = item,
|
||||||
aspectRatio = AspectRatios.TALL,
|
aspectRatio = viewOptions.aspectRatio.ratio,
|
||||||
|
imageType = viewOptions.imageType.imageType,
|
||||||
|
imageContentScale = viewOptions.contentScale.scale,
|
||||||
cornerText = item?.ui?.episdodeUnplayedCornerText,
|
cornerText = item?.ui?.episdodeUnplayedCornerText,
|
||||||
played = item?.data?.userData?.played ?: false,
|
played = item?.data?.userData?.played ?: false,
|
||||||
favorite = item?.favorite ?: false,
|
favorite = item?.favorite ?: false,
|
||||||
|
|
@ -366,7 +370,7 @@ fun HomePageContent(
|
||||||
return@onKeyEvent false
|
return@onKeyEvent false
|
||||||
},
|
},
|
||||||
interactionSource = null,
|
interactionSource = null,
|
||||||
cardHeight = Cards.height2x3,
|
cardHeight = viewOptions.heightDp.dp,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
|
@ -26,6 +25,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
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
|
||||||
import androidx.tv.material3.Icon
|
import androidx.tv.material3.Icon
|
||||||
|
import androidx.tv.material3.ListItem
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import androidx.tv.material3.surfaceColorAtElevation
|
import androidx.tv.material3.surfaceColorAtElevation
|
||||||
|
|
@ -44,6 +44,7 @@ enum class MoveDirection {
|
||||||
@Composable
|
@Composable
|
||||||
fun HomePageRowList(
|
fun HomePageRowList(
|
||||||
state: HomePageSettingsState,
|
state: HomePageSettingsState,
|
||||||
|
onClick: (Int, HomeRowConfigDisplay) -> Unit,
|
||||||
onClickAdd: () -> Unit,
|
onClickAdd: () -> Unit,
|
||||||
onClickMove: (MoveDirection, Int) -> Unit,
|
onClickMove: (MoveDirection, Int) -> Unit,
|
||||||
onClickDelete: (Int) -> Unit,
|
onClickDelete: (Int) -> Unit,
|
||||||
|
|
@ -66,6 +67,7 @@ fun HomePageRowList(
|
||||||
deleteAllowed = row.config !is HomeRowConfig.ContinueWatching,
|
deleteAllowed = row.config !is HomeRowConfig.ContinueWatching,
|
||||||
onClickMove = { onClickMove.invoke(it, index) },
|
onClickMove = { onClickMove.invoke(it, index) },
|
||||||
onClickDelete = { onClickDelete.invoke(index) },
|
onClickDelete = { onClickDelete.invoke(index) },
|
||||||
|
onClick = { onClick.invoke(index, row) },
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
@ -92,6 +94,7 @@ fun HomeRowConfigContent(
|
||||||
moveUpAllowed: Boolean,
|
moveUpAllowed: Boolean,
|
||||||
moveDownAllowed: Boolean,
|
moveDownAllowed: Boolean,
|
||||||
deleteAllowed: Boolean,
|
deleteAllowed: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
onClickMove: (MoveDirection) -> Unit,
|
onClickMove: (MoveDirection) -> Unit,
|
||||||
onClickDelete: () -> Unit,
|
onClickDelete: () -> Unit,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
|
|
@ -111,15 +114,18 @@ fun HomeRowConfigContent(
|
||||||
shape = RoundedCornerShape(8.dp),
|
shape = RoundedCornerShape(8.dp),
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
ListItem(
|
||||||
|
selected = false,
|
||||||
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
text = config.title,
|
text = config.title,
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
style = MaterialTheme.typography.titleMedium,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier,
|
||||||
.weight(1f)
|
)
|
||||||
.padding(start = 4.dp),
|
},
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
)
|
)
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.github.damontecres.wholphin.ui.main.settings
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.tv.material3.MaterialTheme
|
||||||
|
import androidx.tv.material3.Text
|
||||||
|
import androidx.tv.material3.surfaceColorAtElevation
|
||||||
|
import com.github.damontecres.wholphin.data.model.HomeRowViewOptions
|
||||||
|
import com.github.damontecres.wholphin.preferences.AppPreference
|
||||||
|
import com.github.damontecres.wholphin.ui.preferences.ComposablePreference
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HomePageRowSettings(
|
||||||
|
title: String,
|
||||||
|
viewOptions: HomeRowViewOptions,
|
||||||
|
onViewOptionsChange: (HomeRowViewOptions) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
defaultViewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
||||||
|
) {
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = MaterialTheme.typography.titleLarge,
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
LazyColumn {
|
||||||
|
items(HomeRowViewOptions.OPTIONS) { pref ->
|
||||||
|
pref as AppPreference<HomeRowViewOptions, Any>
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
val value = pref.getter.invoke(viewOptions)
|
||||||
|
ComposablePreference(
|
||||||
|
preference = pref,
|
||||||
|
value = value,
|
||||||
|
onNavigate = {},
|
||||||
|
onValueChange = { newValue ->
|
||||||
|
onViewOptionsChange.invoke(pref.setter(viewOptions, newValue))
|
||||||
|
},
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
onClickPreference = { pref ->
|
||||||
|
if (pref == HomeRowViewOptions.ViewOptionsReset) {
|
||||||
|
onViewOptionsChange.invoke(defaultViewOptions)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.background(MaterialTheme.colorScheme.surfaceColorAtElevation(5.dp)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -159,6 +159,7 @@ class HomePageSettingsViewModel
|
||||||
HomeRowLoadingState.Success(
|
HomeRowLoadingState.Success(
|
||||||
title = context.getString(R.string.continue_watching),
|
title = context.getString(R.string.continue_watching),
|
||||||
items = items,
|
items = items,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -167,6 +168,7 @@ class HomePageSettingsViewModel
|
||||||
HomeRowLoadingState.Success(
|
HomeRowLoadingState.Success(
|
||||||
title = context.getString(R.string.continue_watching),
|
title = context.getString(R.string.continue_watching),
|
||||||
items = resume,
|
items = resume,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -175,6 +177,7 @@ class HomePageSettingsViewModel
|
||||||
HomeRowLoadingState.Success(
|
HomeRowLoadingState.Success(
|
||||||
title = context.getString(R.string.next_up),
|
title = context.getString(R.string.next_up),
|
||||||
items = nextUp,
|
items = nextUp,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +205,13 @@ class HomePageSettingsViewModel
|
||||||
val title =
|
val title =
|
||||||
name?.let { context.getString(R.string.genres_in, it) }
|
name?.let { context.getString(R.string.genres_in, it) }
|
||||||
?: context.getString(R.string.genres)
|
?: context.getString(R.string.genres)
|
||||||
listOf(HomeRowLoadingState.Success(title, items))
|
listOf(
|
||||||
|
HomeRowLoadingState.Success(
|
||||||
|
title,
|
||||||
|
items,
|
||||||
|
viewOptions = row.viewOptions,
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowConfig.RecentlyAdded -> {
|
is HomeRowConfig.RecentlyAdded -> {
|
||||||
|
|
@ -222,7 +231,17 @@ class HomePageSettingsViewModel
|
||||||
limit = limit,
|
limit = limit,
|
||||||
isPlayed = null, // Server will handle user's preference
|
isPlayed = null, // Server will handle user's preference
|
||||||
)
|
)
|
||||||
latestNextUpService.loadLatest(listOf(LatestData(title, request)))
|
latestNextUpService
|
||||||
|
.loadLatest(listOf(LatestData(title, request)))
|
||||||
|
.let {
|
||||||
|
it.map {
|
||||||
|
if (it is HomeRowLoadingState.Success) {
|
||||||
|
it.copy(viewOptions = row.viewOptions)
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowConfig.RecentlyReleased -> {
|
is HomeRowConfig.RecentlyReleased -> {
|
||||||
|
|
@ -342,6 +361,39 @@ class HomePageSettingsViewModel
|
||||||
fetchRowData()
|
fetchRowData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateViewOptions(
|
||||||
|
rowId: UUID,
|
||||||
|
viewOptions: HomeRowViewOptions,
|
||||||
|
) {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
_state.update {
|
||||||
|
val index = state.value.rows.indexOfFirst { it.config.id == rowId }
|
||||||
|
val newRowConfig =
|
||||||
|
state.value.rows[index]
|
||||||
|
.config
|
||||||
|
.updateViewOptions(viewOptions)
|
||||||
|
val newRow = state.value.rows[index].copy(config = newRowConfig)
|
||||||
|
it.copy(
|
||||||
|
rows =
|
||||||
|
it.rows.toMutableList().apply {
|
||||||
|
set(index, newRow)
|
||||||
|
},
|
||||||
|
rowData =
|
||||||
|
it.rowData.toMutableList().apply {
|
||||||
|
val row = it.rowData[index]
|
||||||
|
val newRow =
|
||||||
|
if (row is HomeRowLoadingState.Success) {
|
||||||
|
row.copy(viewOptions = viewOptions)
|
||||||
|
} else {
|
||||||
|
row
|
||||||
|
}
|
||||||
|
set(index, newRow)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class HomePageSettingsState(
|
data class HomePageSettingsState(
|
||||||
|
|
@ -410,6 +462,9 @@ fun HomePageSettings(
|
||||||
onClickAdd = { destination = HomePageSettingsDestination.ChooseLibrary },
|
onClickAdd = { destination = HomePageSettingsDestination.ChooseLibrary },
|
||||||
onClickMove = viewModel::moveRow,
|
onClickMove = viewModel::moveRow,
|
||||||
onClickDelete = viewModel::deleteRow,
|
onClickDelete = viewModel::deleteRow,
|
||||||
|
onClick = { index, row ->
|
||||||
|
destination = HomePageSettingsDestination.RowSettings(row.config.id)
|
||||||
|
},
|
||||||
modifier = destModifier,
|
modifier = destModifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +489,17 @@ fun HomePageSettings(
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomePageSettingsDestination.RowSettings -> {
|
is HomePageSettingsDestination.RowSettings -> {
|
||||||
TODO()
|
val row =
|
||||||
|
state.rows
|
||||||
|
.first { it.config.id == dest.rowId }
|
||||||
|
HomePageRowSettings(
|
||||||
|
title = row.title,
|
||||||
|
viewOptions = row.config.viewOptions,
|
||||||
|
onViewOptionsChange = {
|
||||||
|
viewModel.updateViewOptions(dest.rowId, it)
|
||||||
|
},
|
||||||
|
modifier = destModifier,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.github.damontecres.wholphin.ui.main.settings
|
package com.github.damontecres.wholphin.ui.main.settings
|
||||||
|
|
||||||
import com.github.damontecres.wholphin.data.model.HomeRowConfigDisplay
|
import java.util.UUID
|
||||||
|
|
||||||
sealed interface HomePageSettingsDestination {
|
sealed interface HomePageSettingsDestination {
|
||||||
data object RowList : HomePageSettingsDestination
|
data object RowList : HomePageSettingsDestination
|
||||||
|
|
@ -12,6 +12,6 @@ sealed interface HomePageSettingsDestination {
|
||||||
) : HomePageSettingsDestination
|
) : HomePageSettingsDestination
|
||||||
|
|
||||||
data class RowSettings(
|
data class RowSettings(
|
||||||
val row: HomeRowConfigDisplay,
|
val rowId: UUID,
|
||||||
) : HomePageSettingsDestination
|
) : HomePageSettingsDestination
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.github.damontecres.wholphin.util
|
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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic state for loading something from the API
|
* Generic state for loading something from the API
|
||||||
|
|
@ -59,6 +60,7 @@ sealed interface HomeRowLoadingState {
|
||||||
data class Success(
|
data class Success(
|
||||||
override val title: String,
|
override val title: String,
|
||||||
val items: List<BaseItem?>,
|
val items: List<BaseItem?>,
|
||||||
|
val viewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
||||||
) : HomeRowLoadingState
|
) : HomeRowLoadingState
|
||||||
|
|
||||||
data class Error(
|
data class Error(
|
||||||
|
|
|
||||||
|
|
@ -465,6 +465,7 @@
|
||||||
<string name="add_row">Add row</string>
|
<string name="add_row">Add row</string>
|
||||||
<string name="genres_in">Genres in %1$s</string>
|
<string name="genres_in">Genres in %1$s</string>
|
||||||
<string name="recently_released_in">Recently released in %1$s</string>
|
<string name="recently_released_in">Recently released in %1$s</string>
|
||||||
|
<string name="height">Height</string>
|
||||||
|
|
||||||
<string-array name="theme_song_volume">
|
<string-array name="theme_song_volume">
|
||||||
<item>Disabled</item>
|
<item>Disabled</item>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue