From efb87bd692556723bdad6d7be2d69ad4c98d2c93 Mon Sep 17 00:00:00 2001 From: Damontecres Date: Sun, 25 Jan 2026 19:01:33 -0500 Subject: [PATCH] UI controls --- .../damontecres/wholphin/MainActivity.kt | 4 +- .../wholphin/data/model/HomeRowConfig.kt | 113 +---------------- .../wholphin/services/HomeSettingsService.kt | 13 +- .../ui/main/settings/HomeRowSettings.kt | 119 +++++++++++++++++- .../ui/main/settings/HomeSettingsPage.kt | 3 + .../ui/main/settings/HomeSettingsRowList.kt | 38 ++++++ .../ui/main/settings/HomeSettingsViewModel.kt | 22 ++++ 7 files changed, 186 insertions(+), 126 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt b/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt index c7b12bfc..b6772df8 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/MainActivity.kt @@ -265,7 +265,9 @@ class MainActivity : AppCompatActivity() { server = current.server, startDestination = requestedDestination - ?: Destination.Home(), + // TODO undo after testing + // ?: Destination.Home(), + ?: Destination.HomeSettings, navigationManager = navigationManager, preferences = preferences, modifier = Modifier.fillMaxSize(), diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/model/HomeRowConfig.kt b/app/src/main/java/com/github/damontecres/wholphin/data/model/HomeRowConfig.kt index 8e98d947..46c3e664 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/model/HomeRowConfig.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/model/HomeRowConfig.kt @@ -2,16 +2,10 @@ 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.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.data.SortAndDirection import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -160,109 +154,6 @@ data class HomeRowViewOptions( val contentScale: PrefContentScale = PrefContentScale.FIT, val aspectRatio: AspectRatio = AspectRatio.TALL, val imageType: ViewOptionImageType = ViewOptionImageType.PRIMARY, - val showTitles: Boolean = true, + val showTitles: Boolean = false, val useSeries: Boolean = true, -) { - companion object { - val ViewOptionsColumns = - AppSliderPreference( - title = R.string.height, - defaultValue = Cards.HEIGHT_2X3_DP.toLong(), - min = 64L, - max = Cards.HEIGHT_2X3_DP + 64L, - interval = 4, - getter = { it.heightDp.toLong() }, - setter = { prefs, value -> prefs.copy(heightDp = value.toInt()) }, - ) - val ViewOptionsSpacing = - AppSliderPreference( - 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( - 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( - 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( - title = R.string.show_titles, - defaultValue = true, - getter = { it.showTitles }, - setter = { vo, value -> vo.copy(showTitles = value) }, - ) - - val ViewOptionsUseSeries = - AppSwitchPreference( - title = R.string.go_to_series, // TODO - defaultValue = true, - getter = { it.useSeries }, - setter = { vo, value -> vo.copy(useSeries = value) }, - ) - - val ViewOptionsImageType = - AppChoicePreference( - 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 ViewOptionsApplyAll = - AppClickablePreference( - title = R.string.apply_all_rows, - ) - - val ViewOptionsReset = - AppClickablePreference( - title = R.string.reset, - ) - - val OPTIONS = - listOf( - ViewOptionsImageType, - ViewOptionsAspectRatio, - // TODO -// ViewOptionsShowTitles, -// ViewOptionsUseSeries, - ViewOptionsColumns, - ViewOptionsSpacing, - ViewOptionsContentScale, - ViewOptionsApplyAll, - ViewOptionsReset, - ) - } -} +) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt index c1c4d730..94766fb8 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/HomeSettingsService.kt @@ -550,22 +550,13 @@ class HomeSettingsService ) } } - val name = - if (row.name == null && request.parentId != null) { - // If a name was not provided, use the parent's name if available - api.userLibraryApi - .getItem(itemId = request.parentId!!) - .content.name - } else { - row.name - } GetItemsRequestHandler .execute(api, request) .content.items - .map { BaseItem.Companion.from(it, api, true) } + .map { BaseItem(it, true) } .let { HomeRowLoadingState.Success( - name ?: context.getString(R.string.collection), + row.name, it, row.viewOptions, ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowSettings.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowSettings.kt index 5946fe4b..5858a028 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowSettings.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeRowSettings.kt @@ -15,8 +15,18 @@ 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.R import com.github.damontecres.wholphin.data.model.HomeRowViewOptions +import com.github.damontecres.wholphin.preferences.AppChoicePreference +import com.github.damontecres.wholphin.preferences.AppClickablePreference import com.github.damontecres.wholphin.preferences.AppPreference +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.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.tryRequestFocus @@ -39,7 +49,7 @@ fun HomeRowSettings( color = MaterialTheme.colorScheme.onSurface, ) LazyColumn { - itemsIndexed(HomeRowViewOptions.OPTIONS) { index, pref -> + itemsIndexed(Options.OPTIONS) { index, pref -> pref as AppPreference val interactionSource = remember { MutableInteractionSource() } val value = pref.getter.invoke(viewOptions) @@ -52,9 +62,9 @@ fun HomeRowSettings( }, interactionSource = interactionSource, onClickPreference = { pref -> - if (pref == HomeRowViewOptions.ViewOptionsReset) { + if (pref == Options.ViewOptionsReset) { onViewOptionsChange.invoke(defaultViewOptions) - } else if (pref == HomeRowViewOptions.ViewOptionsApplyAll) { + } else if (pref == Options.ViewOptionsApplyAll) { onApplyApplyAll.invoke() } }, @@ -70,3 +80,106 @@ fun HomeRowSettings( } } } + +internal object Options { + val ViewOptionsColumns = + AppSliderPreference( + title = R.string.height, + defaultValue = Cards.HEIGHT_2X3_DP.toLong(), + min = 64L, + max = Cards.HEIGHT_2X3_DP + 64L, + interval = 4, + getter = { it.heightDp.toLong() }, + setter = { prefs, value -> prefs.copy(heightDp = value.toInt()) }, + ) + val ViewOptionsSpacing = + AppSliderPreference( + 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( + 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( + 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( + title = R.string.show_titles, + defaultValue = true, + getter = { it.showTitles }, + setter = { vo, value -> vo.copy(showTitles = value) }, + ) + + val ViewOptionsUseSeries = + AppSwitchPreference( + title = R.string.go_to_series, // TODO + defaultValue = true, + getter = { it.useSeries }, + setter = { vo, value -> vo.copy(useSeries = value) }, + ) + + val ViewOptionsImageType = + AppChoicePreference( + 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 ViewOptionsApplyAll = + AppClickablePreference( + title = R.string.apply_all_rows, + ) + + val ViewOptionsReset = + AppClickablePreference( + title = R.string.reset, + ) + + val OPTIONS = + listOf( + ViewOptionsImageType, + ViewOptionsAspectRatio, + // TODO +// ViewOptionsShowTitles, +// ViewOptionsUseSeries, + ViewOptionsColumns, + ViewOptionsSpacing, + ViewOptionsContentScale, + ViewOptionsApplyAll, + ViewOptionsReset, + ) +} diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsPage.kt index 56aee366..289d1e85 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsPage.kt @@ -78,6 +78,9 @@ fun HomeSettingsPage( listState.scrollToItem(index) } }, + onClickResize = { + viewModel.resizeCards(it) + }, modifier = destModifier, ) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt index 52cd0f83..c6761776 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsRowList.kt @@ -16,6 +16,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Create import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -48,6 +49,7 @@ enum class MoveDirection { fun HomeSettingsRowList( state: HomePageSettingsState, onClick: (Int, HomeRowConfigDisplay) -> Unit, + onClickResize: (Int) -> Unit, onClickSaveLocal: () -> Unit, onClickAdd: () -> Unit, onClickMove: (MoveDirection, Int) -> Unit, @@ -82,6 +84,42 @@ fun HomeSettingsRowList( modifier = Modifier.focusRequester(firstFocus), ) } + item { + ListItem( + selected = false, + headlineContent = { + Text( + text = "Increase card sizes", + ) + }, + leadingContent = { + Icon( + imageVector = Icons.Default.Edit, + contentDescription = null, + ) + }, + onClick = { onClickResize.invoke(1) }, + modifier = Modifier, + ) + } + item { + ListItem( + selected = false, + headlineContent = { + Text( + text = "Decrease card sizes", + ) + }, + leadingContent = { + Icon( + imageVector = Icons.Default.Edit, + contentDescription = null, + ) + }, + onClick = { onClickResize.invoke(-1) }, + modifier = Modifier, + ) + } item { ListItem( selected = false, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt index 0881dc72..a5c1293d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsViewModel.kt @@ -322,6 +322,28 @@ class HomeSettingsViewModel } homeSettingsService.currentSettings.update { HomePageResolvedSettings(state.value.rows) } } + + fun resizeCards(relative: Int) { + updateState { + val newRows = + it.rows.toMutableList().map { row -> + val vo = row.config.viewOptions + val newVo = vo.copy(heightDp = vo.heightDp + (4 * relative)) + row.copy(config = row.config.updateViewOptions(newVo)) + } + it.copy( + rows = newRows, + rowData = + it.rowData.toMutableList().mapIndexed { index, row -> + if (row is HomeRowLoadingState.Success) { + row.copy(viewOptions = newRows[index].config.viewOptions) + } else { + row + } + }, + ) + } + } } data class HomePageSettingsState(