mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Use navigation
This commit is contained in:
parent
01bdf2cefa
commit
75183802e7
5 changed files with 182 additions and 111 deletions
|
|
@ -33,6 +33,7 @@ import kotlinx.serialization.json.jsonArray
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
import org.jellyfin.sdk.api.client.extensions.displayPreferencesApi
|
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.userApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userViewsApi
|
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.GetItemsRequest
|
||||||
import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest
|
import org.jellyfin.sdk.model.api.request.GetLatestMediaRequest
|
||||||
import org.jellyfin.sdk.model.api.request.GetPersonsRequest
|
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 org.jellyfin.sdk.model.api.request.GetRecordingsRequest
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -315,8 +317,11 @@ class HomeSettingsService
|
||||||
val config =
|
val config =
|
||||||
when (sectionType) {
|
when (sectionType) {
|
||||||
HomeSectionType.ACTIVE_RECORDINGS -> {
|
HomeSectionType.ACTIVE_RECORDINGS -> {
|
||||||
// GetRecordingsRequest
|
HomeRowConfigDisplay(
|
||||||
TODO()
|
id = id++,
|
||||||
|
title = context.getString(R.string.active_recordings),
|
||||||
|
config = HomeRowConfig.Recordings(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
HomeSectionType.RESUME -> {
|
HomeSectionType.RESUME -> {
|
||||||
|
|
@ -337,8 +342,11 @@ class HomeSettingsService
|
||||||
|
|
||||||
HomeSectionType.LIVE_TV -> {
|
HomeSectionType.LIVE_TV -> {
|
||||||
if (userDto.policy?.enableLiveTvAccess == true) {
|
if (userDto.policy?.enableLiveTvAccess == true) {
|
||||||
// GetRecommendedProgramsRequest
|
HomeRowConfigDisplay(
|
||||||
TODO()
|
id = id++,
|
||||||
|
title = context.getString(R.string.live_tv),
|
||||||
|
config = HomeRowConfig.TvPrograms(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
@ -478,11 +486,19 @@ class HomeSettingsService
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowConfig.Recordings -> {
|
is HomeRowConfig.Recordings -> {
|
||||||
TODO()
|
HomeRowConfigDisplay(
|
||||||
|
id = id,
|
||||||
|
title = context.getString(R.string.active_recordings),
|
||||||
|
config,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowConfig.TvPrograms -> {
|
is HomeRowConfig.TvPrograms -> {
|
||||||
TODO()
|
HomeRowConfigDisplay(
|
||||||
|
id = id,
|
||||||
|
title = context.getString(R.string.live_tv),
|
||||||
|
config,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -753,12 +769,48 @@ class HomeSettingsService
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeRowConfig.Recordings -> {
|
is HomeRowConfig.Recordings -> {
|
||||||
GetRecordingsRequest()
|
val request =
|
||||||
TODO()
|
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 -> {
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,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 HomeSettingsLibraryList(
|
fun HomeSettingsAddRow(
|
||||||
libraries: List<Library>,
|
libraries: List<Library>,
|
||||||
showDiscover: Boolean,
|
showDiscover: Boolean,
|
||||||
onClick: (Library) -> Unit,
|
onClick: (Library) -> Unit,
|
||||||
|
|
@ -1,24 +1,32 @@
|
||||||
package com.github.damontecres.wholphin.ui.main.settings
|
package com.github.damontecres.wholphin.ui.main.settings
|
||||||
|
|
||||||
import androidx.navigation3.runtime.NavKey
|
import androidx.navigation3.runtime.NavKey
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracking the pages for selecting and configuring rows
|
* Tracking the pages for selecting and configuring rows
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
sealed interface HomeSettingsDestination : NavKey {
|
sealed interface HomeSettingsDestination : NavKey {
|
||||||
|
@Serializable
|
||||||
data object RowList : HomeSettingsDestination
|
data object RowList : HomeSettingsDestination
|
||||||
|
|
||||||
data object ChooseLibrary : HomeSettingsDestination
|
@Serializable
|
||||||
|
data object AddRow : HomeSettingsDestination
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data class ChooseRowType(
|
data class ChooseRowType(
|
||||||
val library: Library,
|
val library: Library,
|
||||||
) : HomeSettingsDestination
|
) : HomeSettingsDestination
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data class RowSettings(
|
data class RowSettings(
|
||||||
val rowId: Int,
|
val rowId: Int,
|
||||||
) : HomeSettingsDestination
|
) : HomeSettingsDestination
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data object ChooseFavorite : HomeSettingsDestination
|
data object ChooseFavorite : HomeSettingsDestination
|
||||||
|
|
||||||
|
@Serializable
|
||||||
data object ChooseDiscover : HomeSettingsDestination
|
data object ChooseDiscover : HomeSettingsDestination
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.github.damontecres.wholphin.ui.main.settings
|
package com.github.damontecres.wholphin.ui.main.settings
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
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.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
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.MaterialTheme
|
||||||
|
import androidx.tv.material3.surfaceColorAtElevation
|
||||||
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
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.ChooseRowType
|
||||||
import com.github.damontecres.wholphin.ui.main.settings.HomeSettingsDestination.RowSettings
|
import com.github.damontecres.wholphin.ui.main.settings.HomeSettingsDestination.RowSettings
|
||||||
|
|
@ -37,20 +39,11 @@ fun HomeSettingsPage(
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
var destination by remember { mutableStateOf<HomeSettingsDestination>(HomeSettingsDestination.RowList) }
|
val backStack = rememberNavBackStack(HomeSettingsDestination.RowList)
|
||||||
|
|
||||||
val state by viewModel.state.collectAsState()
|
val state by viewModel.state.collectAsState()
|
||||||
val discoverEnabled by viewModel.discoverEnabled.collectAsState(false)
|
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(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -62,20 +55,32 @@ fun HomeSettingsPage(
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.background(color = MaterialTheme.colorScheme.surface),
|
.background(color = MaterialTheme.colorScheme.surface),
|
||||||
) {
|
) {
|
||||||
|
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 =
|
val destModifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(4.dp)
|
.padding(4.dp)
|
||||||
when (val dest = destination) {
|
when (val dest = key) {
|
||||||
HomeSettingsDestination.RowList -> {
|
HomeSettingsDestination.RowList -> {
|
||||||
HomeSettingsRowList(
|
HomeSettingsRowList(
|
||||||
state = state,
|
state = state,
|
||||||
onClickAdd = { destination = HomeSettingsDestination.ChooseLibrary },
|
onClickAdd = { backStack.add(HomeSettingsDestination.AddRow) },
|
||||||
onClickSaveLocal = { viewModel.saveToLocal() },
|
onClickSaveLocal = { viewModel.saveToLocal() },
|
||||||
onClickMove = viewModel::moveRow,
|
onClickMove = viewModel::moveRow,
|
||||||
onClickDelete = viewModel::deleteRow,
|
onClickDelete = viewModel::deleteRow,
|
||||||
onClick = { index, row ->
|
onClick = { index, row ->
|
||||||
destination = RowSettings(row.id)
|
backStack.add(RowSettings(row.id))
|
||||||
scope.launch(ExceptionHandler()) {
|
scope.launch(ExceptionHandler()) {
|
||||||
Timber.v("Scroll to $index")
|
Timber.v("Scroll to $index")
|
||||||
listState.scrollToItem(index)
|
listState.scrollToItem(index)
|
||||||
|
|
@ -88,11 +93,11 @@ fun HomeSettingsPage(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is HomeSettingsDestination.ChooseLibrary -> {
|
is HomeSettingsDestination.AddRow -> {
|
||||||
HomeSettingsLibraryList(
|
HomeSettingsAddRow(
|
||||||
libraries = state.libraries,
|
libraries = state.libraries,
|
||||||
showDiscover = discoverEnabled,
|
showDiscover = discoverEnabled,
|
||||||
onClick = { destination = ChooseRowType(it) },
|
onClick = { backStack.add(ChooseRowType(it)) },
|
||||||
onClickMeta = {
|
onClickMeta = {
|
||||||
when (it) {
|
when (it) {
|
||||||
MetaRowType.CONTINUE_WATCHING,
|
MetaRowType.CONTINUE_WATCHING,
|
||||||
|
|
@ -100,15 +105,15 @@ fun HomeSettingsPage(
|
||||||
MetaRowType.COMBINED_CONTINUE_WATCHING,
|
MetaRowType.COMBINED_CONTINUE_WATCHING,
|
||||||
-> {
|
-> {
|
||||||
viewModel.addRow(it)
|
viewModel.addRow(it)
|
||||||
destination = HomeSettingsDestination.RowList
|
backStack.add(HomeSettingsDestination.RowList)
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaRowType.FAVORITES -> {
|
MetaRowType.FAVORITES -> {
|
||||||
destination = HomeSettingsDestination.ChooseFavorite
|
backStack.add(HomeSettingsDestination.ChooseFavorite)
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaRowType.DISCOVER -> {
|
MetaRowType.DISCOVER -> {
|
||||||
destination = HomeSettingsDestination.ChooseDiscover
|
backStack.add(HomeSettingsDestination.ChooseDiscover)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -121,7 +126,7 @@ fun HomeSettingsPage(
|
||||||
library = dest.library,
|
library = dest.library,
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.addRow(dest.library, it)
|
viewModel.addRow(dest.library, it)
|
||||||
destination = HomeSettingsDestination.RowList
|
backStack.add(HomeSettingsDestination.RowList)
|
||||||
},
|
},
|
||||||
modifier = destModifier,
|
modifier = destModifier,
|
||||||
)
|
)
|
||||||
|
|
@ -157,6 +162,9 @@ fun HomeSettingsPage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
HomePageContent(
|
HomePageContent(
|
||||||
loadingState = state.loading,
|
loadingState = state.loading,
|
||||||
homeRows = state.rowData,
|
homeRows = state.rowData,
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.CollectionType
|
import org.jellyfin.sdk.model.api.CollectionType
|
||||||
|
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -400,8 +402,9 @@ data class HomePageSettingsState(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
|
@Serializable
|
||||||
data class Library(
|
data class Library(
|
||||||
val itemId: UUID,
|
@Serializable(UUIDSerializer::class) val itemId: UUID,
|
||||||
val name: String,
|
val name: String,
|
||||||
val collectionType: CollectionType,
|
val collectionType: CollectionType,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue