From dfc6a17f337bfe0cda5efaffcf46f88dacd120b1 Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Thu, 15 Jan 2026 13:35:35 -0800 Subject: [PATCH] feat: updates `@DevicePreviews` to use the Devices object constants --- app/build.gradle.kts | 1 + .../samples/apps/nowinandroid/ui/NiaApp.kt | 50 +++++++++++++++++++ core/datastore-proto/build.gradle.kts | 8 --- .../nowinandroid/core/ui/DevicePreviews.kt | 9 ++-- .../feature/foryou/impl/ForYouScreen.kt | 21 ++++++++ .../impl/navigation/ForYouEntryProvider.kt | 24 +++++++-- gradle/libs.versions.toml | 1 + 7 files changed, 99 insertions(+), 15 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2f0253943..a1d1b2d5e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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) diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index bfaa27fa6..1cd4f51d3 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -64,7 +64,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.ui.NavDisplay +import androidx.navigationevent.compose.LocalNavigationEventDispatcherOwner +import androidx.navigationevent.NavigationEventDispatcher +import androidx.navigationevent.NavigationEventDispatcherOwner 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 @@ -72,8 +79,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAp 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 @@ -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 @@ -205,6 +218,9 @@ internal fun NiaApp( ), ) }, + // Fix for render issue: Scaffold crashes with "List is empty" when contentWindowInsets is set + // but no top/bottom bar is present in some Compose versions. + bottomBar = {}, ) { padding -> Column( Modifier @@ -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 = flowOf(true) + }, + userNewsResourceRepository = object : UserNewsResourceRepository { + override fun observeAll(query: NewsResourceQuery): Flow> = + flowOf(emptyList()) + + override fun observeAllForFollowedTopics(): Flow> = + flowOf(emptyList()) + + override fun observeAllBookmarked(): Flow> = + flowOf(emptyList()) + }, + timeZoneMonitor = object : TimeZoneMonitor { + override val currentTimeZone: Flow = + flowOf(TimeZone.currentSystemDefault()) + }, + ), + ) + } + } +} diff --git a/core/datastore-proto/build.gradle.kts b/core/datastore-proto/build.gradle.kts index 511518dde..be7a16d46 100644 --- a/core/datastore-proto/build.gradle.kts +++ b/core/datastore-proto/build.gradle.kts @@ -42,14 +42,6 @@ protobuf { } } -androidComponents.beforeVariants { - 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) } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt index bb2b59466..27e5151fa 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt @@ -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 diff --git a/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/ForYouScreen.kt b/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/ForYouScreen.kt index 0ae916db3..c7a8262bf 100644 --- a/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/ForYouScreen.kt +++ b/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/ForYouScreen.kt @@ -618,3 +618,24 @@ fun ForYouScreenPopulatedAndLoading( ) } } + +@DevicePreviews +@Composable +fun ForYouScreenNotPopulatedOnboarding() { + NiaTheme { + ForYouScreen( + isSyncing = true, + onboardingUiState = OnboardingUiState.Shown( + topics = emptyList(), + ), + feedState = NewsFeedUiState.Loading, + deepLinkedUserNewsResource = null, + onTopicCheckedChanged = { _, _ -> }, + saveFollowedTopics = {}, + onNewsResourcesCheckedChanged = { _, _ -> }, + onNewsResourceViewed = {}, + onTopicClick = {}, + onDeepLinkOpened = {}, + ) + } +} diff --git a/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/navigation/ForYouEntryProvider.kt b/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/navigation/ForYouEntryProvider.kt index 4bdc7368c..b8fe3219b 100644 --- a/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/navigation/ForYouEntryProvider.kt +++ b/feature/foryou/impl/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/impl/navigation/ForYouEntryProvider.kt @@ -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.forYouEntry(navigator: Navigator) { entry { - ForYouScreen( - onTopicClick = navigator::navigateToTopic, - ) + if (LocalInspectionMode.current) { + ForYouScreen( + isSyncing = false, + onboardingUiState = OnboardingUiState.NotShown, + feedState = NewsFeedUiState.Success(emptyList()), + deepLinkedUserNewsResource = null, + onTopicCheckedChanged = { _, _ -> }, + onTopicClick = {}, + onDeepLinkOpened = {}, + saveFollowedTopics = {}, + onNewsResourcesCheckedChanged = { _, _ -> }, + onNewsResourceViewed = {}, + ) + } else { + ForYouScreen( + onTopicClick = navigator::navigateToTopic, + ) + } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b4bbd187e..7f316d531 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" } 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" }