mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Better support for using thumbnails
This commit is contained in:
parent
f786ec647e
commit
9a86e854e9
8 changed files with 174 additions and 56 deletions
|
|
@ -199,4 +199,7 @@ data class HomeRowViewOptions(
|
|||
val imageType: ViewOptionImageType = ViewOptionImageType.PRIMARY,
|
||||
val showTitles: Boolean = false,
|
||||
val useSeries: Boolean = true,
|
||||
val episodeContentScale: PrefContentScale = PrefContentScale.FIT,
|
||||
val episodeAspectRatio: AspectRatio = AspectRatio.TALL,
|
||||
val episodeImageType: ViewOptionImageType = ViewOptionImageType.PRIMARY,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -976,8 +976,6 @@ val basicPreferences =
|
|||
),
|
||||
)
|
||||
|
||||
val uiPreferences = listOf<PreferenceGroup>()
|
||||
|
||||
private val ExoPlayerSettings =
|
||||
listOf(
|
||||
AppPreference.FfmpegPreference,
|
||||
|
|
|
|||
|
|
@ -371,12 +371,36 @@ fun HomePageContent(
|
|||
}
|
||||
|
||||
else -> {
|
||||
val imageType =
|
||||
remember(item, viewOptions) {
|
||||
if (item?.type == BaseItemKind.EPISODE) {
|
||||
viewOptions.episodeImageType.imageType
|
||||
} else {
|
||||
viewOptions.imageType.imageType
|
||||
}
|
||||
}
|
||||
val ratio =
|
||||
remember(item, viewOptions) {
|
||||
if (item?.type == BaseItemKind.EPISODE) {
|
||||
viewOptions.episodeAspectRatio.ratio
|
||||
} else {
|
||||
viewOptions.aspectRatio.ratio
|
||||
}
|
||||
}
|
||||
val scale =
|
||||
remember(item, viewOptions) {
|
||||
if (item?.type == BaseItemKind.EPISODE) {
|
||||
viewOptions.episodeContentScale.scale
|
||||
} else {
|
||||
viewOptions.contentScale.scale
|
||||
}
|
||||
}
|
||||
BannerCard(
|
||||
name = item?.data?.seriesName ?: item?.name,
|
||||
item = item,
|
||||
aspectRatio = viewOptions.aspectRatio.ratio,
|
||||
imageType = viewOptions.imageType.imageType,
|
||||
imageContentScale = viewOptions.contentScale.scale,
|
||||
aspectRatio = ratio,
|
||||
imageType = imageType,
|
||||
imageContentScale = scale,
|
||||
cornerText = item?.ui?.episdodeUnplayedCornerText,
|
||||
played = item?.data?.userData?.played ?: false,
|
||||
favorite = item?.favorite ?: false,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.surfaceColorAtElevation
|
||||
|
|
@ -25,54 +26,60 @@ import com.github.damontecres.wholphin.preferences.PrefContentScale
|
|||
import com.github.damontecres.wholphin.ui.AspectRatio
|
||||
import com.github.damontecres.wholphin.ui.Cards
|
||||
import com.github.damontecres.wholphin.ui.components.ViewOptionImageType
|
||||
import com.github.damontecres.wholphin.ui.components.ViewOptions
|
||||
import com.github.damontecres.wholphin.ui.ifElse
|
||||
import com.github.damontecres.wholphin.ui.preferences.ComposablePreference
|
||||
import com.github.damontecres.wholphin.ui.preferences.PreferenceGroup
|
||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||
|
||||
@Composable
|
||||
fun HomeRowSettings(
|
||||
title: String,
|
||||
preferenceOptions: List<PreferenceGroup<HomeRowViewOptions>>,
|
||||
viewOptions: HomeRowViewOptions,
|
||||
onViewOptionsChange: (HomeRowViewOptions) -> Unit,
|
||||
onApplyApplyAll: () -> Unit,
|
||||
userGenreSettings: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
defaultViewOptions: HomeRowViewOptions = HomeRowViewOptions(),
|
||||
) {
|
||||
val options = if (userGenreSettings) Options.GENRE_OPTIONS else Options.OPTIONS
|
||||
val firstFocus = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) { firstFocus.tryRequestFocus() }
|
||||
Column(modifier = modifier) {
|
||||
TitleText(title)
|
||||
LazyColumn {
|
||||
itemsIndexed(options) { index, 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 == Options.ViewOptionsReset) {
|
||||
onViewOptionsChange.invoke(defaultViewOptions)
|
||||
} else if (pref == Options.ViewOptionsApplyAll) {
|
||||
onApplyApplyAll.invoke()
|
||||
}
|
||||
},
|
||||
modifier =
|
||||
Modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||
5.dp,
|
||||
),
|
||||
).ifElse(index == 0, Modifier.focusRequester(firstFocus)),
|
||||
)
|
||||
preferenceOptions.forEachIndexed { groupIndex, prefGroup ->
|
||||
if (preferenceOptions.size > 1) {
|
||||
item {
|
||||
TitleText(stringResource(prefGroup.title))
|
||||
}
|
||||
}
|
||||
itemsIndexed(prefGroup.preferences) { index, 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 == Options.ViewOptionsReset) {
|
||||
onViewOptionsChange.invoke(defaultViewOptions)
|
||||
} else if (pref == Options.ViewOptionsApplyAll) {
|
||||
onApplyApplyAll.invoke()
|
||||
}
|
||||
},
|
||||
modifier =
|
||||
Modifier
|
||||
.background(
|
||||
MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||
5.dp,
|
||||
),
|
||||
).ifElse(index == 0, Modifier.focusRequester(firstFocus)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,33 +164,111 @@ internal object Options {
|
|||
)
|
||||
|
||||
val ViewOptionsApplyAll =
|
||||
AppClickablePreference<ViewOptions>(
|
||||
AppClickablePreference<HomeRowViewOptions>(
|
||||
title = R.string.apply_all_rows,
|
||||
)
|
||||
|
||||
val ViewOptionsReset =
|
||||
AppClickablePreference<ViewOptions>(
|
||||
AppClickablePreference<HomeRowViewOptions>(
|
||||
title = R.string.reset,
|
||||
)
|
||||
|
||||
val ViewOptionsEpisodeContentScale =
|
||||
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(episodeContentScale = value) },
|
||||
indexToValue = { PrefContentScale.forNumber(it) },
|
||||
valueToIndex = { it.number },
|
||||
)
|
||||
|
||||
val ViewOptionsEpisodeAspectRatio =
|
||||
AppChoicePreference<HomeRowViewOptions, AspectRatio>(
|
||||
title = R.string.aspect_ratio,
|
||||
defaultValue = AspectRatio.TALL,
|
||||
displayValues = R.array.aspect_ratios,
|
||||
getter = { it.aspectRatio },
|
||||
setter = { viewOptions, value -> viewOptions.copy(episodeAspectRatio = value) },
|
||||
indexToValue = { AspectRatio.entries[it] },
|
||||
valueToIndex = { it.ordinal },
|
||||
)
|
||||
|
||||
val ViewOptionsEpisodeImageType =
|
||||
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(episodeImageType = value, episodeAspectRatio = aspectRatio)
|
||||
},
|
||||
indexToValue = { ViewOptionImageType.entries[it] },
|
||||
valueToIndex = { it.ordinal },
|
||||
)
|
||||
|
||||
val OPTIONS =
|
||||
listOf(
|
||||
ViewOptionsImageType,
|
||||
ViewOptionsAspectRatio,
|
||||
// TODO
|
||||
PreferenceGroup(
|
||||
title = R.string.general,
|
||||
preferences =
|
||||
listOf(
|
||||
ViewOptionsImageType,
|
||||
ViewOptionsAspectRatio,
|
||||
// TODO
|
||||
// ViewOptionsShowTitles,
|
||||
ViewOptionsUseSeries,
|
||||
ViewOptionsCardHeight,
|
||||
ViewOptionsSpacing,
|
||||
ViewOptionsContentScale,
|
||||
ViewOptionsUseSeries,
|
||||
ViewOptionsCardHeight,
|
||||
ViewOptionsSpacing,
|
||||
ViewOptionsContentScale,
|
||||
// ViewOptionsApplyAll,
|
||||
ViewOptionsReset,
|
||||
ViewOptionsReset,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
val OPTIONS_EPISODES =
|
||||
listOf(
|
||||
PreferenceGroup(
|
||||
title = R.string.general,
|
||||
preferences =
|
||||
listOf(
|
||||
ViewOptionsCardHeight,
|
||||
ViewOptionsSpacing,
|
||||
ViewOptionsImageType,
|
||||
ViewOptionsAspectRatio,
|
||||
ViewOptionsUseSeries,
|
||||
ViewOptionsContentScale,
|
||||
ViewOptionsReset,
|
||||
),
|
||||
),
|
||||
PreferenceGroup(
|
||||
title = R.string.for_episodes,
|
||||
preferences =
|
||||
listOf(
|
||||
ViewOptionsEpisodeImageType,
|
||||
ViewOptionsEpisodeContentScale,
|
||||
ViewOptionsEpisodeAspectRatio,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
val GENRE_OPTIONS =
|
||||
listOf(
|
||||
ViewOptionsCardHeight,
|
||||
ViewOptionsSpacing,
|
||||
ViewOptionsReset,
|
||||
PreferenceGroup(
|
||||
title = R.string.general,
|
||||
preferences =
|
||||
listOf(
|
||||
ViewOptionsCardHeight,
|
||||
ViewOptionsSpacing,
|
||||
ViewOptionsReset,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,8 +151,21 @@ fun HomeSettingsPage(
|
|||
val row =
|
||||
state.rows
|
||||
.first { it.id == dest.rowId }
|
||||
val preferenceOptions =
|
||||
remember(row.config) {
|
||||
when (row.config) {
|
||||
is HomeRowConfig.ContinueWatching,
|
||||
is HomeRowConfig.ContinueWatchingCombined,
|
||||
-> Options.OPTIONS_EPISODES
|
||||
|
||||
is HomeRowConfig.Genres -> Options.GENRE_OPTIONS
|
||||
|
||||
else -> Options.OPTIONS
|
||||
}
|
||||
}
|
||||
HomeRowSettings(
|
||||
title = row.title,
|
||||
preferenceOptions = preferenceOptions,
|
||||
viewOptions = row.config.viewOptions,
|
||||
onViewOptionsChange = {
|
||||
viewModel.updateViewOptions(dest.rowId, it)
|
||||
|
|
@ -160,7 +173,6 @@ fun HomeSettingsPage(
|
|||
onApplyApplyAll = {
|
||||
viewModel.updateViewOptionsForAll(row.config.viewOptions)
|
||||
},
|
||||
userGenreSettings = row.config is HomeRowConfig.Genres,
|
||||
modifier = destModifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import kotlinx.serialization.Serializable
|
|||
/**
|
||||
* A group of preferences
|
||||
*/
|
||||
data class PreferenceGroup(
|
||||
data class PreferenceGroup<T>(
|
||||
@param:StringRes val title: Int,
|
||||
val preferences: List<AppPreference<AppPreferences, out Any?>>,
|
||||
val preferences: List<AppPreference<T, out Any?>>,
|
||||
val conditionalPreferences: List<ConditionalPreferences> = listOf(),
|
||||
)
|
||||
|
||||
|
|
@ -34,7 +34,6 @@ sealed interface PreferenceValidation {
|
|||
enum class PreferenceScreenOption {
|
||||
BASIC,
|
||||
ADVANCED,
|
||||
USER_INTERFACE,
|
||||
SUBTITLES,
|
||||
EXO_PLAYER,
|
||||
MPV,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ import com.github.damontecres.wholphin.preferences.MpvPreferences
|
|||
import com.github.damontecres.wholphin.preferences.PlayerBackend
|
||||
import com.github.damontecres.wholphin.preferences.advancedPreferences
|
||||
import com.github.damontecres.wholphin.preferences.basicPreferences
|
||||
import com.github.damontecres.wholphin.preferences.uiPreferences
|
||||
import com.github.damontecres.wholphin.preferences.updatePlaybackPreferences
|
||||
import com.github.damontecres.wholphin.services.UpdateChecker
|
||||
import com.github.damontecres.wholphin.ui.components.ConfirmDialog
|
||||
|
|
@ -125,7 +124,6 @@ fun PreferencesContent(
|
|||
when (preferenceScreenOption) {
|
||||
PreferenceScreenOption.BASIC -> basicPreferences
|
||||
PreferenceScreenOption.ADVANCED -> advancedPreferences
|
||||
PreferenceScreenOption.USER_INTERFACE -> uiPreferences
|
||||
PreferenceScreenOption.SUBTITLES -> SubtitleSettings.preferences
|
||||
PreferenceScreenOption.EXO_PLAYER -> ExoPlayerPreferences
|
||||
PreferenceScreenOption.MPV -> MpvPreferences
|
||||
|
|
@ -134,7 +132,6 @@ fun PreferencesContent(
|
|||
when (preferenceScreenOption) {
|
||||
PreferenceScreenOption.BASIC -> R.string.settings
|
||||
PreferenceScreenOption.ADVANCED -> R.string.advanced_settings
|
||||
PreferenceScreenOption.USER_INTERFACE -> R.string.ui_interface
|
||||
PreferenceScreenOption.SUBTITLES -> R.string.subtitle_style
|
||||
PreferenceScreenOption.EXO_PLAYER -> R.string.exoplayer_options
|
||||
PreferenceScreenOption.MPV -> R.string.mpv_options
|
||||
|
|
@ -526,7 +523,6 @@ fun PreferencesPage(
|
|||
when (preferenceScreenOption) {
|
||||
PreferenceScreenOption.BASIC,
|
||||
PreferenceScreenOption.ADVANCED,
|
||||
PreferenceScreenOption.USER_INTERFACE,
|
||||
PreferenceScreenOption.EXO_PLAYER,
|
||||
PreferenceScreenOption.MPV,
|
||||
-> {
|
||||
|
|
|
|||
|
|
@ -476,6 +476,7 @@
|
|||
<string name="add_row_for">Add row for %1$s</string>
|
||||
<string name="overwrite_server_settings">Overwrite settings on server?</string>
|
||||
<string name="overwrite_local_settings">Overwrite local settings?</string>
|
||||
<string name="for_episodes">For episodes</string>
|
||||
|
||||
<string-array name="theme_song_volume">
|
||||
<item>Disabled</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue