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 955a173d..b6a784b0 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 @@ -33,6 +33,7 @@ import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi +import org.jellyfin.sdk.api.client.extensions.liveTvApi import org.jellyfin.sdk.api.client.extensions.userApi import org.jellyfin.sdk.api.client.extensions.userLibraryApi import org.jellyfin.sdk.api.client.extensions.userViewsApi @@ -46,6 +47,7 @@ import org.jellyfin.sdk.model.api.request.GetGenresRequest import org.jellyfin.sdk.model.api.request.GetItemsRequest import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest import org.jellyfin.sdk.model.api.request.GetPersonsRequest +import org.jellyfin.sdk.model.api.request.GetRecommendedProgramsRequest import org.jellyfin.sdk.model.api.request.GetRecordingsRequest import timber.log.Timber import java.io.File @@ -315,8 +317,11 @@ class HomeSettingsService val config = when (sectionType) { HomeSectionType.ACTIVE_RECORDINGS -> { - // GetRecordingsRequest - TODO() + HomeRowConfigDisplay( + id = id++, + title = context.getString(R.string.active_recordings), + config = HomeRowConfig.Recordings(), + ) } HomeSectionType.RESUME -> { @@ -337,8 +342,11 @@ class HomeSettingsService HomeSectionType.LIVE_TV -> { if (userDto.policy?.enableLiveTvAccess == true) { - // GetRecommendedProgramsRequest - TODO() + HomeRowConfigDisplay( + id = id++, + title = context.getString(R.string.live_tv), + config = HomeRowConfig.TvPrograms(), + ) } else { null } @@ -478,11 +486,19 @@ class HomeSettingsService } is HomeRowConfig.Recordings -> { - TODO() + HomeRowConfigDisplay( + id = id, + title = context.getString(R.string.active_recordings), + config, + ) } is HomeRowConfig.TvPrograms -> { - TODO() + HomeRowConfigDisplay( + id = id, + title = context.getString(R.string.live_tv), + config, + ) } } @@ -753,12 +769,48 @@ class HomeSettingsService } is HomeRowConfig.Recordings -> { - GetRecordingsRequest() - TODO() + val request = + GetRecordingsRequest( + userId = userDto.id, + isInProgress = true, + fields = DefaultItemFields, + limit = limit, + enableImages = true, + enableUserData = true, + ) + api.liveTvApi + .getRecordings(request) + .content.items + .map { BaseItem(it, true) } + .let { + Success( + context.getString(R.string.active_recordings), + it, + row.viewOptions, + ) + } } is HomeRowConfig.TvPrograms -> { - TODO() + val request = + GetRecommendedProgramsRequest( + userId = userDto.id, + fields = DefaultItemFields, + limit = limit, + enableImages = true, + enableUserData = true, + ) + api.liveTvApi + .getRecommendedPrograms(request) + .content.items + .map { BaseItem(it, true) } + .let { + Success( + context.getString(R.string.live_tv), + it, + row.viewOptions, + ) + } } } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsLibraryList.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsAddRow.kt similarity index 99% rename from app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsLibraryList.kt rename to app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsAddRow.kt index e8dd5c6c..7fa15ceb 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsLibraryList.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsAddRow.kt @@ -28,7 +28,7 @@ import com.github.damontecres.wholphin.ui.ifElse import com.github.damontecres.wholphin.ui.tryRequestFocus @Composable -fun HomeSettingsLibraryList( +fun HomeSettingsAddRow( libraries: List, showDiscover: Boolean, onClick: (Library) -> Unit, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsDestination.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsDestination.kt index e3f4cb62..7aa65db9 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsDestination.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/settings/HomeSettingsDestination.kt @@ -1,24 +1,32 @@ package com.github.damontecres.wholphin.ui.main.settings import androidx.navigation3.runtime.NavKey +import kotlinx.serialization.Serializable /** * Tracking the pages for selecting and configuring rows */ +@Serializable sealed interface HomeSettingsDestination : NavKey { + @Serializable data object RowList : HomeSettingsDestination - data object ChooseLibrary : HomeSettingsDestination + @Serializable + data object AddRow : HomeSettingsDestination + @Serializable data class ChooseRowType( val library: Library, ) : HomeSettingsDestination + @Serializable data class RowSettings( val rowId: Int, ) : HomeSettingsDestination + @Serializable data object ChooseFavorite : HomeSettingsDestination + @Serializable data object ChooseDiscover : HomeSettingsDestination } 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 ae605e9a..3c3bdf9b 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 @@ -1,6 +1,5 @@ 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 @@ -13,14 +12,17 @@ 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.rememberCoroutineScope -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.navigation3.rememberViewModelStoreNavEntryDecorator +import androidx.navigation3.runtime.NavEntry +import androidx.navigation3.runtime.rememberNavBackStack +import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator +import androidx.navigation3.ui.NavDisplay import androidx.tv.material3.MaterialTheme +import androidx.tv.material3.surfaceColorAtElevation import com.github.damontecres.wholphin.ui.main.HomePageContent import com.github.damontecres.wholphin.ui.main.settings.HomeSettingsDestination.ChooseRowType import com.github.damontecres.wholphin.ui.main.settings.HomeSettingsDestination.RowSettings @@ -37,20 +39,11 @@ fun HomeSettingsPage( ) { val scope = rememberCoroutineScope() val listState = rememberLazyListState() - var destination by remember { mutableStateOf(HomeSettingsDestination.RowList) } + val backStack = rememberNavBackStack(HomeSettingsDestination.RowList) val state by viewModel.state.collectAsState() val discoverEnabled by viewModel.discoverEnabled.collectAsState(false) - BackHandler(destination is ChooseRowType) { - destination = HomeSettingsDestination.ChooseLibrary - } - BackHandler(destination is HomeSettingsDestination.ChooseLibrary) { - destination = HomeSettingsDestination.RowList - } - BackHandler(destination is RowSettings) { - destination = HomeSettingsDestination.RowList - } Row( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = modifier, @@ -62,100 +55,115 @@ fun HomeSettingsPage( .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 }, - onClickSaveLocal = { viewModel.saveToLocal() }, - onClickMove = viewModel::moveRow, - onClickDelete = viewModel::deleteRow, - onClick = { index, row -> - destination = RowSettings(row.id) - scope.launch(ExceptionHandler()) { - Timber.v("Scroll to $index") - listState.scrollToItem(index) + NavDisplay( + backStack = backStack, +// onBack = { navigationManager.goBack() }, + entryDecorators = + listOf( + rememberSaveableStateHolderNavEntryDecorator(), + rememberViewModelStoreNavEntryDecorator(), + ), + modifier = Modifier.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)), + entryProvider = { key -> + key as HomeSettingsDestination + NavEntry(key, contentKey = key.toString()) { + val destModifier = + Modifier + .fillMaxSize() + .padding(4.dp) + when (val dest = key) { + HomeSettingsDestination.RowList -> { + HomeSettingsRowList( + state = state, + onClickAdd = { backStack.add(HomeSettingsDestination.AddRow) }, + onClickSaveLocal = { viewModel.saveToLocal() }, + onClickMove = viewModel::moveRow, + onClickDelete = viewModel::deleteRow, + onClick = { index, row -> + backStack.add(RowSettings(row.id)) + scope.launch(ExceptionHandler()) { + Timber.v("Scroll to $index") + listState.scrollToItem(index) + } + }, + onClickResize = { + viewModel.resizeCards(it) + }, + modifier = destModifier, + ) } - }, - onClickResize = { - viewModel.resizeCards(it) - }, - modifier = destModifier, - ) - } - is HomeSettingsDestination.ChooseLibrary -> { - HomeSettingsLibraryList( - libraries = state.libraries, - showDiscover = discoverEnabled, - onClick = { destination = ChooseRowType(it) }, - onClickMeta = { - when (it) { - MetaRowType.CONTINUE_WATCHING, - MetaRowType.NEXT_UP, - MetaRowType.COMBINED_CONTINUE_WATCHING, - -> { - viewModel.addRow(it) - destination = HomeSettingsDestination.RowList - } + is HomeSettingsDestination.AddRow -> { + HomeSettingsAddRow( + libraries = state.libraries, + showDiscover = discoverEnabled, + onClick = { backStack.add(ChooseRowType(it)) }, + onClickMeta = { + when (it) { + MetaRowType.CONTINUE_WATCHING, + MetaRowType.NEXT_UP, + MetaRowType.COMBINED_CONTINUE_WATCHING, + -> { + viewModel.addRow(it) + backStack.add(HomeSettingsDestination.RowList) + } - MetaRowType.FAVORITES -> { - destination = HomeSettingsDestination.ChooseFavorite - } + MetaRowType.FAVORITES -> { + backStack.add(HomeSettingsDestination.ChooseFavorite) + } - MetaRowType.DISCOVER -> { - destination = HomeSettingsDestination.ChooseDiscover - } + MetaRowType.DISCOVER -> { + backStack.add(HomeSettingsDestination.ChooseDiscover) + } + } + }, + modifier = destModifier, + ) } - }, - modifier = destModifier, - ) - } - is ChooseRowType -> { - HomeLibraryRowTypeList( - library = dest.library, - onClick = { - viewModel.addRow(dest.library, it) - destination = HomeSettingsDestination.RowList - }, - modifier = destModifier, - ) - } + is ChooseRowType -> { + HomeLibraryRowTypeList( + library = dest.library, + onClick = { + viewModel.addRow(dest.library, it) + backStack.add(HomeSettingsDestination.RowList) + }, + modifier = destModifier, + ) + } - is RowSettings -> { - val row = - state.rows - .first { it.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, - ) - } + is RowSettings -> { + val row = + state.rows + .first { it.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, + ) + } - HomeSettingsDestination.ChooseDiscover -> { - TODO() - } + HomeSettingsDestination.ChooseDiscover -> { + TODO() + } - HomeSettingsDestination.ChooseFavorite -> { - HomeSettingsFavoriteList( - onClick = { type -> - viewModel.addFavoriteRow(type) - }, - ) - } - } + HomeSettingsDestination.ChooseFavorite -> { + HomeSettingsFavoriteList( + onClick = { type -> + viewModel.addFavoriteRow(type) + }, + ) + } + } + } + }, + ) } HomePageContent( loadingState = state.loading, 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 1e89437a..348cbf7b 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 @@ -34,8 +34,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update +import kotlinx.serialization.Serializable import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.CollectionType +import org.jellyfin.sdk.model.serializer.UUIDSerializer import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -400,8 +402,9 @@ data class HomePageSettingsState( } @Immutable +@Serializable data class Library( - val itemId: UUID, + @Serializable(UUIDSerializer::class) val itemId: UUID, val name: String, val collectionType: CollectionType, )