This commit is contained in:
Damontecres 2026-01-24 14:51:09 -05:00
parent b2016bf976
commit 84dc56289c
No known key found for this signature in database
9 changed files with 166 additions and 162 deletions

View file

@ -24,7 +24,7 @@ import com.github.damontecres.wholphin.ui.ifElse
import com.github.damontecres.wholphin.ui.tryRequestFocus import com.github.damontecres.wholphin.ui.tryRequestFocus
@Composable @Composable
fun HomePageLibraryRowTypeList( fun HomeLibraryRowTypeList(
library: Library, library: Library,
onClick: (LibraryRowType) -> Unit, onClick: (LibraryRowType) -> Unit,
modifier: Modifier, modifier: Modifier,

View file

@ -1,15 +0,0 @@
package com.github.damontecres.wholphin.ui.main.settings
sealed interface HomePageSettingsDestination {
data object RowList : HomePageSettingsDestination
data object ChooseLibrary : HomePageSettingsDestination
data class ChooseRowType(
val library: Library,
) : HomePageSettingsDestination
data class RowSettings(
val rowId: Int,
) : HomePageSettingsDestination
}

View file

@ -17,7 +17,7 @@ import com.github.damontecres.wholphin.preferences.AppPreference
import com.github.damontecres.wholphin.ui.preferences.ComposablePreference import com.github.damontecres.wholphin.ui.preferences.ComposablePreference
@Composable @Composable
fun HomePageRowSettings( fun HomeRowSettings(
title: String, title: String,
viewOptions: HomeRowViewOptions, viewOptions: HomeRowViewOptions,
onViewOptionsChange: (HomeRowViewOptions) -> Unit, onViewOptionsChange: (HomeRowViewOptions) -> Unit,

View file

@ -0,0 +1,18 @@
package com.github.damontecres.wholphin.ui.main.settings
/**
* Tracking the pages for selecting and configuring rows
*/
sealed interface HomeSettingsDestination {
data object RowList : HomeSettingsDestination
data object ChooseLibrary : HomeSettingsDestination
data class ChooseRowType(
val library: Library,
) : HomeSettingsDestination
data class RowSettings(
val rowId: Int,
) : HomeSettingsDestination
}

View file

@ -24,7 +24,7 @@ import com.github.damontecres.wholphin.ui.ifElse
import com.github.damontecres.wholphin.ui.tryRequestFocus import com.github.damontecres.wholphin.ui.tryRequestFocus
@Composable @Composable
fun HomePageLibraryList( fun HomeSettingsLibraryList(
libraries: List<Library>, libraries: List<Library>,
onClick: (Library) -> Unit, onClick: (Library) -> Unit,
onClickMeta: (MetaRowType) -> Unit, onClickMeta: (MetaRowType) -> Unit,

View file

@ -0,0 +1,130 @@
package com.github.damontecres.wholphin.ui.main.settings
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.tv.material3.MaterialTheme
import com.github.damontecres.wholphin.ui.main.HomePageContent
val settingsWidth = 300.dp
@Composable
fun HomeSettingsPage(
modifier: Modifier,
viewModel: HomeSettingsViewModel = hiltViewModel(),
) {
val state by viewModel.state.collectAsState()
val listState = rememberLazyListState()
var destination by remember { mutableStateOf<HomeSettingsDestination>(HomeSettingsDestination.RowList) }
BackHandler(destination is HomeSettingsDestination.ChooseRowType) {
destination = HomeSettingsDestination.ChooseLibrary
}
BackHandler(destination is HomeSettingsDestination.ChooseLibrary) {
destination = HomeSettingsDestination.RowList
}
BackHandler(destination is HomeSettingsDestination.RowSettings) {
destination = HomeSettingsDestination.RowList
}
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier,
) {
Box(
modifier =
Modifier
.width(settingsWidth)
.fillMaxHeight()
.background(color = MaterialTheme.colorScheme.surface),
) {
val destModifier =
Modifier
.fillMaxSize()
.padding(4.dp)
when (val dest = destination) {
HomeSettingsDestination.RowList -> {
HomeSettingsRowList(
state = state,
onClickAdd = { destination = HomeSettingsDestination.ChooseLibrary },
onClickMove = viewModel::moveRow,
onClickDelete = viewModel::deleteRow,
onClick = { index, row ->
destination = HomeSettingsDestination.RowSettings(row.config.id)
},
modifier = destModifier,
)
}
is HomeSettingsDestination.ChooseLibrary -> {
HomeSettingsLibraryList(
libraries = state.libraries,
onClick = { destination = HomeSettingsDestination.ChooseRowType(it) },
onClickMeta = {
viewModel.addRow(it)
destination = HomeSettingsDestination.RowList
},
modifier = destModifier,
)
}
is HomeSettingsDestination.ChooseRowType -> {
HomeLibraryRowTypeList(
library = dest.library,
onClick = {
viewModel.addRow(dest.library, it)
destination = HomeSettingsDestination.RowList
},
modifier = destModifier,
)
}
is HomeSettingsDestination.RowSettings -> {
val row =
state.rows
.first { it.config.id == dest.rowId }
HomeRowSettings(
title = row.title,
viewOptions = row.config.viewOptions,
onViewOptionsChange = {
viewModel.updateViewOptions(dest.rowId, it)
},
onApplyApplyAll = {
viewModel.updateViewOptionsForAll(row.config.viewOptions)
},
modifier = destModifier,
)
}
}
}
HomePageContent(
loadingState = state.loading,
homeRows = state.rowData,
onClickItem = { _, _ -> },
onLongClickItem = { _, _ -> },
onClickPlay = { _, _ -> },
showClock = false,
onUpdateBackdrop = viewModel::updateBackdrop,
listState = listState,
modifier =
Modifier
.fillMaxHeight()
.weight(1f),
)
}
}

View file

@ -41,7 +41,7 @@ enum class MoveDirection {
} }
@Composable @Composable
fun HomePageRowList( fun HomeSettingsRowList(
state: HomePageSettingsState, state: HomePageSettingsState,
onClick: (Int, HomeRowConfigDisplay) -> Unit, onClick: (Int, HomeRowConfigDisplay) -> Unit,
onClickAdd: () -> Unit, onClickAdd: () -> Unit,

View file

@ -1,29 +1,9 @@
package com.github.damontecres.wholphin.ui.main.settings package com.github.damontecres.wholphin.ui.main.settings
import android.content.Context import android.content.Context
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.tv.material3.MaterialTheme
import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.NavDrawerItemRepository import com.github.damontecres.wholphin.data.NavDrawerItemRepository
import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.ServerRepository
@ -40,12 +20,10 @@ import com.github.damontecres.wholphin.ui.DefaultItemFields
import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.components.getGenreImageMap import com.github.damontecres.wholphin.ui.components.getGenreImageMap
import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.main.HomePageContent
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
import com.github.damontecres.wholphin.util.GetGenresRequestHandler import com.github.damontecres.wholphin.util.GetGenresRequestHandler
import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler
import com.github.damontecres.wholphin.util.HomeRowLoadingState import com.github.damontecres.wholphin.util.HomeRowLoadingState
import com.github.damontecres.wholphin.util.HomeRowLoadingState.Success
import com.github.damontecres.wholphin.util.LoadingState import com.github.damontecres.wholphin.util.LoadingState
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
@ -66,7 +44,7 @@ import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel
class HomePageSettingsViewModel class HomeSettingsViewModel
@Inject @Inject
constructor( constructor(
@param:ApplicationContext private val context: Context, @param:ApplicationContext private val context: Context,
@ -215,7 +193,7 @@ class HomePageSettingsViewModel
is HomeRowConfig.ContinueWatching -> { is HomeRowConfig.ContinueWatching -> {
val resume = latestNextUpService.getResume(userDto.id, limit, true) val resume = latestNextUpService.getResume(userDto.id, limit, true)
listOf( listOf(
Success( HomeRowLoadingState.Success(
title = context.getString(R.string.continue_watching), title = context.getString(R.string.continue_watching),
items = resume, items = resume,
viewOptions = row.viewOptions, viewOptions = row.viewOptions,
@ -232,7 +210,7 @@ class HomePageSettingsViewModel
false, false,
) )
listOf( listOf(
Success( HomeRowLoadingState.Success(
title = context.getString(R.string.next_up), title = context.getString(R.string.next_up),
items = nextUp, items = nextUp,
viewOptions = row.viewOptions, viewOptions = row.viewOptions,
@ -252,7 +230,7 @@ class HomePageSettingsViewModel
) )
listOf( listOf(
Success( HomeRowLoadingState.Success(
title = context.getString(R.string.continue_watching), title = context.getString(R.string.continue_watching),
items = items =
latestNextUpService.buildCombined( latestNextUpService.buildCombined(
@ -298,7 +276,7 @@ class HomePageSettingsViewModel
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( listOf(
Success( HomeRowLoadingState.Success(
title, title,
genres, genres,
viewOptions = row.viewOptions, viewOptions = row.viewOptions,
@ -327,9 +305,9 @@ class HomePageSettingsViewModel
api.userLibraryApi api.userLibraryApi
.getLatestMedia(request) .getLatestMedia(request)
.content .content
.map { BaseItem.from(it, api, true) } .map { BaseItem.Companion.from(it, api, true) }
.let { .let {
Success( HomeRowLoadingState.Success(
title, title,
it, it,
row.viewOptions, row.viewOptions,
@ -359,10 +337,10 @@ class HomePageSettingsViewModel
GetItemsRequestHandler GetItemsRequestHandler
.execute(api, request) .execute(api, request)
.content.items .content.items
.map { BaseItem.from(it, api, true) } .map { BaseItem.Companion.from(it, api, true) }
.let { .let {
listOf( listOf(
Success( HomeRowLoadingState.Success(
title, title,
it, it,
row.viewOptions, row.viewOptions,
@ -392,7 +370,7 @@ class HomePageSettingsViewModel
.map { BaseItem(it, true) } .map { BaseItem(it, true) }
.let { .let {
listOf( listOf(
Success( HomeRowLoadingState.Success(
name ?: context.getString(R.string.collection), name ?: context.getString(R.string.collection),
it, it,
row.viewOptions, row.viewOptions,
@ -427,10 +405,10 @@ class HomePageSettingsViewModel
GetItemsRequestHandler GetItemsRequestHandler
.execute(api, request) .execute(api, request)
.content.items .content.items
.map { BaseItem.from(it, api, true) } .map { BaseItem.Companion.from(it, api, true) }
.let { .let {
listOf( listOf(
Success( HomeRowLoadingState.Success(
name ?: context.getString(R.string.collection), name ?: context.getString(R.string.collection),
it, it,
row.viewOptions, row.viewOptions,
@ -662,110 +640,3 @@ data class Library(
val name: String, val name: String,
val collectionType: CollectionType, val collectionType: CollectionType,
) )
val settingsWidth = 300.dp
@Composable
fun HomePageSettings(
modifier: Modifier,
viewModel: HomePageSettingsViewModel = hiltViewModel(),
) {
val state by viewModel.state.collectAsState()
val listState = rememberLazyListState()
var destination by remember { mutableStateOf<HomePageSettingsDestination>(HomePageSettingsDestination.RowList) }
BackHandler(destination is HomePageSettingsDestination.ChooseRowType) {
destination = HomePageSettingsDestination.ChooseLibrary
}
BackHandler(destination is HomePageSettingsDestination.ChooseLibrary) {
destination = HomePageSettingsDestination.RowList
}
BackHandler(destination is HomePageSettingsDestination.RowSettings) {
destination = HomePageSettingsDestination.RowList
}
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier,
) {
Box(
modifier =
Modifier
.width(settingsWidth)
.fillMaxHeight()
.background(color = MaterialTheme.colorScheme.surface),
) {
val destModifier =
Modifier
.fillMaxSize()
.padding(4.dp)
when (val dest = destination) {
HomePageSettingsDestination.RowList -> {
HomePageRowList(
state = state,
onClickAdd = { destination = HomePageSettingsDestination.ChooseLibrary },
onClickMove = viewModel::moveRow,
onClickDelete = viewModel::deleteRow,
onClick = { index, row ->
destination = HomePageSettingsDestination.RowSettings(row.config.id)
},
modifier = destModifier,
)
}
is HomePageSettingsDestination.ChooseLibrary -> {
HomePageLibraryList(
libraries = state.libraries,
onClick = { destination = HomePageSettingsDestination.ChooseRowType(it) },
onClickMeta = {
viewModel.addRow(it)
destination = HomePageSettingsDestination.RowList
},
modifier = destModifier,
)
}
is HomePageSettingsDestination.ChooseRowType -> {
HomePageLibraryRowTypeList(
library = dest.library,
onClick = {
viewModel.addRow(dest.library, it)
destination = HomePageSettingsDestination.RowList
},
modifier = destModifier,
)
}
is HomePageSettingsDestination.RowSettings -> {
val row =
state.rows
.first { it.config.id == dest.rowId }
HomePageRowSettings(
title = row.title,
viewOptions = row.config.viewOptions,
onViewOptionsChange = {
viewModel.updateViewOptions(dest.rowId, it)
},
onApplyApplyAll = {
viewModel.updateViewOptionsForAll(row.config.viewOptions)
},
modifier = destModifier,
)
}
}
}
HomePageContent(
loadingState = state.loading,
homeRows = state.rowData,
onClickItem = { _, _ -> },
onLongClickItem = { _, _ -> },
onClickPlay = { _, _ -> },
showClock = false,
onUpdateBackdrop = viewModel::updateBackdrop,
listState = listState,
modifier =
Modifier
.fillMaxHeight()
.weight(1f),
)
}
}

View file

@ -32,7 +32,7 @@ import com.github.damontecres.wholphin.ui.detail.series.SeriesOverview
import com.github.damontecres.wholphin.ui.discover.DiscoverPage import com.github.damontecres.wholphin.ui.discover.DiscoverPage
import com.github.damontecres.wholphin.ui.main.HomePage import com.github.damontecres.wholphin.ui.main.HomePage
import com.github.damontecres.wholphin.ui.main.SearchPage import com.github.damontecres.wholphin.ui.main.SearchPage
import com.github.damontecres.wholphin.ui.main.settings.HomePageSettings import com.github.damontecres.wholphin.ui.main.settings.HomeSettingsPage
import com.github.damontecres.wholphin.ui.playback.PlaybackPage import com.github.damontecres.wholphin.ui.playback.PlaybackPage
import com.github.damontecres.wholphin.ui.preferences.PreferencesPage import com.github.damontecres.wholphin.ui.preferences.PreferencesPage
import com.github.damontecres.wholphin.ui.setup.InstallUpdatePage import com.github.damontecres.wholphin.ui.setup.InstallUpdatePage
@ -62,7 +62,7 @@ fun DestinationContent(
} }
is Destination.HomeSettings -> { is Destination.HomeSettings -> {
HomePageSettings(modifier) HomeSettingsPage(modifier)
} }
is Destination.PlaybackList, is Destination.PlaybackList,