diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt index 300809d50..1d922b0d1 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/App.kt @@ -78,6 +78,10 @@ import com.nuvio.app.features.profiles.ProfileRepository import com.nuvio.app.features.profiles.ProfileSelectionScreen import com.nuvio.app.features.search.SearchScreen import com.nuvio.app.features.settings.SettingsScreen +import com.nuvio.app.features.settings.HomescreenSettingsScreen +import com.nuvio.app.features.settings.ContinueWatchingSettingsScreen +import com.nuvio.app.features.settings.AddonsSettingsScreen +import com.nuvio.app.features.settings.AccountSettingsScreen import com.nuvio.app.features.streams.StreamsRepository import com.nuvio.app.features.streams.StreamsScreen import com.nuvio.app.features.watched.WatchedRepository @@ -92,6 +96,18 @@ object TabsRoute @Serializable data class DetailRoute(val type: String, val id: String) +@Serializable +object HomescreenSettingsRoute + +@Serializable +object ContinueWatchingSettingsRoute + +@Serializable +object AddonsSettingsRoute + +@Serializable +object AccountSettingsRoute + @Serializable data class StreamRoute( val type: String, @@ -393,6 +409,10 @@ private fun MainAppContent( onContinueWatchingClick = onContinueWatchingClick, onContinueWatchingLongPress = onContinueWatchingLongPress, onSwitchProfile = onSwitchProfile, + onHomescreenSettingsClick = { navController.navigate(HomescreenSettingsRoute) }, + onContinueWatchingSettingsClick = { navController.navigate(ContinueWatchingSettingsRoute) }, + onAddonsSettingsClick = { navController.navigate(AddonsSettingsRoute) }, + onAccountSettingsClick = { navController.navigate(AccountSettingsRoute) }, ) } } @@ -518,6 +538,26 @@ private fun MainAppContent( modifier = Modifier.fillMaxSize(), ) } + composable { + HomescreenSettingsScreen( + onBack = { navController.popBackStack() }, + ) + } + composable { + ContinueWatchingSettingsScreen( + onBack = { navController.popBackStack() }, + ) + } + composable { + AddonsSettingsScreen( + onBack = { navController.popBackStack() }, + ) + } + composable { + AccountSettingsScreen( + onBack = { navController.popBackStack() }, + ) + } } NuvioPosterActionSheet( @@ -554,6 +594,10 @@ private fun AppTabHost( onContinueWatchingClick: ((ContinueWatchingItem) -> Unit)? = null, onContinueWatchingLongPress: ((ContinueWatchingItem) -> Unit)? = null, onSwitchProfile: (() -> Unit)? = null, + onHomescreenSettingsClick: () -> Unit = {}, + onContinueWatchingSettingsClick: () -> Unit = {}, + onAddonsSettingsClick: () -> Unit = {}, + onAccountSettingsClick: () -> Unit = {}, ) { Box(modifier = modifier.fillMaxSize()) { keepAliveTab( @@ -591,6 +635,10 @@ private fun AppTabHost( SettingsScreen( modifier = Modifier.fillMaxSize(), onSwitchProfile = onSwitchProfile, + onHomescreenClick = onHomescreenSettingsClick, + onContinueWatchingClick = onContinueWatchingSettingsClick, + onAddonsClick = onAddonsSettingsClick, + onAccountClick = onAccountSettingsClick, ) } } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsFullScreenPages.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsFullScreenPages.kt new file mode 100644 index 000000000..4002623a5 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsFullScreenPages.kt @@ -0,0 +1,123 @@ +package com.nuvio.app.features.settings + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.nuvio.app.core.ui.NuvioScreen +import com.nuvio.app.core.ui.NuvioScreenHeader +import com.nuvio.app.features.addons.AddonRepository +import com.nuvio.app.features.home.HomeCatalogSettingsRepository +import com.nuvio.app.features.watchprogress.ContinueWatchingPreferencesRepository + +@Composable +fun HomescreenSettingsScreen( + onBack: () -> Unit, +) { + val addonsUiState by AddonRepository.uiState.collectAsStateWithLifecycle() + val homescreenSettingsUiState by HomeCatalogSettingsRepository.uiState.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + AddonRepository.initialize() + } + + LaunchedEffect(addonsUiState.addons) { + HomeCatalogSettingsRepository.syncCatalogs(addonsUiState.addons) + } + + NuvioScreen( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + ) { + stickyHeader { + NuvioScreenHeader( + title = "Homescreen", + onBack = onBack, + ) + } + homescreenSettingsContent( + isTablet = false, + heroEnabled = homescreenSettingsUiState.heroEnabled, + items = homescreenSettingsUiState.items, + ) + } +} + +@Composable +fun ContinueWatchingSettingsScreen( + onBack: () -> Unit, +) { + val continueWatchingPreferencesUiState by remember { + ContinueWatchingPreferencesRepository.ensureLoaded() + ContinueWatchingPreferencesRepository.uiState + }.collectAsStateWithLifecycle() + + NuvioScreen( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + ) { + stickyHeader { + NuvioScreenHeader( + title = "Continue Watching", + onBack = onBack, + ) + } + continueWatchingSettingsContent( + isTablet = false, + isVisible = continueWatchingPreferencesUiState.isVisible, + style = continueWatchingPreferencesUiState.style, + ) + } +} + +@Composable +fun AddonsSettingsScreen( + onBack: () -> Unit, +) { + LaunchedEffect(Unit) { + AddonRepository.initialize() + } + + NuvioScreen( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + ) { + stickyHeader { + NuvioScreenHeader( + title = "Addons", + onBack = onBack, + ) + } + addonsSettingsContent() + } +} + +@Composable +fun AccountSettingsScreen( + onBack: () -> Unit, +) { + NuvioScreen( + modifier = Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + ) { + stickyHeader { + NuvioScreenHeader( + title = "Account", + onBack = onBack, + ) + } + accountSettingsContent( + isTablet = false, + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt index cd134c767..5b52cced4 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsModels.kt @@ -19,11 +19,7 @@ internal enum class SettingsPage( Root("Settings"), Playback("Playback"), Appearance("Appearance"), - ContinueWatching("Continue Watching"), ContentDiscovery("Content & Discovery"), - Addons("Addons"), - Homescreen("Homescreen"), - Account("Account"), } internal fun SettingsPage.previousPage(): SettingsPage? = @@ -31,9 +27,5 @@ internal fun SettingsPage.previousPage(): SettingsPage? = SettingsPage.Root -> null SettingsPage.Playback -> SettingsPage.Root SettingsPage.Appearance -> SettingsPage.Root - SettingsPage.ContinueWatching -> SettingsPage.Appearance SettingsPage.ContentDiscovery -> SettingsPage.Root - SettingsPage.Addons -> SettingsPage.ContentDiscovery - SettingsPage.Homescreen -> SettingsPage.ContentDiscovery - SettingsPage.Account -> SettingsPage.Root } diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt index 93f13eb96..ae36fc99f 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/SettingsScreen.kt @@ -22,7 +22,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -36,41 +35,26 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.nuvio.app.core.ui.PlatformBackHandler import com.nuvio.app.core.ui.NuvioScreen import com.nuvio.app.core.ui.NuvioScreenHeader -import com.nuvio.app.features.addons.AddonRepository -import com.nuvio.app.features.home.HomeCatalogSettingsItem -import com.nuvio.app.features.home.HomeCatalogSettingsRepository import com.nuvio.app.features.player.PlayerSettingsRepository -import com.nuvio.app.features.watchprogress.ContinueWatchingPreferencesRepository -import com.nuvio.app.features.watchprogress.ContinueWatchingSectionStyle @Composable fun SettingsScreen( modifier: Modifier = Modifier, onSwitchProfile: (() -> Unit)? = null, + onHomescreenClick: () -> Unit = {}, + onContinueWatchingClick: () -> Unit = {}, + onAddonsClick: () -> Unit = {}, + onAccountClick: () -> Unit = {}, ) { BoxWithConstraints( modifier = modifier .fillMaxSize() .background(MaterialTheme.colorScheme.background), ) { - LaunchedEffect(Unit) { - AddonRepository.initialize() - } - - val addonsUiState by AddonRepository.uiState.collectAsStateWithLifecycle() - val homescreenSettingsUiState by HomeCatalogSettingsRepository.uiState.collectAsStateWithLifecycle() val playerSettingsUiState by remember { PlayerSettingsRepository.ensureLoaded() PlayerSettingsRepository.uiState }.collectAsStateWithLifecycle() - val continueWatchingPreferencesUiState by remember { - ContinueWatchingPreferencesRepository.ensureLoaded() - ContinueWatchingPreferencesRepository.uiState - }.collectAsStateWithLifecycle() - - LaunchedEffect(addonsUiState.addons) { - HomeCatalogSettingsRepository.syncCatalogs(addonsUiState.addons) - } var currentPage by rememberSaveable { mutableStateOf(SettingsPage.Root.name) } val page = remember(currentPage) { SettingsPage.valueOf(currentPage) } @@ -85,23 +69,23 @@ fun SettingsScreen( TabletSettingsScreen( page = page, onPageChange = { currentPage = it.name }, - heroEnabled = homescreenSettingsUiState.heroEnabled, - homescreenSettings = homescreenSettingsUiState.items, showLoadingOverlay = playerSettingsUiState.showLoadingOverlay, - continueWatchingVisible = continueWatchingPreferencesUiState.isVisible, - continueWatchingStyle = continueWatchingPreferencesUiState.style, onSwitchProfile = onSwitchProfile, + onHomescreenClick = onHomescreenClick, + onContinueWatchingClick = onContinueWatchingClick, + onAddonsClick = onAddonsClick, + onAccountClick = onAccountClick, ) } else { MobileSettingsScreen( page = page, onPageChange = { currentPage = it.name }, - heroEnabled = homescreenSettingsUiState.heroEnabled, - homescreenSettings = homescreenSettingsUiState.items, showLoadingOverlay = playerSettingsUiState.showLoadingOverlay, - continueWatchingVisible = continueWatchingPreferencesUiState.isVisible, - continueWatchingStyle = continueWatchingPreferencesUiState.style, onSwitchProfile = onSwitchProfile, + onHomescreenClick = onHomescreenClick, + onContinueWatchingClick = onContinueWatchingClick, + onAddonsClick = onAddonsClick, + onAccountClick = onAccountClick, ) } } @@ -111,12 +95,12 @@ fun SettingsScreen( private fun MobileSettingsScreen( page: SettingsPage, onPageChange: (SettingsPage) -> Unit, - heroEnabled: Boolean, - homescreenSettings: List, showLoadingOverlay: Boolean, - continueWatchingVisible: Boolean, - continueWatchingStyle: ContinueWatchingSectionStyle, onSwitchProfile: (() -> Unit)? = null, + onHomescreenClick: () -> Unit = {}, + onContinueWatchingClick: () -> Unit = {}, + onAddonsClick: () -> Unit = {}, + onAccountClick: () -> Unit = {}, ) { NuvioScreen { stickyHeader { @@ -133,7 +117,7 @@ private fun MobileSettingsScreen( onPlaybackClick = { onPageChange(SettingsPage.Playback) }, onAppearanceClick = { onPageChange(SettingsPage.Appearance) }, onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) }, - onAccountClick = { onPageChange(SettingsPage.Account) }, + onAccountClick = onAccountClick, onSwitchProfileClick = onSwitchProfile, ) SettingsPage.Playback -> playbackSettingsContent( @@ -142,26 +126,12 @@ private fun MobileSettingsScreen( ) SettingsPage.Appearance -> appearanceSettingsContent( isTablet = false, - onContinueWatchingClick = { onPageChange(SettingsPage.ContinueWatching) }, - ) - SettingsPage.ContinueWatching -> continueWatchingSettingsContent( - isTablet = false, - isVisible = continueWatchingVisible, - style = continueWatchingStyle, + onContinueWatchingClick = onContinueWatchingClick, ) SettingsPage.ContentDiscovery -> contentDiscoveryContent( isTablet = false, - onAddonsClick = { onPageChange(SettingsPage.Addons) }, - onHomescreenClick = { onPageChange(SettingsPage.Homescreen) }, - ) - SettingsPage.Addons -> addonsSettingsContent() - SettingsPage.Homescreen -> homescreenSettingsContent( - isTablet = false, - heroEnabled = heroEnabled, - items = homescreenSettings, - ) - SettingsPage.Account -> accountSettingsContent( - isTablet = false, + onAddonsClick = onAddonsClick, + onHomescreenClick = onHomescreenClick, ) } } @@ -171,12 +141,12 @@ private fun MobileSettingsScreen( private fun TabletSettingsScreen( page: SettingsPage, onPageChange: (SettingsPage) -> Unit, - heroEnabled: Boolean, - homescreenSettings: List, showLoadingOverlay: Boolean, - continueWatchingVisible: Boolean, - continueWatchingStyle: ContinueWatchingSectionStyle, onSwitchProfile: (() -> Unit)? = null, + onHomescreenClick: () -> Unit = {}, + onContinueWatchingClick: () -> Unit = {}, + onAddonsClick: () -> Unit = {}, + onAccountClick: () -> Unit = {}, ) { var selectedCategory by rememberSaveable { mutableStateOf(SettingsCategory.General.name) } val activeCategory = SettingsCategory.valueOf(selectedCategory) @@ -242,7 +212,7 @@ private fun TabletSettingsScreen( onPlaybackClick = { onPageChange(SettingsPage.Playback) }, onAppearanceClick = { onPageChange(SettingsPage.Appearance) }, onContentDiscoveryClick = { onPageChange(SettingsPage.ContentDiscovery) }, - onAccountClick = { onPageChange(SettingsPage.Account) }, + onAccountClick = onAccountClick, onSwitchProfileClick = onSwitchProfile, ) SettingsPage.Playback -> playbackSettingsContent( @@ -251,26 +221,12 @@ private fun TabletSettingsScreen( ) SettingsPage.Appearance -> appearanceSettingsContent( isTablet = true, - onContinueWatchingClick = { onPageChange(SettingsPage.ContinueWatching) }, - ) - SettingsPage.ContinueWatching -> continueWatchingSettingsContent( - isTablet = true, - isVisible = continueWatchingVisible, - style = continueWatchingStyle, + onContinueWatchingClick = onContinueWatchingClick, ) SettingsPage.ContentDiscovery -> contentDiscoveryContent( isTablet = true, - onAddonsClick = { onPageChange(SettingsPage.Addons) }, - onHomescreenClick = { onPageChange(SettingsPage.Homescreen) }, - ) - SettingsPage.Addons -> addonsSettingsContent() - SettingsPage.Homescreen -> homescreenSettingsContent( - isTablet = true, - heroEnabled = heroEnabled, - items = homescreenSettings, - ) - SettingsPage.Account -> accountSettingsContent( - isTablet = true, + onAddonsClick = onAddonsClick, + onHomescreenClick = onHomescreenClick, ) } }