Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.navigation3.ui)
implementation(libs.androidx.navigationevent.compose)
implementation(libs.androidx.compose.material3.adaptive)
implementation(libs.androidx.compose.material3.adaptive.layout)
implementation(libs.androidx.compose.material3.adaptive.navigation)
Expand Down
8 changes: 4 additions & 4 deletions app/dependencies/prodReleaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ androidx.navigation3:navigation3-runtime-android:1.0.0
androidx.navigation3:navigation3-runtime:1.0.0
androidx.navigation3:navigation3-ui-android:1.0.0
androidx.navigation3:navigation3-ui:1.0.0
androidx.navigationevent:navigationevent-android:1.0.0
androidx.navigationevent:navigationevent-compose-android:1.0.0
androidx.navigationevent:navigationevent-compose:1.0.0
androidx.navigationevent:navigationevent:1.0.0
androidx.navigationevent:navigationevent-android:1.0.1
androidx.navigationevent:navigationevent-compose-android:1.0.1
androidx.navigationevent:navigationevent-compose:1.0.1
androidx.navigationevent:navigationevent:1.0.1
androidx.print:print:1.0.0
androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05
androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,26 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.ui.NavDisplay
import androidx.navigationevent.NavigationEventDispatcher
import androidx.navigationevent.NavigationEventDispatcherOwner
import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
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.NiaNavigationSuiteScaffold
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.GradientColors
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalGradientColors
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.navigation.Navigator
import com.google.samples.apps.nowinandroid.core.navigation.toEntries
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.LocalSnackbarHostState
import com.google.samples.apps.nowinandroid.feature.bookmarks.impl.navigation.bookmarksEntry
import com.google.samples.apps.nowinandroid.feature.foryou.api.navigation.ForYouNavKey
Expand All @@ -84,6 +94,9 @@ import com.google.samples.apps.nowinandroid.feature.search.impl.navigation.searc
import com.google.samples.apps.nowinandroid.feature.settings.impl.SettingsDialog
import com.google.samples.apps.nowinandroid.feature.topic.impl.navigation.topicEntry
import com.google.samples.apps.nowinandroid.navigation.TOP_LEVEL_NAV_ITEMS
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.datetime.TimeZone
import com.google.samples.apps.nowinandroid.feature.settings.impl.R as settingsR

@Composable
Expand Down Expand Up @@ -205,6 +218,9 @@ internal fun NiaApp(
),
)
},
// Fix for render issue: Scaffold crashes with "List is empty" when contentWindowInsets is set
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a link to the issue so we can remove this workaround when it's fixed.

// but no top/bottom bar is present in some Compose versions.
bottomBar = {},
) { padding ->
Column(
Modifier
Expand Down Expand Up @@ -296,3 +312,37 @@ private fun Modifier.notificationDot(): Modifier =
)
}
}

@DevicePreviews
@Composable
fun NiaAppPreview() {
NiaTheme {
CompositionLocalProvider(
LocalNavigationEventDispatcherOwner provides object : NavigationEventDispatcherOwner {
override val navigationEventDispatcher = NavigationEventDispatcher()
},
) {
NiaApp(
appState = rememberNiaAppState(
networkMonitor = object : NetworkMonitor {
override val isOnline: Flow<Boolean> = flowOf(true)
},
userNewsResourceRepository = object : UserNewsResourceRepository {
override fun observeAll(query: NewsResourceQuery): Flow<List<UserNewsResource>> =
flowOf(emptyList())

override fun observeAllForFollowedTopics(): Flow<List<UserNewsResource>> =
flowOf(emptyList())

override fun observeAllBookmarked(): Flow<List<UserNewsResource>> =
flowOf(emptyList())
},
timeZoneMonitor = object : TimeZoneMonitor {
override val currentTimeZone: Flow<TimeZone> =
flowOf(TimeZone.currentSystemDefault())
},
),
)
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The news cards are an important part of the screenshots because they improve test fidelity - is there a reason why they've been removed from all the screenshots?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That change wasn't intentional, I assure you. Perhaps one of the GitHub bots made this change? I'll look into it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. There is a step in the build workflow that generates new screenshots based on the changes in your PR. This is so that you, the PR owner, can visually verify that the changes you've made have the desired effect, or allows you to spot when you've changed something that inadvertently changes the UI.

In this case, it sounds like the latter so you need to fix the news resources being displayed. The current screenshots will be removed from the PR after you push the code changes and the build workflow completes.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/testDemo/screenshots/snackbar_compact_medium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/testDemo/screenshots/snackbar_expanded_expanded.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/testDemo/screenshots/snackbar_medium_medium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 0 additions & 8 deletions core/datastore-proto/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ protobuf {
}
}

androidComponents.beforeVariants {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why has this been removed? Usually if it's not directly related to the PR it should go in a separate PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was made by Gemini. I believe it was done to address a build error. I'll see if I can revert this without breaking the PR.

Copy link
Collaborator

@dturner dturner Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change has already been made on main in #2051. You can revert the changes made to this file and rebase.

android.sourceSets.register(it.name) {
val buildDir = layout.buildDirectory.get().asFile
java.srcDir(buildDir.resolve("generated/source/proto/${it.name}/java"))
kotlin.srcDir(buildDir.resolve("generated/source/proto/${it.name}/kotlin"))
}
}

dependencies {
api(libs.protobuf.kotlin.lite)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

package com.google.samples.apps.nowinandroid.core.ui

import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview

/**
* Multipreview annotation that represents various device sizes. Add this annotation to a composable
* to render various devices.
*/
@Preview(name = "phone", device = "spec:shape=Normal,width=360,height=640,unit=dp,dpi=480")
@Preview(name = "landscape", device = "spec:shape=Normal,width=640,height=360,unit=dp,dpi=480")
@Preview(name = "foldable", device = "spec:shape=Normal,width=673,height=841,unit=dp,dpi=480")
@Preview(name = "tablet", device = "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=480")
@Preview(name = "phone", device = Devices.PHONE, showBackground = true)
@Preview(name = "foldable", device = Devices.FOLDABLE, showBackground = true)
@Preview(name = "tablet", device = Devices.TABLET, showBackground = true)
@Preview(name = "desktop", device = Devices.DESKTOP, showBackground = true)
annotation class DevicePreviews
Original file line number Diff line number Diff line change
Expand Up @@ -618,3 +618,24 @@ fun ForYouScreenPopulatedAndLoading(
)
}
}

@DevicePreviews
@Composable
fun ForYouScreenNotPopulatedOnboarding() {
NiaTheme {
ForYouScreen(
isSyncing = true,
onboardingUiState = OnboardingUiState.Shown(
topics = emptyList(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a justification for adding this preview, using topics = emptyList() here means this is not a realistic preview of the ForYouScreen when the onboarding UI is shown. There's code from the other previews that can be copied here to load the topics.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned previously, it's realistic in the sense that it's a state I encountered. Specifically when running on a tablet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You encountered a state where the onboarding was shown but there were no topics in it? If so, that's a bug, and we shouldn't provide previews for buggy states.

The correct state to preview should be that the onboarding has topics in it.

),
feedState = NewsFeedUiState.Loading,
deepLinkedUserNewsResource = null,
onTopicCheckedChanged = { _, _ -> },
saveFollowedTopics = {},
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
onTopicClick = {},
onDeepLinkOpened = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,35 @@

package com.google.samples.apps.nowinandroid.feature.foryou.impl.navigation

import androidx.compose.ui.platform.LocalInspectionMode
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import com.google.samples.apps.nowinandroid.core.navigation.Navigator
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.feature.foryou.api.navigation.ForYouNavKey
import com.google.samples.apps.nowinandroid.feature.foryou.impl.ForYouScreen
import com.google.samples.apps.nowinandroid.feature.foryou.impl.OnboardingUiState
import com.google.samples.apps.nowinandroid.feature.topic.api.navigation.navigateToTopic

fun EntryProviderScope<NavKey>.forYouEntry(navigator: Navigator) {
entry<ForYouNavKey> {
ForYouScreen(
onTopicClick = navigator::navigateToTopic,
)
if (LocalInspectionMode.current) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pollutes the production code with code that is only used for previews. Are there any alternatives to doing this? Maybe have a different entryProvider that is used for previews instead?

ForYouScreen(
isSyncing = false,
onboardingUiState = OnboardingUiState.NotShown,
feedState = NewsFeedUiState.Success(emptyList()),
deepLinkedUserNewsResource = null,
onTopicCheckedChanged = { _, _ -> },
onTopicClick = {},
onDeepLinkOpened = {},
saveFollowedTopics = {},
onNewsResourcesCheckedChanged = { _, _ -> },
onNewsResourceViewed = {},
)
} else {
ForYouScreen(
onTopicClick = navigator::navigateToTopic,
)
}
}
}
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", v
androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
androidx-navigation3-runtime = { group = "androidx.navigation3", name = "navigation3-runtime", version.ref = "androidxNavigation3" }
androidx-navigation3-ui = { group = "androidx.navigation3", name = "navigation3-ui", version.ref = "androidxNavigation3" }
androidx-navigationevent-compose = { group = "androidx.navigationevent", name = "navigationevent-compose", version = "1.0.1" }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the convention for all other dependencies by moving the version number into a variable at the top of the file.

androidx-savedstate-compose = { group = "androidx.savedstate", name = "savedstate-compose", version.ref = "androidxSavedStateCompose" }
androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstaller" }
androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" }
Expand Down