diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 10bfe9c22..50e64c192 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -86,6 +86,7 @@ dependencies { implementation(project(":core:ui")) implementation(project(":core:designsystem")) implementation(project(":core:navigation")) + implementation(project(":core:model")) implementation(project(":sync:work")) implementation(project(":sync:sync-test")) 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 1d5ec6e98..f564f11db 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 @@ -14,8 +14,15 @@ * limitations under the License. */ +@file:OptIn( + ExperimentalMaterial3Api::class, + ExperimentalLayoutApi::class, + ExperimentalComposeUiApi::class, ExperimentalMaterial3WindowSizeClassApi::class +) + package com.google.samples.apps.nowinandroid.ui +import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets @@ -32,15 +39,21 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.WindowSizeClass +import androidx.compose.material3.windowsizeclass.WindowSizeClass.Companion import androidx.compose.runtime.Composable import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground @@ -52,15 +65,20 @@ 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.model.data.FollowableAuthor +import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic +import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.model.data.previewAuthors +import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources +import com.google.samples.apps.nowinandroid.core.model.data.previewTopics +import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success +import com.google.samples.apps.nowinandroid.core.ui.ReferenceDevicePreviews +import com.google.samples.apps.nowinandroid.feature.foryou.ForYouInterestsSelectionUiState.WithInterestsSelection +import com.google.samples.apps.nowinandroid.feature.foryou.ForYouScreen 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 -@OptIn( - ExperimentalMaterial3Api::class, - ExperimentalLayoutApi::class, - ExperimentalComposeUiApi::class -) @Composable fun NiaApp( windowSizeClass: WindowSizeClass, @@ -109,14 +127,41 @@ fun NiaApp( ) } - NiaNavHost( - navController = appState.navController, - onBackClick = appState::onBackClick, - onNavigateToDestination = appState::navigate, - modifier = Modifier - .padding(padding) - .consumedWindowInsets(padding) - ) + if(!LocalInspectionMode.current) + { + NiaNavHost( + navController = appState.navController, + onBackClick = appState::onBackClick, + onNavigateToDestination = appState::navigate, + modifier = Modifier + .padding(padding) + .consumedWindowInsets(padding) + ) + } + else + { + BoxWithConstraints { + NiaTheme { + ForYouScreen( + isOffline = false, + isSyncing = false, + interestsSelectionState = WithInterestsSelection( + topics = previewTopics.map { FollowableTopic(it, false) }, + authors = previewAuthors.map { FollowableAuthor(it, false) } + ), + feedState = Success( + feed = previewNewsResources.map { + SaveableNewsResource(it, false) + } + ), + onTopicCheckedChanged = { _, _ -> }, + onAuthorCheckedChanged = { _, _ -> }, + saveFollowedTopics = {}, + onNewsResourcesCheckedChanged = { _, _ -> } + ) + } + } + } } } } @@ -195,3 +240,11 @@ private fun NiaBottomBar( } } } +@ReferenceDevicePreviews +@Composable +fun NiaAppLayoutPreview(){ + val widthDp = Dp(LocalConfiguration.current.screenWidthDp.toFloat()) + val heightDp = Dp(LocalConfiguration.current.screenHeightDp.toFloat()) + val windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(widthDp, heightDp)) + NiaApp(windowSizeClass = windowSizeClass) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt index bb2b59466..059f69016 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt @@ -18,6 +18,15 @@ package com.google.samples.apps.nowinandroid.core.ui import androidx.compose.ui.tooling.preview.Preview +/** + * Multipreview annotation the maps to the Android Studio reference devices. + */ +@Preview(name = "1_phone", device = Devices.PHONE) +@Preview(name = "2_foldable", device = Devices.FOLDABLE) +@Preview(name = "3_tablet", device = Devices.TABLET) +@Preview(name = "4_desktop", device = Devices.DESKTOP) +annotation class ReferenceDevicePreviews + /** * Multipreview annotation that represents various device sizes. Add this annotation to a composable * to render various devices. diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/ReferenceDevices.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/ReferenceDevices.kt new file mode 100644 index 000000000..cd712915f --- /dev/null +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/ReferenceDevices.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.ui + +import androidx.compose.ui.tooling.preview.Preview + +import androidx.annotation.StringDef + +/** + * List with the pre-defined devices available to be used in the preview. + */ +object Devices { + + // Reference devices + const val PHONE = "spec:shape=Normal,width=411,height=891,unit=dp,dpi=420" + const val FOLDABLE = "spec:shape=Normal,width=673,height=841,unit=dp,dpi=420" + const val TABLET = "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=420" + const val DESKTOP = "spec:shape=Normal,width=1920,height=1080,unit=dp,dpi=420" +} + +/** + * Annotation for defining the [Preview] device to use. + * @suppress + */ +@Retention(AnnotationRetention.SOURCE) +@StringDef( + open = true, + value = [ + Devices.PHONE, + Devices.FOLDABLE, + Devices.TABLET, + Devices.DESKTOP, + ] +) +annotation class Device