Merge pull request #1094 from lihenggui/main

Upgrade Spotless and Ktlint and remove code convention violations
pull/1119/head
Don Turner 1 year ago committed by GitHub
commit ad15f0137e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,3 +4,4 @@
[*.{kt,kts}] [*.{kt,kts}]
ij_kotlin_allow_trailing_comma=true ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test

@ -179,7 +179,7 @@ class MainActivity : ComponentActivity() {
To see quick turnaround of the ProfileVerifier, we recommend using `speed-profile`. To see quick turnaround of the ProfileVerifier, we recommend using `speed-profile`.
If you don't do either of these steps, you might only see the profile status reported as If you don't do either of these steps, you might only see the profile status reported as
"enqueued for compilation" when running the sample locally. "enqueued for compilation" when running the sample locally.
*/ */
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val status = ProfileVerifier.getCompilationStatusAsync().await() val status = ProfileVerifier.getCompilationStatusAsync().await()
Log.d(TAG, "ProfileInstaller status code: ${status.profileInstallResultCode}") Log.d(TAG, "ProfileInstaller status code: ${status.profileInstallResultCode}")

@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.bookmarksScreen import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.bookmarksScreen
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouNavigationRoute import com.google.samples.apps.nowinandroid.feature.foryou.navigation.FOR_YOU_ROUTE
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouScreen import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouScreen
import com.google.samples.apps.nowinandroid.feature.interests.navigation.interestsGraph import com.google.samples.apps.nowinandroid.feature.interests.navigation.interestsGraph
import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen import com.google.samples.apps.nowinandroid.feature.search.navigation.searchScreen
@ -41,7 +41,7 @@ fun NiaNavHost(
appState: NiaAppState, appState: NiaAppState,
onShowSnackbar: suspend (String, String?) -> Boolean, onShowSnackbar: suspend (String, String?) -> Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
startDestination: String = forYouNavigationRoute, startDestination: String = FOR_YOU_ROUTE,
) { ) {
val navController = appState.navController val navController = appState.navController
NavHost( NavHost(

@ -33,11 +33,11 @@ import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository 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.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.bookmarksRoute import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.BOOKMARKS_ROUTE
import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.navigateToBookmarks import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.navigateToBookmarks
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.forYouNavigationRoute import com.google.samples.apps.nowinandroid.feature.foryou.navigation.FOR_YOU_ROUTE
import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou import com.google.samples.apps.nowinandroid.feature.foryou.navigation.navigateToForYou
import com.google.samples.apps.nowinandroid.feature.interests.navigation.interestsRoute import com.google.samples.apps.nowinandroid.feature.interests.navigation.INTERESTS_ROUTE
import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterestsGraph import com.google.samples.apps.nowinandroid.feature.interests.navigation.navigateToInterestsGraph
import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch import com.google.samples.apps.nowinandroid.feature.search.navigation.navigateToSearch
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
@ -91,9 +91,9 @@ class NiaAppState(
val currentTopLevelDestination: TopLevelDestination? val currentTopLevelDestination: TopLevelDestination?
@Composable get() = when (currentDestination?.route) { @Composable get() = when (currentDestination?.route) {
forYouNavigationRoute -> FOR_YOU FOR_YOU_ROUTE -> FOR_YOU
bookmarksRoute -> BOOKMARKS BOOKMARKS_ROUTE -> BOOKMARKS
interestsRoute -> INTERESTS INTERESTS_ROUTE -> INTERESTS
else -> null else -> null
} }

@ -60,7 +60,8 @@ class StartupBenchmark {
packageName = PACKAGE_NAME, packageName = PACKAGE_NAME,
metrics = listOf(StartupTimingMetric()), metrics = listOf(StartupTimingMetric()),
compilationMode = compilationMode, compilationMode = compilationMode,
iterations = 20, // More iterations result in higher statistical significance. // More iterations result in higher statistical significance.
iterations = 20,
startupMode = COLD, startupMode = COLD,
setupBlock = { setupBlock = {
pressHome() pressHome()

@ -35,6 +35,8 @@ abstract class AnalyticsModule {
companion object { companion object {
@Provides @Provides
@Singleton @Singleton
fun provideFirebaseAnalytics(): FirebaseAnalytics { return Firebase.analytics } fun provideFirebaseAnalytics(): FirebaseAnalytics {
return Firebase.analytics
}
} }
} }

@ -134,7 +134,7 @@ fun NiaOutlinedButton(
MaterialTheme.colorScheme.outline MaterialTheme.colorScheme.outline
} else { } else {
MaterialTheme.colorScheme.onSurface.copy( MaterialTheme.colorScheme.onSurface.copy(
alpha = NiaButtonDefaults.DisabledOutlinedButtonBorderAlpha, alpha = NiaButtonDefaults.DISABLED_OUTLINED_BUTTON_BORDER_ALPHA,
) )
}, },
), ),
@ -278,7 +278,7 @@ fun NiaButtonPreview() {
@ThemePreviews @ThemePreviews
@Composable @Composable
fun NiaOutlinedButtonPreview() { fun NiaOutlinedButtonPreview() {
NiaTheme() { NiaTheme {
NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) {
NiaOutlinedButton(onClick = {}, text = { Text("Test button") }) NiaOutlinedButton(onClick = {}, text = { Text("Test button") })
} }
@ -315,7 +315,7 @@ fun NiaButtonLeadingIconPreview() {
object NiaButtonDefaults { object NiaButtonDefaults {
// TODO: File bug // TODO: File bug
// OutlinedButton border color doesn't respect disabled state by default // OutlinedButton border color doesn't respect disabled state by default
const val DisabledOutlinedButtonBorderAlpha = 0.12f const val DISABLED_OUTLINED_BUTTON_BORDER_ALPHA = 0.12f
// TODO: File bug // TODO: File bug
// OutlinedButton default border width isn't exposed via ButtonDefaults // OutlinedButton default border width isn't exposed via ButtonDefaults

@ -76,10 +76,10 @@ fun NiaFilterChip(
borderColor = MaterialTheme.colorScheme.onBackground, borderColor = MaterialTheme.colorScheme.onBackground,
selectedBorderColor = MaterialTheme.colorScheme.onBackground, selectedBorderColor = MaterialTheme.colorScheme.onBackground,
disabledBorderColor = MaterialTheme.colorScheme.onBackground.copy( disabledBorderColor = MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaChipDefaults.DisabledChipContentAlpha, alpha = NiaChipDefaults.DISABLED_CHIP_CONTENT_ALPHA,
), ),
disabledSelectedBorderColor = MaterialTheme.colorScheme.onBackground.copy( disabledSelectedBorderColor = MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaChipDefaults.DisabledChipContentAlpha, alpha = NiaChipDefaults.DISABLED_CHIP_CONTENT_ALPHA,
), ),
selectedBorderWidth = NiaChipDefaults.ChipBorderWidth, selectedBorderWidth = NiaChipDefaults.ChipBorderWidth,
), ),
@ -88,16 +88,16 @@ fun NiaFilterChip(
iconColor = MaterialTheme.colorScheme.onBackground, iconColor = MaterialTheme.colorScheme.onBackground,
disabledContainerColor = if (selected) { disabledContainerColor = if (selected) {
MaterialTheme.colorScheme.onBackground.copy( MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaChipDefaults.DisabledChipContainerAlpha, alpha = NiaChipDefaults.DISABLED_CHIP_CONTAINER_ALPHA,
) )
} else { } else {
Color.Transparent Color.Transparent
}, },
disabledLabelColor = MaterialTheme.colorScheme.onBackground.copy( disabledLabelColor = MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaChipDefaults.DisabledChipContentAlpha, alpha = NiaChipDefaults.DISABLED_CHIP_CONTENT_ALPHA,
), ),
disabledLeadingIconColor = MaterialTheme.colorScheme.onBackground.copy( disabledLeadingIconColor = MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaChipDefaults.DisabledChipContentAlpha, alpha = NiaChipDefaults.DISABLED_CHIP_CONTENT_ALPHA,
), ),
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer, selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
selectedLabelColor = MaterialTheme.colorScheme.onBackground, selectedLabelColor = MaterialTheme.colorScheme.onBackground,
@ -124,7 +124,7 @@ fun ChipPreview() {
object NiaChipDefaults { object NiaChipDefaults {
// TODO: File bug // TODO: File bug
// FilterChip default values aren't exposed via FilterChipDefaults // FilterChip default values aren't exposed via FilterChipDefaults
const val DisabledChipContainerAlpha = 0.12f const val DISABLED_CHIP_CONTAINER_ALPHA = 0.12f
const val DisabledChipContentAlpha = 0.38f const val DISABLED_CHIP_CONTENT_ALPHA = 0.38f
val ChipBorderWidth = 1.dp val ChipBorderWidth = 1.dp
} }

@ -60,7 +60,7 @@ fun NiaIconToggleButton(
checkedContentColor = MaterialTheme.colorScheme.onPrimaryContainer, checkedContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
disabledContainerColor = if (checked) { disabledContainerColor = if (checked) {
MaterialTheme.colorScheme.onBackground.copy( MaterialTheme.colorScheme.onBackground.copy(
alpha = NiaIconButtonDefaults.DisabledIconButtonContainerAlpha, alpha = NiaIconButtonDefaults.DISABLED_ICON_BUTTON_CONTAINER_ALPHA,
) )
} else { } else {
Color.Transparent Color.Transparent
@ -123,5 +123,5 @@ fun IconButtonPreviewUnchecked() {
object NiaIconButtonDefaults { object NiaIconButtonDefaults {
// TODO: File bug // TODO: File bug
// IconToggleButton disabled container alpha not exposed by IconButtonDefaults // IconToggleButton disabled container alpha not exposed by IconButtonDefaults
const val DisabledIconButtonContainerAlpha = 0.12f const val DISABLED_ICON_BUTTON_CONTAINER_ALPHA = 0.12f
} }

@ -40,7 +40,7 @@ fun NiaTopicTag(
MaterialTheme.colorScheme.primaryContainer MaterialTheme.colorScheme.primaryContainer
} else { } else {
MaterialTheme.colorScheme.surfaceVariant.copy( MaterialTheme.colorScheme.surfaceVariant.copy(
alpha = NiaTagDefaults.UnfollowedTopicTagContainerAlpha, alpha = NiaTagDefaults.UNFOLLOWED_TOPIC_TAG_CONTAINER_ALPHA,
) )
} }
TextButton( TextButton(
@ -50,7 +50,7 @@ fun NiaTopicTag(
containerColor = containerColor, containerColor = containerColor,
contentColor = contentColorFor(backgroundColor = containerColor), contentColor = contentColorFor(backgroundColor = containerColor),
disabledContainerColor = MaterialTheme.colorScheme.onSurface.copy( disabledContainerColor = MaterialTheme.colorScheme.onSurface.copy(
alpha = NiaTagDefaults.DisabledTopicTagContainerAlpha, alpha = NiaTagDefaults.DISABLED_TOPIC_TAG_CONTAINER_ALPHA,
), ),
), ),
) { ) {
@ -75,9 +75,9 @@ fun TagPreview() {
* Now in Android tag default values. * Now in Android tag default values.
*/ */
object NiaTagDefaults { object NiaTagDefaults {
const val UnfollowedTopicTagContainerAlpha = 0.5f const val UNFOLLOWED_TOPIC_TAG_CONTAINER_ALPHA = 0.5f
// TODO: File bug // TODO: File bug
// Button disabled container alpha value not exposed by ButtonDefaults // Button disabled container alpha value not exposed by ButtonDefaults
const val DisabledTopicTagContainerAlpha = 0.12f const val DISABLED_TOPIC_TAG_CONTAINER_ALPHA = 0.12f
} }

@ -251,5 +251,7 @@ private fun scrollbarThumbColor(
} }
private enum class ThumbState { private enum class ThumbState {
Active, Inactive, Dormant Active,
Inactive,
Dormant,
} }

@ -66,7 +66,7 @@ class LoadingWheelScreenshotTests() {
fun loadingWheelAnimation() { fun loadingWheelAnimation() {
composeTestRule.mainClock.autoAdvance = false composeTestRule.mainClock.autoAdvance = false
composeTestRule.setContent { composeTestRule.setContent {
NiaTheme() { NiaTheme {
NiaLoadingWheel(contentDesc = "") NiaLoadingWheel(contentDesc = "")
} }
} }

@ -17,5 +17,7 @@
package com.google.samples.apps.nowinandroid.core.model.data package com.google.samples.apps.nowinandroid.core.model.data
enum class DarkThemeConfig { enum class DarkThemeConfig {
FOLLOW_SYSTEM, LIGHT, DARK FOLLOW_SYSTEM,
LIGHT,
DARK,
} }

@ -19,7 +19,8 @@ package com.google.samples.apps.nowinandroid.core.model.data
/** /**
* A [topic] with the additional information for whether or not it is followed. * A [topic] with the additional information for whether or not it is followed.
*/ */
data class FollowableTopic( // TODO consider changing to UserTopic and flattening // TODO consider changing to UserTopic and flattening
data class FollowableTopic(
val topic: Topic, val topic: Topic,
val isFollowed: Boolean, val isFollowed: Boolean,
) )

@ -17,5 +17,6 @@
package com.google.samples.apps.nowinandroid.core.model.data package com.google.samples.apps.nowinandroid.core.model.data
enum class ThemeBrand { enum class ThemeBrand {
DEFAULT, ANDROID DEFAULT,
ANDROID,
} }

@ -44,10 +44,10 @@ class FakeNiaNetworkDataSourceTest {
) )
} }
@Suppress("ktlint:standard:max-line-length")
@Test @Test
fun testDeserializationOfTopics() = runTest(testDispatcher) { fun testDeserializationOfTopics() = runTest(testDispatcher) {
assertEquals( assertEquals(
/* ktlint-disable max-line-length */
NetworkTopic( NetworkTopic(
id = "1", id = "1",
name = "Headlines", name = "Headlines",
@ -56,15 +56,14 @@ class FakeNiaNetworkDataSourceTest {
url = "", url = "",
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_Headlines.svg?alt=media&token=506faab0-617a-4668-9e63-4a2fb996603f", imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_Headlines.svg?alt=media&token=506faab0-617a-4668-9e63-4a2fb996603f",
), ),
/* ktlint-enable max-line-length */
subject.getTopics().first(), subject.getTopics().first(),
) )
} }
@Suppress("ktlint:standard:max-line-length")
@Test @Test
fun testDeserializationOfNewsResources() = runTest(testDispatcher) { fun testDeserializationOfNewsResources() = runTest(testDispatcher) {
assertEquals( assertEquals(
/* ktlint-disable max-line-length */
NetworkNewsResource( NetworkNewsResource(
id = "125", id = "125",
title = "Android Basics with Compose", title = "Android Basics with Compose",
@ -83,7 +82,6 @@ class FakeNiaNetworkDataSourceTest {
type = "Codelab", type = "Codelab",
topics = listOf("2", "3", "10"), topics = listOf("2", "3", "10"),
), ),
/* ktlint-enable max-line-length */
subject.getNewsResources().find { it.id == "125" }, subject.getNewsResources().find { it.id == "125" },
) )
} }

@ -14,12 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.testing.data package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
/* ktlint-disable max-line-length */
val followableTopicTestData: List<FollowableTopic> = listOf( val followableTopicTestData: List<FollowableTopic> = listOf(
FollowableTopic( FollowableTopic(
topic = Topic( topic = Topic(

@ -14,12 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.testing.data package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
/* ktlint-disable max-line-length */
val newsResourcesTestData: List<NewsResource> = listOf( val newsResourcesTestData: List<NewsResource> = listOf(
NewsResource( NewsResource(
id = "1", id = "1",

@ -14,11 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.testing.data package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
/* ktlint-disable max-line-length */
val topicsTestData: List<Topic> = listOf( val topicsTestData: List<Topic> = listOf(
Topic( Topic(
id = "2", id = "2",

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.testing.data package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig
@ -26,7 +28,6 @@ import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant import kotlinx.datetime.toInstant
/* ktlint-disable max-line-length */
val userNewsResourcesTestData: List<UserNewsResource> = UserData( val userNewsResourcesTestData: List<UserNewsResource> = UserData(
bookmarkedNewsResources = setOf("1", "4"), bookmarkedNewsResources = setOf("1", "4"),
viewedNewsResources = setOf("1", "2", "4"), viewedNewsResources = setOf("1", "2", "4"),

@ -38,8 +38,10 @@ import org.robolectric.RuntimeEnvironment
val DefaultRoborazziOptions = val DefaultRoborazziOptions =
RoborazziOptions( RoborazziOptions(
compareOptions = CompareOptions(changeThreshold = 0f), // Pixel-perfect matching // Pixel-perfect matching
recordOptions = RecordOptions(resizeScale = 0.5), // Reduce the size of the PNGs compareOptions = CompareOptions(changeThreshold = 0f),
// Reduce the size of the PNGs
recordOptions = RecordOptions(resizeScale = 0.5),
) )
enum class DefaultTestDevices(val description: String, val spec: String) { enum class DefaultTestDevices(val description: String, val spec: String) {

@ -14,13 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.ui package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
/* ktlint-disable max-line-length */
/** /**
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider) * This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)
* provides list of [FollowableTopic] for Composable previews. * provides list of [FollowableTopic] for Composable previews.

@ -186,7 +186,8 @@ fun NewsResourceHeaderImage(
painterResource(drawable.ic_placeholder_default) painterResource(drawable.ic_placeholder_default)
}, },
// TODO b/226661685: Investigate using alt text of image to populate content description // TODO b/226661685: Investigate using alt text of image to populate content description
contentDescription = null, // decorative image, // decorative image,
contentDescription = null,
) )
} }
} }
@ -295,7 +296,8 @@ fun NewsResourceTopics(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Row( Row(
modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips // causes narrow chips
modifier = modifier.horizontalScroll(rememberScrollState()),
horizontalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp),
) { ) {
for (followableTopic in topics) { for (followableTopic in topics) {

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.core.ui package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -29,7 +31,6 @@ import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant import kotlinx.datetime.toInstant
/* ktlint-disable max-line-length */
/** /**
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider) * This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)
* provides list of [UserNewsResource] for Composable previews. * provides list of [UserNewsResource] for Composable previews.

@ -22,17 +22,17 @@ import androidx.navigation.NavOptions
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import com.google.samples.apps.nowinandroid.feature.bookmarks.BookmarksRoute import com.google.samples.apps.nowinandroid.feature.bookmarks.BookmarksRoute
const val bookmarksRoute = "bookmarks_route" const val BOOKMARKS_ROUTE = "bookmarks_route"
fun NavController.navigateToBookmarks(navOptions: NavOptions? = null) { fun NavController.navigateToBookmarks(navOptions: NavOptions? = null) {
this.navigate(bookmarksRoute, navOptions) this.navigate(BOOKMARKS_ROUTE, navOptions)
} }
fun NavGraphBuilder.bookmarksScreen( fun NavGraphBuilder.bookmarksScreen(
onTopicClick: (String) -> Unit, onTopicClick: (String) -> Unit,
onShowSnackbar: suspend (String, String?) -> Boolean, onShowSnackbar: suspend (String, String?) -> Boolean,
) { ) {
composable(route = bookmarksRoute) { composable(route = BOOKMARKS_ROUTE) {
BookmarksRoute(onTopicClick, onShowSnackbar) BookmarksRoute(onTopicClick, onShowSnackbar)
} }
} }

@ -437,7 +437,8 @@ fun TopicIcon(
DynamicAsyncImage( DynamicAsyncImage(
placeholder = painterResource(R.drawable.ic_icon_placeholder), placeholder = painterResource(R.drawable.ic_icon_placeholder),
imageUrl = imageUrl, imageUrl = imageUrl,
contentDescription = null, // decorative // decorative
contentDescription = null,
modifier = modifier modifier = modifier
.padding(10.dp) .padding(10.dp)
.size(32.dp), .size(32.dp),

@ -26,17 +26,17 @@ import androidx.navigation.navDeepLink
import com.google.samples.apps.nowinandroid.feature.foryou.ForYouRoute import com.google.samples.apps.nowinandroid.feature.foryou.ForYouRoute
const val LINKED_NEWS_RESOURCE_ID = "linkedNewsResourceId" const val LINKED_NEWS_RESOURCE_ID = "linkedNewsResourceId"
const val forYouNavigationRoute = "for_you_route/{$LINKED_NEWS_RESOURCE_ID}" const val FOR_YOU_ROUTE = "for_you_route/{$LINKED_NEWS_RESOURCE_ID}"
private const val DEEP_LINK_URI_PATTERN = private const val DEEP_LINK_URI_PATTERN =
"https://www.nowinandroid.apps.samples.google.com/foryou/{$LINKED_NEWS_RESOURCE_ID}" "https://www.nowinandroid.apps.samples.google.com/foryou/{$LINKED_NEWS_RESOURCE_ID}"
fun NavController.navigateToForYou(navOptions: NavOptions? = null) { fun NavController.navigateToForYou(navOptions: NavOptions? = null) {
this.navigate(forYouNavigationRoute, navOptions) this.navigate(FOR_YOU_ROUTE, navOptions)
} }
fun NavGraphBuilder.forYouScreen(onTopicClick: (String) -> Unit) { fun NavGraphBuilder.forYouScreen(onTopicClick: (String) -> Unit) {
composable( composable(
route = forYouNavigationRoute, route = FOR_YOU_ROUTE,
deepLinks = listOf( deepLinks = listOf(
navDeepLink { uriPattern = DEEP_LINK_URI_PATTERN }, navDeepLink { uriPattern = DEEP_LINK_URI_PATTERN },
), ),

@ -99,7 +99,8 @@ private fun InterestsIcon(topicImageUrl: String, modifier: Modifier = Modifier)
.background(MaterialTheme.colorScheme.surface) .background(MaterialTheme.colorScheme.surface)
.padding(4.dp), .padding(4.dp),
imageVector = NiaIcons.Person, imageVector = NiaIcons.Person,
contentDescription = null, // decorative image // decorative image
contentDescription = null,
) )
} else { } else {
DynamicAsyncImage( DynamicAsyncImage(

@ -24,7 +24,7 @@ import androidx.navigation.navigation
import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute import com.google.samples.apps.nowinandroid.feature.interests.InterestsRoute
private const val INTERESTS_GRAPH_ROUTE_PATTERN = "interests_graph" private const val INTERESTS_GRAPH_ROUTE_PATTERN = "interests_graph"
const val interestsRoute = "interests_route" const val INTERESTS_ROUTE = "interests_route"
fun NavController.navigateToInterestsGraph(navOptions: NavOptions? = null) { fun NavController.navigateToInterestsGraph(navOptions: NavOptions? = null) {
this.navigate(INTERESTS_GRAPH_ROUTE_PATTERN, navOptions) this.navigate(INTERESTS_GRAPH_ROUTE_PATTERN, navOptions)
@ -36,9 +36,9 @@ fun NavGraphBuilder.interestsGraph(
) { ) {
navigation( navigation(
route = INTERESTS_GRAPH_ROUTE_PATTERN, route = INTERESTS_GRAPH_ROUTE_PATTERN,
startDestination = interestsRoute, startDestination = INTERESTS_ROUTE,
) { ) {
composable(route = interestsRoute) { composable(route = INTERESTS_ROUTE) {
InterestsRoute(onTopicClick) InterestsRoute(onTopicClick)
} }
nestedGraphs() nestedGraphs()

@ -328,7 +328,8 @@ private fun SearchResultBody(
topics.forEach { followableTopic -> topics.forEach { followableTopic ->
val topicId = followableTopic.topic.id val topicId = followableTopic.topic.id
item( item(
key = "topic-$topicId", // Append a prefix to distinguish a key for news resources // Append a prefix to distinguish a key for news resources
key = "topic-$topicId",
span = StaggeredGridItemSpan.FullLine, span = StaggeredGridItemSpan.FullLine,
) { ) {
InterestsItem( InterestsItem(

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.feature.search package com.google.samples.apps.nowinandroid.feature.search
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -21,7 +23,6 @@ import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.topics import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.topics
/* ktlint-disable max-line-length */
/** /**
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider) * This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)
* provides list of [SearchResultUiState] for Composable previews. * provides list of [SearchResultUiState] for Composable previews.

@ -22,10 +22,10 @@ import androidx.navigation.NavOptions
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import com.google.samples.apps.nowinandroid.feature.search.SearchRoute import com.google.samples.apps.nowinandroid.feature.search.SearchRoute
const val searchRoute = "search_route" const val SEARCH_ROUTE = "search_route"
fun NavController.navigateToSearch(navOptions: NavOptions? = null) { fun NavController.navigateToSearch(navOptions: NavOptions? = null) {
this.navigate(searchRoute, navOptions) this.navigate(SEARCH_ROUTE, navOptions)
} }
fun NavGraphBuilder.searchScreen( fun NavGraphBuilder.searchScreen(
@ -35,7 +35,7 @@ fun NavGraphBuilder.searchScreen(
) { ) {
// TODO: Handle back stack for each top-level destination. At the moment each top-level // TODO: Handle back stack for each top-level destination. At the moment each top-level
// destination may have own search screen's back stack. // destination may have own search screen's back stack.
composable(route = searchRoute) { composable(route = SEARCH_ROUTE) {
SearchRoute( SearchRoute(
onBackClick = onBackClick, onBackClick = onBackClick,
onInterestsClick = onInterestsClick, onInterestsClick = onInterestsClick,

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("ktlint:standard:max-line-length")
package com.google.samples.apps.nowinandroid.feature.settings package com.google.samples.apps.nowinandroid.feature.settings
import android.content.Intent import android.content.Intent
@ -316,7 +318,6 @@ private fun PreviewSettingsDialogLoading() {
} }
} }
/* ktlint-disable max-line-length */
private const val PRIVACY_POLICY_URL = "https://policies.google.com/privacy" private const val PRIVACY_POLICY_URL = "https://policies.google.com/privacy"
private const val BRAND_GUIDELINES_URL = "https://developer.android.com/distribute/marketing-tools/brand-guidelines" private const val BRAND_GUIDELINES_URL = "https://developer.android.com/distribute/marketing-tools/brand-guidelines"
private const val FEEDBACK_URL = "https://goo.gle/nia-app-feedback" private const val FEEDBACK_URL = "https://goo.gle/nia-app-feedback"

@ -31,11 +31,11 @@ import kotlin.text.Charsets.UTF_8
private val URL_CHARACTER_ENCODING = UTF_8.name() private val URL_CHARACTER_ENCODING = UTF_8.name()
@VisibleForTesting @VisibleForTesting
internal const val topicIdArg = "topicId" internal const val TOPIC_ID_ARG = "topicId"
internal class TopicArgs(val topicId: String) { internal class TopicArgs(val topicId: String) {
constructor(savedStateHandle: SavedStateHandle) : constructor(savedStateHandle: SavedStateHandle) :
this(URLDecoder.decode(checkNotNull(savedStateHandle[topicIdArg]), URL_CHARACTER_ENCODING)) this(URLDecoder.decode(checkNotNull(savedStateHandle[TOPIC_ID_ARG]), URL_CHARACTER_ENCODING))
} }
fun NavController.navigateToTopic(topicId: String) { fun NavController.navigateToTopic(topicId: String) {
@ -50,9 +50,9 @@ fun NavGraphBuilder.topicScreen(
onTopicClick: (String) -> Unit, onTopicClick: (String) -> Unit,
) { ) {
composable( composable(
route = "topic_route/{$topicIdArg}", route = "topic_route/{$TOPIC_ID_ARG}",
arguments = listOf( arguments = listOf(
navArgument(topicIdArg) { type = NavType.StringType }, navArgument(TOPIC_ID_ARG) { type = NavType.StringType },
), ),
) { ) {
TopicRoute(onBackClick = onBackClick, onTopicClick = onTopicClick) TopicRoute(onBackClick = onBackClick, onTopicClick = onTopicClick)

@ -25,7 +25,7 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepo
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule
import com.google.samples.apps.nowinandroid.feature.topic.navigation.topicIdArg import com.google.samples.apps.nowinandroid.feature.topic.navigation.TOPIC_ID_ARG
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
@ -60,7 +60,7 @@ class TopicViewModelTest {
@Before @Before
fun setup() { fun setup() {
viewModel = TopicViewModel( viewModel = TopicViewModel(
savedStateHandle = SavedStateHandle(mapOf(topicIdArg to testInputTopics[0].topic.id)), savedStateHandle = SavedStateHandle(mapOf(TOPIC_ID_ARG to testInputTopics[0].topic.id)),
userDataRepository = userDataRepository, userDataRepository = userDataRepository,
topicsRepository = topicsRepository, topicsRepository = topicsRepository,
userNewsResourceRepository = userNewsResourceRepository, userNewsResourceRepository = userNewsResourceRepository,

@ -14,10 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
val ktlintVersion = "0.48.1" val ktlintVersion = "1.0.1"
initscript { initscript {
val spotlessVersion = "6.22.0" val spotlessVersion = "6.23.3"
repositories { repositories {
mavenCentral() mavenCentral()
@ -35,7 +35,11 @@ rootProject {
kotlin { kotlin {
target("**/*.kt") target("**/*.kt")
targetExclude("**/build/**/*.kt") targetExclude("**/build/**/*.kt")
ktlint(ktlintVersion).userData(mapOf("android" to "true")) ktlint(ktlintVersion).editorConfigOverride(
mapOf(
"android" to "true",
),
)
licenseHeaderFile(rootProject.file("spotless/copyright.kt")) licenseHeaderFile(rootProject.file("spotless/copyright.kt"))
} }
format("kts") { format("kts") {

@ -28,7 +28,7 @@ object Sync {
WorkManager.getInstance(context).apply { WorkManager.getInstance(context).apply {
// Run sync on app startup and ensure only one sync worker runs at any time // Run sync on app startup and ensure only one sync worker runs at any time
enqueueUniqueWork( enqueueUniqueWork(
SyncWorkName, SYNC_WORK_NAME,
ExistingWorkPolicy.KEEP, ExistingWorkPolicy.KEEP,
SyncWorker.startUpSyncWork(), SyncWorker.startUpSyncWork(),
) )
@ -37,4 +37,4 @@ object Sync {
} }
// This name should not be changed otherwise the app may have concurrent sync requests running // This name should not be changed otherwise the app may have concurrent sync requests running
internal const val SyncWorkName = "SyncWorkName" internal const val SYNC_WORK_NAME = "SyncWorkName"

@ -22,7 +22,7 @@ import androidx.work.WorkInfo
import androidx.work.WorkInfo.State import androidx.work.WorkInfo.State
import androidx.work.WorkManager import androidx.work.WorkManager
import com.google.samples.apps.nowinandroid.core.data.util.SyncManager import com.google.samples.apps.nowinandroid.core.data.util.SyncManager
import com.google.samples.apps.nowinandroid.sync.initializers.SyncWorkName import com.google.samples.apps.nowinandroid.sync.initializers.SYNC_WORK_NAME
import com.google.samples.apps.nowinandroid.sync.workers.SyncWorker import com.google.samples.apps.nowinandroid.sync.workers.SyncWorker
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -37,7 +37,7 @@ class WorkManagerSyncManager @Inject constructor(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
) : SyncManager { ) : SyncManager {
override val isSyncing: Flow<Boolean> = override val isSyncing: Flow<Boolean> =
WorkManager.getInstance(context).getWorkInfosForUniqueWorkFlow(SyncWorkName) WorkManager.getInstance(context).getWorkInfosForUniqueWorkFlow(SYNC_WORK_NAME)
.map(List<WorkInfo>::anyRunning) .map(List<WorkInfo>::anyRunning)
.conflate() .conflate()
@ -45,7 +45,7 @@ class WorkManagerSyncManager @Inject constructor(
val workManager = WorkManager.getInstance(context) val workManager = WorkManager.getInstance(context)
// Run sync on app startup and ensure only one sync worker runs at any time // Run sync on app startup and ensure only one sync worker runs at any time
workManager.enqueueUniqueWork( workManager.enqueueUniqueWork(
SyncWorkName, SYNC_WORK_NAME,
ExistingWorkPolicy.KEEP, ExistingWorkPolicy.KEEP,
SyncWorker.startUpSyncWork(), SyncWorker.startUpSyncWork(),
) )

Loading…
Cancel
Save