Enforce `resourcePrefix` on Android library modules

```
:ui-test-hilt-manifest -> ui_test_hilt_manifest_
:core:analytics -> core_analytics_
:core:common -> core_common_
:core:data -> core_data_
:core:data-test -> core_data_test_
:core:database -> core_database_
:core:datastore -> core_datastore_
:core:datastore-test -> core_datastore_test_
:core:designsystem -> core_designsystem_
:core:domain -> core_domain_
:core:network -> core_network_
:core:notifications -> core_notifications_
:core:testing -> core_testing_
:core:ui -> core_ui_
:feature:bookmarks -> feature_bookmarks_
:feature:foryou -> feature_foryou_
:feature:interests -> feature_interests_
:feature:search -> feature_search_
:feature:settings -> feature_settings_
:feature:topic -> feature_topic_
:sync:sync-test -> sync_test_
:sync:work -> sync_work_
```
pull/767/head
Simon Marquis 1 year ago
parent 151f877bbe
commit ebfe01affd

@ -51,7 +51,7 @@ import javax.inject.Inject
import kotlin.properties.ReadOnlyProperty
import com.google.samples.apps.nowinandroid.feature.bookmarks.R as BookmarksR
import com.google.samples.apps.nowinandroid.feature.foryou.R as FeatureForyouR
import com.google.samples.apps.nowinandroid.feature.interests.R as FeatureInterestsR
import com.google.samples.apps.nowinandroid.feature.search.R as FeatureSearchR
import com.google.samples.apps.nowinandroid.feature.settings.R as SettingsR
/**
@ -93,15 +93,15 @@ class NavigationTest {
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
// The strings used for matching in these tests
private val navigateUp by composeTestRule.stringResource(FeatureForyouR.string.navigate_up)
private val forYou by composeTestRule.stringResource(FeatureForyouR.string.for_you)
private val interests by composeTestRule.stringResource(FeatureInterestsR.string.interests)
private val navigateUp by composeTestRule.stringResource(FeatureForyouR.string.feature_foryou_navigate_up)
private val forYou by composeTestRule.stringResource(FeatureForyouR.string.feature_foryou_title)
private val interests by composeTestRule.stringResource(FeatureSearchR.string.feature_search_interests)
private val sampleTopic = "Headlines"
private val appName by composeTestRule.stringResource(R.string.app_name)
private val saved by composeTestRule.stringResource(BookmarksR.string.saved)
private val settings by composeTestRule.stringResource(SettingsR.string.top_app_bar_action_icon_description)
private val brand by composeTestRule.stringResource(SettingsR.string.brand_android)
private val ok by composeTestRule.stringResource(SettingsR.string.dismiss_dialog_button_text)
private val saved by composeTestRule.stringResource(BookmarksR.string.feature_bookmarks_title)
private val settings by composeTestRule.stringResource(SettingsR.string.feature_settings_top_app_bar_action_icon_description)
private val brand by composeTestRule.stringResource(SettingsR.string.feature_settings_brand_android)
private val ok by composeTestRule.stringResource(SettingsR.string.feature_settings_dismiss_dialog_button_text)
@Before
fun setup() = hiltRule.inject()

@ -21,7 +21,7 @@ import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.feature.bookmarks.R as bookmarksR
import com.google.samples.apps.nowinandroid.feature.foryou.R as forYouR
import com.google.samples.apps.nowinandroid.feature.interests.R as interestsR
import com.google.samples.apps.nowinandroid.feature.search.R as searchR
/**
* Type for the top level destinations in the application. Each of these destinations
@ -37,19 +37,19 @@ enum class TopLevelDestination(
FOR_YOU(
selectedIcon = NiaIcons.Upcoming,
unselectedIcon = NiaIcons.UpcomingBorder,
iconTextId = forYouR.string.for_you,
iconTextId = forYouR.string.feature_foryou_title,
titleTextId = R.string.app_name,
),
BOOKMARKS(
selectedIcon = NiaIcons.Bookmarks,
unselectedIcon = NiaIcons.BookmarksBorder,
iconTextId = bookmarksR.string.saved,
titleTextId = bookmarksR.string.saved,
iconTextId = bookmarksR.string.feature_bookmarks_title,
titleTextId = bookmarksR.string.feature_bookmarks_title,
),
INTERESTS(
selectedIcon = NiaIcons.Grid3x3,
unselectedIcon = NiaIcons.Grid3x3,
iconTextId = interestsR.string.interests,
titleTextId = interestsR.string.interests,
iconTextId = searchR.string.feature_search_interests,
titleTextId = searchR.string.feature_search_interests,
),
}

@ -183,11 +183,11 @@ fun NiaApp(
titleRes = destination.titleTextId,
navigationIcon = NiaIcons.Search,
navigationIconContentDescription = stringResource(
id = settingsR.string.top_app_bar_navigation_icon_description,
id = settingsR.string.feature_settings_top_app_bar_navigation_icon_description,
),
actionIcon = NiaIcons.Settings,
actionIconContentDescription = stringResource(
id = settingsR.string.top_app_bar_action_icon_description,
id = settingsR.string.feature_settings_top_app_bar_action_icon_description,
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent,

@ -41,6 +41,9 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
defaultConfig.targetSdk = 34
configureFlavors(this)
configureGradleManagedDevices(this)
// The resource prefix is derived from the module name,
// so resources inside ":core:module1" must be prefixed with "core_module1_"
resourcePrefix = path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_").lowercase() + "_"
}
extensions.configure<LibraryAndroidComponentsExtension> {
configurePrintApksTask(this)

@ -49,7 +49,7 @@ fun DynamicAsyncImage(
imageUrl: String,
contentDescription: String?,
modifier: Modifier = Modifier,
placeholder: Painter = painterResource(R.drawable.ic_placeholder_default),
placeholder: Painter = painterResource(R.drawable.core_designsystem_ic_placeholder_default),
) {
val iconTint = LocalTintTheme.current.iconTint
var isLoading by remember { mutableStateOf(true) }

@ -72,7 +72,7 @@ class SystemTrayNotifier @Inject constructor(
.map { newsResource ->
createNewsNotification {
setSmallIcon(
com.google.samples.apps.nowinandroid.core.common.R.drawable.ic_nia_notification,
com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification,
)
.setContentTitle(newsResource.title)
.setContentText(newsResource.content)
@ -83,13 +83,13 @@ class SystemTrayNotifier @Inject constructor(
}
val summaryNotification = createNewsNotification {
val title = getString(
R.string.news_notification_group_summary,
R.string.core_notifications_news_notification_group_summary,
truncatedNewsResources.size,
)
setContentTitle(title)
.setContentText(title)
.setSmallIcon(
com.google.samples.apps.nowinandroid.core.common.R.drawable.ic_nia_notification,
com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification,
)
// Build summary info into InboxStyle template.
.setStyle(newsNotificationStyle(truncatedNewsResources, title))
@ -148,10 +148,10 @@ private fun Context.ensureNotificationChannelExists() {
val channel = NotificationChannel(
NEWS_NOTIFICATION_CHANNEL_ID,
getString(R.string.news_notification_channel_name),
getString(R.string.core_notifications_news_notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT,
).apply {
description = getString(R.string.news_notification_channel_description)
description = getString(R.string.core_notifications_news_notification_channel_description)
}
// Register the channel with the system
NotificationManagerCompat.from(this).createNotificationChannel(channel)

@ -15,7 +15,7 @@
limitations under the License.
-->
<resources>
<string name="news_notification_channel_name">News updates</string>
<string name="news_notification_channel_description">The latest updates on what\'s new in Android</string>
<string name="news_notification_group_summary">%1$d news updates</string>
<string name="core_notifications_news_notification_channel_name">News updates</string>
<string name="core_notifications_news_notification_channel_description">The latest updates on what\'s new in Android</string>
<string name="core_notifications_news_notification_group_summary">%1$d news updates</string>
</resources>

@ -52,7 +52,7 @@ class NewsResourceCardTest {
composeTestRule
.onNodeWithText(
composeTestRule.activity.getString(
R.string.card_meta_data_text,
R.string.core_ui_card_meta_data_text,
dateFormatted,
newsWithKnownResourceType.type,
),
@ -123,7 +123,7 @@ class NewsResourceCardTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.getString(
R.string.unread_resource_dot_content_description,
R.string.core_ui_unread_resource_dot_content_description,
),
)
.assertIsDisplayed()
@ -147,7 +147,7 @@ class NewsResourceCardTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.getString(
R.string.unread_resource_dot_content_description,
R.string.core_ui_unread_resource_dot_content_description,
),
)
.assertDoesNotExist()

@ -91,7 +91,7 @@ fun NewsResourceCardExpanded(
onTopicClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
val clickActionLabel = stringResource(R.string.card_tap_action)
val clickActionLabel = stringResource(R.string.core_ui_card_tap_action)
Card(
onClick = onClick,
shape = RoundedCornerShape(16.dp),
@ -183,7 +183,7 @@ fun NewsResourceHeaderImage(
painter = if (isError.not() && !isLocalInspection) {
imageLoader
} else {
painterResource(drawable.ic_placeholder_default)
painterResource(drawable.core_designsystem_ic_placeholder_default)
},
// TODO b/226661685: Investigate using alt text of image to populate content description
contentDescription = null, // decorative image,
@ -212,13 +212,13 @@ fun BookmarkButton(
icon = {
Icon(
imageVector = NiaIcons.BookmarkBorder,
contentDescription = stringResource(R.string.bookmark),
contentDescription = stringResource(R.string.core_ui_bookmark),
)
},
checkedIcon = {
Icon(
imageVector = NiaIcons.Bookmark,
contentDescription = stringResource(R.string.unbookmark),
contentDescription = stringResource(R.string.core_ui_unbookmark),
)
},
)
@ -229,7 +229,7 @@ fun NotificationDot(
color: Color,
modifier: Modifier = Modifier,
) {
val description = stringResource(R.string.unread_resource_dot_content_description)
val description = stringResource(R.string.core_ui_unread_resource_dot_content_description)
Canvas(
modifier = modifier
.semantics { contentDescription = description },
@ -273,7 +273,7 @@ fun NewsResourceMetaData(
val formattedDate = dateFormatted(publishDate)
Text(
if (resourceType.isNotBlank()) {
stringResource(R.string.card_meta_data_text, formattedDate, resourceType)
stringResource(R.string.core_ui_card_meta_data_text, formattedDate, resourceType)
} else {
formattedDate
},
@ -305,12 +305,12 @@ fun NewsResourceTopics(
text = {
val contentDescription = if (followableTopic.isFollowed) {
stringResource(
R.string.topic_chip_content_description_when_followed,
R.string.core_ui_topic_chip_content_description_when_followed,
followableTopic.topic.name,
)
} else {
stringResource(
R.string.topic_chip_content_description_when_not_followed,
R.string.core_ui_topic_chip_content_description_when_not_followed,
followableTopic.topic.name,
)
}

@ -15,15 +15,15 @@
limitations under the License.
-->
<resources>
<string name="bookmark">Bookmark</string>
<string name="unbookmark">Unbookmark</string>
<string name="back">Back</string>
<string name="core_ui_bookmark">Bookmark</string>
<string name="core_ui_unbookmark">Unbookmark</string>
<string name="core_ui_back">Back</string>
<string name="unread_resource_dot_content_description">Unread</string>
<string name="core_ui_unread_resource_dot_content_description">Unread</string>
<string name="card_tap_action">Open Resource Link</string>
<string name="card_meta_data_text">%1$s • %2$s</string>
<string name="core_ui_card_tap_action">Open Resource Link</string>
<string name="core_ui_card_meta_data_text">%1$s • %2$s</string>
<string name="topic_chip_content_description_when_followed">%1$s is followed</string>
<string name="topic_chip_content_description_when_not_followed">%1$s is not followed</string>
<string name="core_ui_topic_chip_content_description_when_followed">%1$s is followed</string>
<string name="core_ui_topic_chip_content_description_when_not_followed">%1$s is not followed</string>
</resources>

@ -59,7 +59,7 @@ class BookmarksScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.saved_loading),
composeTestRule.activity.resources.getString(R.string.feature_bookmarks_loading),
)
.assertExists()
}
@ -125,7 +125,7 @@ class BookmarksScreenTest {
composeTestRule
.onAllNodesWithContentDescription(
composeTestRule.activity.getString(
com.google.samples.apps.nowinandroid.core.ui.R.string.unbookmark,
com.google.samples.apps.nowinandroid.core.ui.R.string.core_ui_unbookmark,
),
).filter(
hasAnyAncestor(
@ -156,13 +156,13 @@ class BookmarksScreenTest {
composeTestRule
.onNodeWithText(
composeTestRule.activity.getString(R.string.bookmarks_empty_error),
composeTestRule.activity.getString(R.string.feature_bookmarks_empty_error),
)
.assertExists()
composeTestRule
.onNodeWithText(
composeTestRule.activity.getString(R.string.bookmarks_empty_description),
composeTestRule.activity.getString(R.string.feature_bookmarks_empty_description),
)
.assertExists()
}

@ -113,8 +113,8 @@ internal fun BookmarksScreen(
undoBookmarkRemoval: () -> Unit = {},
clearUndoState: () -> Unit = {},
) {
val bookmarkRemovedMessage = stringResource(id = R.string.bookmark_removed)
val undoText = stringResource(id = R.string.undo)
val bookmarkRemovedMessage = stringResource(id = R.string.feature_bookmarks_removed)
val undoText = stringResource(id = R.string.feature_bookmarks_undo)
LaunchedEffect(shouldDisplayUndoBookmark) {
if (shouldDisplayUndoBookmark) {
@ -163,7 +163,7 @@ private fun LoadingState(modifier: Modifier = Modifier) {
.fillMaxWidth()
.wrapContentSize()
.testTag("forYou:loading"),
contentDesc = stringResource(id = R.string.saved_loading),
contentDesc = stringResource(id = R.string.feature_bookmarks_loading),
)
}
@ -236,7 +236,7 @@ private fun EmptyState(modifier: Modifier = Modifier) {
val iconTint = LocalTintTheme.current.iconTint
Image(
modifier = Modifier.fillMaxWidth(),
painter = painterResource(id = R.drawable.img_empty_bookmarks),
painter = painterResource(id = R.drawable.feature_bookmarks_img_empty_bookmarks),
colorFilter = if (iconTint != null) ColorFilter.tint(iconTint) else null,
contentDescription = null,
)
@ -244,7 +244,7 @@ private fun EmptyState(modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.height(48.dp))
Text(
text = stringResource(id = R.string.bookmarks_empty_error),
text = stringResource(id = R.string.feature_bookmarks_empty_error),
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleMedium,
@ -254,7 +254,7 @@ private fun EmptyState(modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(id = R.string.bookmarks_empty_description),
text = stringResource(id = R.string.feature_bookmarks_empty_description),
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,

@ -15,10 +15,10 @@
limitations under the License.
-->
<resources>
<string name="saved">Saved</string>
<string name="saved_loading">Loading saved…</string>
<string name="bookmarks_empty_error">No saved updates</string>
<string name="bookmarks_empty_description">Updates you save will be stored here\nto read later</string>
<string name="bookmark_removed">Bookmark removed</string>
<string name="undo">UNDO</string>
<string name="feature_bookmarks_title">Saved</string>
<string name="feature_bookmarks_loading">Loading saved…</string>
<string name="feature_bookmarks_empty_error">No saved updates</string>
<string name="feature_bookmarks_empty_description">Updates you save will be stored here\nto read later</string>
<string name="feature_bookmarks_removed">Bookmark removed</string>
<string name="feature_bookmarks_undo">UNDO</string>
</resources>

@ -45,7 +45,7 @@ class ForYouScreenTest {
private val doneButtonMatcher by lazy {
hasText(
composeTestRule.activity.resources.getString(R.string.done),
composeTestRule.activity.resources.getString(R.string.feature_foryou_done),
)
}
@ -70,7 +70,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.for_you_loading),
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
)
.assertExists()
}
@ -96,7 +96,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.for_you_loading),
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
)
.assertExists()
}
@ -215,7 +215,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.for_you_loading),
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
)
.assertExists()
}
@ -241,7 +241,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.for_you_loading),
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
)
.assertExists()
}

@ -216,7 +216,7 @@ internal fun ForYouScreen(
targetOffsetY = { fullHeight -> -fullHeight },
) + fadeOut(),
) {
val loadingContentDescription = stringResource(id = R.string.for_you_loading)
val loadingContentDescription = stringResource(id = R.string.feature_foryou_loading)
Box(
modifier = Modifier
.fillMaxWidth()
@ -271,7 +271,7 @@ private fun LazyGridScope.onboarding(
item(span = { GridItemSpan(maxLineSpan) }, contentType = "onboarding") {
Column(modifier = interestsItemModifier) {
Text(
text = stringResource(R.string.onboarding_guidance_title),
text = stringResource(R.string.feature_foryou_onboarding_guidance_title),
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
@ -279,7 +279,7 @@ private fun LazyGridScope.onboarding(
style = MaterialTheme.typography.titleMedium,
)
Text(
text = stringResource(R.string.onboarding_guidance_subtitle),
text = stringResource(R.string.feature_foryou_onboarding_guidance_subtitle),
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp, start = 24.dp, end = 24.dp),
@ -305,7 +305,7 @@ private fun LazyGridScope.onboarding(
.fillMaxWidth(),
) {
Text(
text = stringResource(R.string.done),
text = stringResource(R.string.feature_foryou_done),
)
}
}
@ -434,7 +434,7 @@ fun TopicIcon(
modifier: Modifier = Modifier,
) {
DynamicAsyncImage(
placeholder = painterResource(R.drawable.ic_icon_placeholder),
placeholder = painterResource(R.drawable.feature_foryou_ic_icon_placeholder),
imageUrl = imageUrl,
contentDescription = null, // decorative
modifier = modifier

@ -15,11 +15,11 @@
limitations under the License.
-->
<resources>
<string name="for_you">For you</string>
<string name="done">Done</string>
<string name="for_you_loading">Loading for you…</string>
<string name="navigate_up">Navigate up</string>
<string name="onboarding_guidance_title">What are you interested in?</string>
<string name="onboarding_guidance_subtitle">Updates from topics you follow will appear here. Follow some things to get started.</string>
<string name="feature_foryou_title">For you</string>
<string name="feature_foryou_done">Done</string>
<string name="feature_foryou_loading">Loading for you…</string>
<string name="feature_foryou_navigate_up">Navigate up</string>
<string name="feature_foryou_onboarding_guidance_title">What are you interested in?</string>
<string name="feature_foryou_onboarding_guidance_subtitle">Updates from topics you follow will appear here. Follow some things to get started.</string>
</resources>

@ -50,12 +50,12 @@ class InterestsScreenTest {
@Before
fun setup() {
composeTestRule.activity.apply {
interestsLoading = getString(R.string.loading)
interestsEmptyHeader = getString(R.string.empty_header)
interestsLoading = getString(R.string.feature_interests_loading)
interestsEmptyHeader = getString(R.string.feature_interests_empty_header)
interestsTopicCardFollowButton =
getString(R.string.card_follow_button_content_desc)
getString(R.string.feature_interests_card_follow_button_content_desc)
interestsTopicCardUnfollowButton =
getString(R.string.card_unfollow_button_content_desc)
getString(R.string.feature_interests_card_unfollow_button_content_desc)
}
}

@ -68,7 +68,7 @@ fun InterestsItem(
Icon(
imageVector = NiaIcons.Add,
contentDescription = stringResource(
id = string.card_follow_button_content_desc,
id = string.feature_interests_card_follow_button_content_desc,
),
)
},
@ -76,7 +76,7 @@ fun InterestsItem(
Icon(
imageVector = NiaIcons.Check,
contentDescription = stringResource(
id = string.card_unfollow_button_content_desc,
id = string.feature_interests_card_unfollow_button_content_desc,
),
)
},

@ -65,7 +65,7 @@ internal fun InterestsScreen(
InterestsUiState.Loading ->
NiaLoadingWheel(
modifier = modifier,
contentDesc = stringResource(id = R.string.loading),
contentDesc = stringResource(id = R.string.feature_interests_loading),
)
is InterestsUiState.Interests ->
TopicsTabContent(
@ -82,7 +82,7 @@ internal fun InterestsScreen(
@Composable
private fun InterestsEmptyScreen() {
Text(text = stringResource(id = R.string.empty_header))
Text(text = stringResource(id = R.string.feature_interests_empty_header))
}
@DevicePreviews

@ -15,9 +15,9 @@
limitations under the License.
-->
<resources>
<string name="interests">Interests</string>
<string name="loading">Loading data</string>
<string name="empty_header">"No available data"</string>
<string name="card_follow_button_content_desc">Follow interest</string>
<string name="card_unfollow_button_content_desc">Unfollow interest</string>
<string name="feature_interests_title">Interests</string>
<string name="feature_interests_loading">Loading data</string>
<string name="feature_interests_empty_header">"No available data"</string>
<string name="feature_interests_card_follow_button_content_desc">Follow interest</string>
<string name="feature_interests_card_unfollow_button_content_desc">Unfollow interest</string>
</resources>

@ -70,17 +70,17 @@ class SearchScreenTest {
@Before
fun setup() {
composeTestRule.activity.apply {
clearSearchContentDesc = getString(R.string.clear_search_text_content_desc)
clearRecentSearchesContentDesc = getString(R.string.clear_recent_searches_content_desc)
clearSearchContentDesc = getString(R.string.feature_search_clear_search_text_content_desc)
clearRecentSearchesContentDesc = getString(R.string.feature_search_clear_recent_searches_content_desc)
followButtonContentDesc =
getString(interestsR.string.card_follow_button_content_desc)
getString(interestsR.string.feature_interests_card_follow_button_content_desc)
unfollowButtonContentDesc =
getString(interestsR.string.card_unfollow_button_content_desc)
topicsString = getString(R.string.topics)
updatesString = getString(R.string.updates)
tryAnotherSearchString = getString(R.string.try_another_search) +
" " + getString(R.string.interests) + " " + getString(R.string.to_browse_topics)
searchNotReadyString = getString(R.string.search_not_ready)
getString(interestsR.string.feature_interests_card_unfollow_button_content_desc)
topicsString = getString(R.string.feature_search_topics)
updatesString = getString(R.string.feature_search_updates)
tryAnotherSearchString = getString(R.string.feature_search_try_another_search) +
" " + getString(R.string.feature_search_interests) + " " + getString(R.string.feature_search_to_browse_topics)
searchNotReadyString = getString(R.string.feature_search_not_ready)
}
}

@ -217,7 +217,7 @@ fun EmptySearchResultBody(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 48.dp),
) {
val message = stringResource(id = searchR.string.search_result_not_found, searchQuery)
val message = stringResource(id = searchR.string.feature_search_result_not_found, searchQuery)
val start = message.indexOf(searchQuery)
Text(
text = AnnotatedString(
@ -234,9 +234,9 @@ fun EmptySearchResultBody(
textAlign = TextAlign.Center,
modifier = Modifier.padding(vertical = 24.dp),
)
val interests = stringResource(id = searchR.string.interests)
val interests = stringResource(id = searchR.string.feature_search_interests)
val tryAnotherSearchString = buildAnnotatedString {
append(stringResource(id = searchR.string.try_another_search))
append(stringResource(id = searchR.string.feature_search_try_another_search))
append(" ")
withStyle(
style = SpanStyle(
@ -248,7 +248,7 @@ fun EmptySearchResultBody(
append(interests)
}
append(" ")
append(stringResource(id = searchR.string.to_browse_topics))
append(stringResource(id = searchR.string.feature_search_to_browse_topics))
}
ClickableText(
text = tryAnotherSearchString,
@ -278,7 +278,7 @@ private fun SearchNotReadyBody() {
modifier = Modifier.padding(horizontal = 48.dp),
) {
Text(
text = stringResource(id = searchR.string.search_not_ready),
text = stringResource(id = searchR.string.feature_search_not_ready),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center,
modifier = Modifier.padding(vertical = 24.dp),
@ -321,7 +321,7 @@ private fun SearchResultBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.topics))
append(stringResource(id = searchR.string.feature_search_topics))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -360,7 +360,7 @@ private fun SearchResultBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.updates))
append(stringResource(id = searchR.string.feature_search_updates))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -412,7 +412,7 @@ private fun RecentSearchesBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.recent_searches))
append(stringResource(id = searchR.string.feature_search_recent_searches))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -427,7 +427,7 @@ private fun RecentSearchesBody(
Icon(
imageVector = NiaIcons.Close,
contentDescription = stringResource(
id = searchR.string.clear_recent_searches_content_desc,
id = searchR.string.feature_search_clear_recent_searches_content_desc,
),
tint = MaterialTheme.colorScheme.onSurface,
)
@ -465,7 +465,7 @@ private fun SearchToolbar(
Icon(
imageVector = NiaIcons.ArrowBack,
contentDescription = stringResource(
id = string.back,
id = string.core_ui_back,
),
)
}
@ -502,7 +502,7 @@ private fun SearchTextField(
Icon(
imageVector = NiaIcons.Search,
contentDescription = stringResource(
id = searchR.string.search,
id = searchR.string.feature_search_title,
),
tint = MaterialTheme.colorScheme.onSurface,
)
@ -517,7 +517,7 @@ private fun SearchTextField(
Icon(
imageVector = NiaIcons.Close,
contentDescription = stringResource(
id = searchR.string.clear_search_text_content_desc,
id = searchR.string.feature_search_clear_search_text_content_desc,
),
tint = MaterialTheme.colorScheme.onSurface,
)

@ -15,15 +15,15 @@
limitations under the License.
-->
<resources>
<string name="search">Search</string>
<string name="clear_search_text_content_desc">Clear search text</string>
<string name="search_result_not_found">Sorry, there is no content found for your search \"%1$s\"</string>
<string name="search_not_ready">Sorry, we are still processing the search index. Please come back later.</string>
<string name="try_another_search">Try another search or explorer </string>
<string name="interests">Interests</string>
<string name="to_browse_topics"> to browse topics</string>
<string name="topics">Topics</string>
<string name="updates">Updates</string>
<string name="recent_searches">Recent searches</string>
<string name="clear_recent_searches_content_desc">Clear searches</string>
<string name="feature_search_title">Search</string>
<string name="feature_search_clear_search_text_content_desc">Clear search text</string>
<string name="feature_search_result_not_found">Sorry, there is no content found for your search \"%1$s\"</string>
<string name="feature_search_not_ready">Sorry, we are still processing the search index. Please come back later</string>
<string name="feature_search_try_another_search">Try another search or explorer </string>
<string name="feature_search_interests">Interests</string>
<string name="feature_search_to_browse_topics"> to browse topics</string>
<string name="feature_search_topics">Topics</string>
<string name="feature_search_updates">Updates</string>
<string name="feature_search_recent_searches">Recent searches</string>
<string name="feature_search_clear_recent_searches_content_desc">Clear searches</string>
</resources>

@ -48,7 +48,7 @@ class SettingsDialogTest {
}
composeTestRule
.onNodeWithText(getString(R.string.loading))
.onNodeWithText(getString(R.string.feature_settings_loading))
.assertExists()
}
@ -71,17 +71,17 @@ class SettingsDialogTest {
}
// Check that all the possible settings are displayed.
composeTestRule.onNodeWithText(getString(R.string.brand_default)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.brand_android)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_brand_default)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_brand_android)).assertExists()
composeTestRule.onNodeWithText(
getString(R.string.dark_mode_config_system_default),
getString(R.string.feature_settings_dark_mode_config_system_default),
).assertExists()
composeTestRule.onNodeWithText(getString(R.string.dark_mode_config_light)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.dark_mode_config_dark)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dark_mode_config_light)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dark_mode_config_dark)).assertExists()
// Check that the correct settings are selected.
composeTestRule.onNodeWithText(getString(R.string.brand_android)).assertIsSelected()
composeTestRule.onNodeWithText(getString(R.string.dark_mode_config_dark)).assertIsSelected()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_brand_android)).assertIsSelected()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dark_mode_config_dark)).assertIsSelected()
}
@Test
@ -103,12 +103,12 @@ class SettingsDialogTest {
)
}
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_preference)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_yes)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_no)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_preference)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_yes)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_no)).assertExists()
// Check that the correct default dynamic color setting is selected.
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_no)).assertIsSelected()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_no)).assertIsSelected()
}
@Test
@ -129,10 +129,10 @@ class SettingsDialogTest {
)
}
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_preference))
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_preference))
.assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_yes)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_no)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_yes)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_no)).assertDoesNotExist()
}
@Test
@ -153,10 +153,10 @@ class SettingsDialogTest {
)
}
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_preference))
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_preference))
.assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_yes)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.dynamic_color_no)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_yes)).assertDoesNotExist()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_dynamic_color_no)).assertDoesNotExist()
}
@Test
@ -177,9 +177,9 @@ class SettingsDialogTest {
)
}
composeTestRule.onNodeWithText(getString(R.string.privacy_policy)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.licenses)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.brand_guidelines)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feedback)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_privacy_policy)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_licenses)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_brand_guidelines)).assertExists()
composeTestRule.onNodeWithText(getString(R.string.feature_settings_feedback)).assertExists()
}
}

@ -108,7 +108,7 @@ fun SettingsDialog(
onDismissRequest = { onDismiss() },
title = {
Text(
text = stringResource(string.settings_title),
text = stringResource(string.feature_settings_title),
style = MaterialTheme.typography.titleLarge,
)
},
@ -118,7 +118,7 @@ fun SettingsDialog(
when (settingsUiState) {
Loading -> {
Text(
text = stringResource(string.loading),
text = stringResource(string.feature_settings_loading),
modifier = Modifier.padding(vertical = 16.dp),
)
}
@ -140,7 +140,7 @@ fun SettingsDialog(
},
confirmButton = {
Text(
text = stringResource(string.dismiss_dialog_button_text),
text = stringResource(string.feature_settings_dismiss_dialog_button_text),
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier
@ -160,50 +160,50 @@ private fun ColumnScope.SettingsPanel(
onChangeDynamicColorPreference: (useDynamicColor: Boolean) -> Unit,
onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit,
) {
SettingsDialogSectionTitle(text = stringResource(string.theme))
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_theme))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.brand_default),
text = stringResource(string.feature_settings_brand_default),
selected = settings.brand == DEFAULT,
onClick = { onChangeThemeBrand(DEFAULT) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.brand_android),
text = stringResource(string.feature_settings_brand_android),
selected = settings.brand == ANDROID,
onClick = { onChangeThemeBrand(ANDROID) },
)
}
AnimatedVisibility(visible = settings.brand == DEFAULT && supportDynamicColor) {
Column {
SettingsDialogSectionTitle(text = stringResource(string.dynamic_color_preference))
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_dynamic_color_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_yes),
text = stringResource(string.feature_settings_dynamic_color_yes),
selected = settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(true) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_no),
text = stringResource(string.feature_settings_dynamic_color_no),
selected = !settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(false) },
)
}
}
}
SettingsDialogSectionTitle(text = stringResource(string.dark_mode_preference))
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_dark_mode_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.dark_mode_config_system_default),
text = stringResource(string.feature_settings_dark_mode_config_system_default),
selected = settings.darkThemeConfig == FOLLOW_SYSTEM,
onClick = { onChangeDarkThemeConfig(FOLLOW_SYSTEM) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.dark_mode_config_light),
text = stringResource(string.feature_settings_dark_mode_config_light),
selected = settings.darkThemeConfig == LIGHT,
onClick = { onChangeDarkThemeConfig(LIGHT) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.dark_mode_config_dark),
text = stringResource(string.feature_settings_dark_mode_config_dark),
selected = settings.darkThemeConfig == DARK,
onClick = { onChangeDarkThemeConfig(DARK) },
)
@ -259,7 +259,7 @@ private fun LinksPanel() {
NiaTextButton(
onClick = { uriHandler.openUri(PRIVACY_POLICY_URL) },
) {
Text(text = stringResource(string.privacy_policy))
Text(text = stringResource(string.feature_settings_privacy_policy))
}
val context = LocalContext.current
NiaTextButton(
@ -267,17 +267,17 @@ private fun LinksPanel() {
context.startActivity(Intent(context, OssLicensesMenuActivity::class.java))
},
) {
Text(text = stringResource(string.licenses))
Text(text = stringResource(string.feature_settings_licenses))
}
NiaTextButton(
onClick = { uriHandler.openUri(BRAND_GUIDELINES_URL) },
) {
Text(text = stringResource(string.brand_guidelines))
Text(text = stringResource(string.feature_settings_brand_guidelines))
}
NiaTextButton(
onClick = { uriHandler.openUri(FEEDBACK_URL) },
) {
Text(text = stringResource(string.feedback))
Text(text = stringResource(string.feature_settings_feedback))
}
}
}

@ -15,23 +15,23 @@
limitations under the License.
-->
<resources>
<string name="top_app_bar_action_icon_description">Settings</string>
<string name="top_app_bar_navigation_icon_description">Search</string>
<string name="settings_title">Settings</string>
<string name="loading">Loading…</string>
<string name="privacy_policy">Privacy policy</string>
<string name="licenses">Licenses</string>
<string name="brand_guidelines">Brand Guidelines</string>
<string name="feedback">Feedback</string>
<string name="theme">Theme</string>
<string name="brand_default">Default</string>
<string name="brand_android">Android</string>
<string name="dark_mode_preference">Dark mode preference</string>
<string name="dark_mode_config_system_default">System default</string>
<string name="dark_mode_config_light">Light</string>
<string name="dark_mode_config_dark">Dark</string>
<string name="dynamic_color_preference">Use Dynamic Color</string>
<string name="dynamic_color_yes">Yes</string>
<string name="dynamic_color_no">No</string>
<string name="dismiss_dialog_button_text">OK</string>
<string name="feature_settings_top_app_bar_action_icon_description">Settings</string>
<string name="feature_settings_top_app_bar_navigation_icon_description">Search</string>
<string name="feature_settings_title">Settings</string>
<string name="feature_settings_loading">Loading…</string>
<string name="feature_settings_privacy_policy">Privacy policy</string>
<string name="feature_settings_licenses">Licenses</string>
<string name="feature_settings_brand_guidelines">Brand Guidelines</string>
<string name="feature_settings_feedback">Feedback</string>
<string name="feature_settings_theme">Theme</string>
<string name="feature_settings_brand_default">Default</string>
<string name="feature_settings_brand_android">Android</string>
<string name="feature_settings_dark_mode_preference">Dark mode preference</string>
<string name="feature_settings_dark_mode_config_system_default">System default</string>
<string name="feature_settings_dark_mode_config_light">Light</string>
<string name="feature_settings_dark_mode_config_dark">Dark</string>
<string name="feature_settings_dynamic_color_preference">Use Dynamic Color</string>
<string name="feature_settings_dynamic_color_yes">Yes</string>
<string name="feature_settings_dynamic_color_no">No</string>
<string name="feature_settings_dismiss_dialog_button_text">OK</string>
</resources>

@ -45,7 +45,7 @@ class TopicScreenTest {
@Before
fun setup() {
composeTestRule.activity.apply {
topicLoading = getString(R.string.topic_loading)
topicLoading = getString(R.string.feature_topic_loading)
}
}

@ -119,7 +119,7 @@ internal fun TopicScreen(
TopicUiState.Loading -> item {
NiaLoadingWheel(
modifier = modifier,
contentDesc = stringResource(id = string.topic_loading),
contentDesc = stringResource(id = string.feature_topic_loading),
)
}
@ -284,7 +284,7 @@ private fun TopicToolbar(
Icon(
imageVector = NiaIcons.ArrowBack,
contentDescription = stringResource(
id = com.google.samples.apps.nowinandroid.core.ui.R.string.back,
id = com.google.samples.apps.nowinandroid.core.ui.R.string.core_ui_back,
),
)
}

@ -15,5 +15,5 @@
limitations under the License.
-->
<resources>
<string name="topic_loading">Loading topic</string>
<string name="feature_topic_loading">Loading topic</string>
</resources>

@ -54,10 +54,10 @@ private fun Context.syncWorkNotification(): Notification {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
SYNC_NOTIFICATION_CHANNEL_ID,
getString(R.string.sync_notification_channel_name),
getString(R.string.sync_work_notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT,
).apply {
description = getString(R.string.sync_notification_channel_description)
description = getString(R.string.sync_work_notification_channel_description)
}
// Register the channel with the system
val notificationManager: NotificationManager? =
@ -71,9 +71,9 @@ private fun Context.syncWorkNotification(): Notification {
SYNC_NOTIFICATION_CHANNEL_ID,
)
.setSmallIcon(
com.google.samples.apps.nowinandroid.core.common.R.drawable.ic_nia_notification,
com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification,
)
.setContentTitle(getString(R.string.sync_notification_title))
.setContentTitle(getString(R.string.sync_work_notification_title))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
}

@ -15,8 +15,8 @@
limitations under the License.
-->
<resources>
<string name="sync_notification_title">Now in Android</string>
<string name="sync_notification_channel_name">Sync</string>
<string name="sync_notification_channel_description">Background tasks for Now in Android</string>
<string name="sync_work_notification_title">Now in Android</string>
<string name="sync_work_notification_channel_name">Sync</string>
<string name="sync_work_notification_channel_description">Background tasks for Now in Android</string>
</resources>

Loading…
Cancel
Save