diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index 5731a4d6a..0d14d396e 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaGradientBackground import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationRail @@ -51,6 +52,8 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavig import com.google.samples.apps.nowinandroid.core.designsystem.icon.Icon.DrawableResourceIcon import com.google.samples.apps.nowinandroid.core.designsystem.icon.Icon.ImageVectorIcon import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.navigation.NiaNavigationDestination +import com.google.samples.apps.nowinandroid.feature.foryou.navigation.ForYouDestination import com.google.samples.apps.nowinandroid.navigation.NiaNavHost import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination @@ -65,7 +68,13 @@ fun NiaApp( appState: NiaAppState = rememberNiaAppState(windowSizeClass) ) { NiaTheme { - NiaBackground { + val background: @Composable (@Composable () -> Unit) -> Unit = + when (appState.currentDestination?.route) { + ForYouDestination.route -> { content -> NiaGradientBackground(content = content) } + else -> { content -> NiaBackground(content = content) } + } + + background { Scaffold( modifier = Modifier.semantics { testTagsAsResourceId = true diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt index 2bb86954f..017238e07 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip import androidx.compose.material3.FilterChipDefaults @@ -63,6 +64,7 @@ fun NiaFilterChip( contentDescription = null ) }, + shape = CircleShape, border = FilterChipDefaults.filterChipBorder( borderColor = MaterialTheme.colorScheme.onBackground, selectedBorderColor = MaterialTheme.colorScheme.onBackground, diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt index 8537f5fbf..57d70642c 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt +++ b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt @@ -88,7 +88,6 @@ fun NiaNavigationBar( ) { NavigationBar( modifier = modifier, - containerColor = NiaNavigationDefaults.NavigationContainerColor, contentColor = NiaNavigationDefaults.navigationContentColor(), tonalElevation = 0.dp, content = content @@ -155,7 +154,7 @@ fun NiaNavigationRail( ) { NavigationRail( modifier = modifier, - containerColor = NiaNavigationDefaults.NavigationContainerColor, + containerColor = Color.Transparent, contentColor = NiaNavigationDefaults.navigationContentColor(), header = header, content = content @@ -166,7 +165,6 @@ fun NiaNavigationRail( * Now in Android navigation default values. */ object NiaNavigationDefaults { - val NavigationContainerColor = Color.Transparent @Composable fun navigationContentColor() = MaterialTheme.colorScheme.onSurfaceVariant @Composable diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 5ffe9ed95..7168bb505 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -69,44 +69,42 @@ fun BookmarksScreen( removeFromBookmarks: (String) -> Unit, modifier: Modifier = Modifier ) { - NiaGradientBackground { - Scaffold( - topBar = { - NiaTopAppBar( - titleRes = R.string.top_app_bar_title_saved, - actionIcon = NiaIcons.AccountCircle, - actionIconContentDescription = stringResource( - id = R.string.top_app_bar_action_menu - ), - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = Color.Transparent - ) - ) - }, - containerColor = Color.Transparent, - contentWindowInsets = WindowInsets(0, 0, 0, 0) - ) { innerPadding -> - LazyVerticalGrid( - columns = Adaptive(300.dp), - contentPadding = PaddingValues(16.dp), - horizontalArrangement = Arrangement.spacedBy(32.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), - modifier = modifier - .fillMaxSize() - .testTag("bookmarks:feed") - .padding(innerPadding) - .consumedWindowInsets(innerPadding) - ) { - newsFeed( - feedState = feedState, - onNewsResourcesCheckedChanged = { id, _ -> removeFromBookmarks(id) }, - showLoadingUIIfLoading = true, - loadingContentDescription = R.string.saved_loading + Scaffold( + topBar = { + NiaTopAppBar( + titleRes = R.string.top_app_bar_title_saved, + actionIcon = NiaIcons.AccountCircle, + actionIconContentDescription = stringResource( + id = R.string.top_app_bar_action_menu + ), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors( + containerColor = Color.Transparent ) + ) + }, + containerColor = Color.Transparent, + contentWindowInsets = WindowInsets(0, 0, 0, 0) + ) { innerPadding -> + LazyVerticalGrid( + columns = Adaptive(300.dp), + contentPadding = PaddingValues(16.dp), + horizontalArrangement = Arrangement.spacedBy(32.dp), + verticalArrangement = Arrangement.spacedBy(24.dp), + modifier = modifier + .fillMaxSize() + .testTag("bookmarks:feed") + .padding(innerPadding) + .consumedWindowInsets(innerPadding) + ) { + newsFeed( + feedState = feedState, + onNewsResourcesCheckedChanged = { id, _ -> removeFromBookmarks(id) }, + showLoadingUIIfLoading = true, + loadingContentDescription = R.string.saved_loading + ) - item(span = { GridItemSpan(maxLineSpan) }) { - Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing)) - } + item(span = { GridItemSpan(maxLineSpan) }) { + Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing)) } } } diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index 63e001c3b..895103a65 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -124,95 +124,93 @@ fun ForYouScreen( onNewsResourcesCheckedChanged: (String, Boolean) -> Unit, modifier: Modifier = Modifier, ) { - NiaGradientBackground { - Scaffold( - topBar = { - NiaTopAppBar( - titleRes = R.string.top_app_bar_title, - actionIcon = NiaIcons.AccountCircle, - actionIconContentDescription = stringResource( - id = R.string.for_you_top_app_bar_action_my_account - ), - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = Color.Transparent - ) + Scaffold( + topBar = { + NiaTopAppBar( + titleRes = R.string.top_app_bar_title, + actionIcon = NiaIcons.AccountCircle, + actionIconContentDescription = stringResource( + id = R.string.for_you_top_app_bar_action_my_account + ), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors( + containerColor = Color.Transparent ) - }, - containerColor = Color.Transparent, - contentWindowInsets = WindowInsets(0, 0, 0, 0) - ) { innerPadding -> - // Workaround to call Activity.reportFullyDrawn from Jetpack Compose. - // This code should be called when the UI is ready for use - // and relates to Time To Full Display. - val interestsLoaded = - interestsSelectionState !is ForYouInterestsSelectionUiState.Loading - val feedLoaded = feedState !is NewsFeedUiState.Loading + ) + }, + containerColor = Color.Transparent, + contentWindowInsets = WindowInsets(0, 0, 0, 0) + ) { innerPadding -> + // Workaround to call Activity.reportFullyDrawn from Jetpack Compose. + // This code should be called when the UI is ready for use + // and relates to Time To Full Display. + val interestsLoaded = + interestsSelectionState !is ForYouInterestsSelectionUiState.Loading + val feedLoaded = feedState !is NewsFeedUiState.Loading - if (interestsLoaded && feedLoaded) { - val localView = LocalView.current - // We use Unit to call reportFullyDrawn only on the first recomposition, - // however it will be called again if this composable goes out of scope. - // Activity.reportFullyDrawn() has its own check for this - // and is safe to call multiple times though. - LaunchedEffect(Unit) { - // We're leveraging the fact, that the current view is directly set as content of Activity. - val activity = localView.context as? Activity ?: return@LaunchedEffect - // To be sure not to call in the middle of a frame draw. - localView.doOnPreDraw { activity.reportFullyDrawn() } - } + if (interestsLoaded && feedLoaded) { + val localView = LocalView.current + // We use Unit to call reportFullyDrawn only on the first recomposition, + // however it will be called again if this composable goes out of scope. + // Activity.reportFullyDrawn() has its own check for this + // and is safe to call multiple times though. + LaunchedEffect(Unit) { + // We're leveraging the fact, that the current view is directly set as content of Activity. + val activity = localView.context as? Activity ?: return@LaunchedEffect + // To be sure not to call in the middle of a frame draw. + localView.doOnPreDraw { activity.reportFullyDrawn() } } + } - val tag = "forYou:feed" + val tag = "forYou:feed" - val lazyGridState = rememberLazyGridState() - TrackScrollJank(scrollableState = lazyGridState, stateName = tag) + val lazyGridState = rememberLazyGridState() + TrackScrollJank(scrollableState = lazyGridState, stateName = tag) - LazyVerticalGrid( - columns = Adaptive(300.dp), - contentPadding = PaddingValues(16.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), - modifier = modifier - .padding(innerPadding) - .consumedWindowInsets(innerPadding) - .fillMaxSize() - .testTag("forYou:feed"), - state = lazyGridState - ) { - interestsSelection( - interestsSelectionState = interestsSelectionState, - onAuthorCheckedChanged = onAuthorCheckedChanged, - onTopicCheckedChanged = onTopicCheckedChanged, - saveFollowedTopics = saveFollowedTopics, - // Custom LayoutModifier to remove the enforced parent 16.dp contentPadding - // from the LazyVerticalGrid and enable edge-to-edge scrolling for this section - interestsItemModifier = Modifier.layout { measurable, constraints -> - val placeable = measurable.measure( - constraints.copy( - maxWidth = constraints.maxWidth + 32.dp.roundToPx() - ) + LazyVerticalGrid( + columns = Adaptive(300.dp), + contentPadding = PaddingValues(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(24.dp), + modifier = modifier + .padding(innerPadding) + .consumedWindowInsets(innerPadding) + .fillMaxSize() + .testTag("forYou:feed"), + state = lazyGridState + ) { + interestsSelection( + interestsSelectionState = interestsSelectionState, + onAuthorCheckedChanged = onAuthorCheckedChanged, + onTopicCheckedChanged = onTopicCheckedChanged, + saveFollowedTopics = saveFollowedTopics, + // Custom LayoutModifier to remove the enforced parent 16.dp contentPadding + // from the LazyVerticalGrid and enable edge-to-edge scrolling for this section + interestsItemModifier = Modifier.layout { measurable, constraints -> + val placeable = measurable.measure( + constraints.copy( + maxWidth = constraints.maxWidth + 32.dp.roundToPx() ) - layout(placeable.width, placeable.height) { - placeable.place(0, 0) - } + ) + layout(placeable.width, placeable.height) { + placeable.place(0, 0) } - ) + } + ) - newsFeed( - feedState = feedState, - // Avoid showing a second loading wheel if we already are for the interests - // selection - showLoadingUIIfLoading = - interestsSelectionState !is ForYouInterestsSelectionUiState.Loading, - onNewsResourcesCheckedChanged = onNewsResourcesCheckedChanged, - loadingContentDescription = R.string.for_you_loading - ) + newsFeed( + feedState = feedState, + // Avoid showing a second loading wheel if we already are for the interests + // selection + showLoadingUIIfLoading = + interestsSelectionState !is ForYouInterestsSelectionUiState.Loading, + onNewsResourcesCheckedChanged = onNewsResourcesCheckedChanged, + loadingContentDescription = R.string.for_you_loading + ) - item(span = { GridItemSpan(maxLineSpan) }) { - Column { - Spacer(modifier = Modifier.height(8.dp)) - Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing)) - } + item(span = { GridItemSpan(maxLineSpan) }) { + Column { + Spacer(modifier = Modifier.height(8.dp)) + Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing)) } } }