From 445c18a80363bb03fc3d3d39f2620652fa145699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Moczkowski?= Date: Wed, 5 Jul 2023 13:18:57 +0200 Subject: [PATCH] Refactor InterestsItem to Material3 ListItem Change-Id: I12adc8820964aecd97ea0b4e22ae13e95e1428ab --- .../feature/interests/InterestsItem.kt | 101 +++++++----------- .../feature/search/SearchScreenTest.kt | 24 +++-- 2 files changed, 56 insertions(+), 69 deletions(-) diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt index ec9fd8f10..7456ba92b 100644 --- a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt +++ b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt @@ -18,22 +18,20 @@ package com.google.samples.apps.nowinandroid.feature.interests import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.material3.Icon +import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.component.DynamicAsyncImage import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton @@ -51,63 +49,46 @@ fun InterestsItem( modifier: Modifier = Modifier, iconModifier: Modifier = Modifier, description: String = "", - itemSeparation: Dp = 16.dp, ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = modifier, - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .weight(1f) - .clickable { onClick() } - .padding(vertical = itemSeparation), - ) { + ListItem( + leadingContent = { InterestsIcon(topicImageUrl, iconModifier.size(64.dp)) - Spacer(modifier = Modifier.width(24.dp)) - InterestContent(name, description) - } - NiaIconToggleButton( - checked = following, - onCheckedChange = onFollowButtonClick, - icon = { - Icon( - imageVector = NiaIcons.Add, - contentDescription = stringResource( - id = string.card_follow_button_content_desc, - ), - ) - }, - checkedIcon = { - Icon( - imageVector = NiaIcons.Check, - contentDescription = stringResource( - id = string.card_unfollow_button_content_desc, - ), - ) - }, - ) - } -} - -@Composable -private fun InterestContent(name: String, description: String, modifier: Modifier = Modifier) { - Column(modifier) { - Text( - text = name, - style = MaterialTheme.typography.headlineSmall, - modifier = Modifier.padding( - vertical = if (description.isEmpty()) 0.dp else 4.dp, - ), - ) - if (description.isNotEmpty()) { - Text( - text = description, - style = MaterialTheme.typography.bodyMedium, + }, + headlineContent = { + Text(text = name) + }, + supportingContent = { + Text(text = description) + }, + trailingContent = { + NiaIconToggleButton( + checked = following, + onCheckedChange = onFollowButtonClick, + icon = { + Icon( + imageVector = NiaIcons.Add, + contentDescription = stringResource( + id = string.card_follow_button_content_desc, + ), + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Check, + contentDescription = stringResource( + id = string.card_unfollow_button_content_desc, + ), + ) + }, ) - } - } + }, + colors = ListItemDefaults.colors( + containerColor = Color.Transparent, + ), + modifier = modifier + .semantics(mergeDescendants = true) { /* no-op */ } + .clickable(enabled = true, onClick = onClick), + ) } @Composable diff --git a/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt b/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt index 53f00c0dc..d6c07221e 100644 --- a/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt +++ b/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt @@ -20,11 +20,14 @@ import androidx.activity.ComponentActivity import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsFocused +import androidx.compose.ui.test.hasScrollToNodeAction import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onAllNodesWithContentDescription +import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performScrollToIndex import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.DARK import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.ANDROID @@ -139,15 +142,18 @@ class SearchScreenTest { composeTestRule .onNodeWithText(topicsString) .assertIsDisplayed() - composeTestRule - .onNodeWithText(followableTopicTestData[0].topic.name) - .assertIsDisplayed() - composeTestRule - .onNodeWithText(followableTopicTestData[1].topic.name) - .assertIsDisplayed() - composeTestRule - .onNodeWithText(followableTopicTestData[2].topic.name) - .assertIsDisplayed() + + val scrollableNode = composeTestRule + .onAllNodes(hasScrollToNodeAction()) + .onFirst() + + followableTopicTestData.forEachIndexed { index, followableTopic -> + scrollableNode.performScrollToIndex(index) + + composeTestRule + .onNodeWithText(followableTopic.topic.name) + .assertIsDisplayed() + } composeTestRule .onAllNodesWithContentDescription(followButtonContentDesc)