Add settings module, refactor top bar

pull/330/head
Don Turner 2 years ago
parent b7500ea09b
commit 8c30ab9f80

@ -82,6 +82,7 @@ dependencies {
implementation(project(":feature:foryou")) implementation(project(":feature:foryou"))
implementation(project(":feature:bookmarks")) implementation(project(":feature:bookmarks"))
implementation(project(":feature:topic")) implementation(project(":feature:topic"))
implementation(project(":feature:settings"))
implementation(project(":core:common")) implementation(project(":core:common"))
implementation(project(":core:ui")) implementation(project(":core:ui"))

@ -16,17 +16,22 @@
package com.google.samples.apps.nowinandroid.ui package com.google.samples.apps.nowinandroid.ui
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.assertIsOn
import androidx.compose.ui.test.assertIsSelected import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
import androidx.test.espresso.NoActivityResumedException import androidx.test.espresso.NoActivityResumedException
import com.google.samples.apps.nowinandroid.MainActivity import com.google.samples.apps.nowinandroid.MainActivity
import com.google.samples.apps.nowinandroid.R
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.foryou.R as FeatureForyouR
import com.google.samples.apps.nowinandroid.feature.interests.R as FeatureInterestsR import com.google.samples.apps.nowinandroid.feature.interests.R as FeatureInterestsR
import com.google.samples.apps.nowinandroid.feature.settings.R as SettingsR
import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.BindValue
import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltAndroidTest
@ -67,6 +72,9 @@ class NavigationTest {
private lateinit var forYou: String private lateinit var forYou: String
private lateinit var interests: String private lateinit var interests: String
private lateinit var sampleTopic: String private lateinit var sampleTopic: String
private lateinit var appName: String
private lateinit var saved: String
private lateinit var settings: String
@Before @Before
fun setup() { fun setup() {
@ -77,6 +85,9 @@ class NavigationTest {
forYou = getString(FeatureForyouR.string.for_you) forYou = getString(FeatureForyouR.string.for_you)
interests = getString(FeatureInterestsR.string.interests) interests = getString(FeatureInterestsR.string.interests)
sampleTopic = "Headlines" sampleTopic = "Headlines"
appName = getString(R.string.app_name)
saved = getString(BookmarksR.string.saved)
settings = getString(SettingsR.string.top_app_bar_action_icon_description)
} }
} }
@ -146,6 +157,38 @@ class NavigationTest {
} }
} }
@Test
fun topLevelDestinations_showTopBarWithTitle() {
composeTestRule.apply {
// Verify that the top bar contains the app name on the first screen.
onNodeWithText(appName).assertExists()
// Go to the bookmarks tab, verify that the top bar contains the app name.
onNodeWithText(saved).performClick()
onNodeWithText(appName).assertExists()
// Go to the interests tab, verify that the top bar contains "Interests". This means
// we'll have 2 elements with the text "Interests" on screen. One in the top bar, and
// one in the bottom navigation.
onNodeWithText(interests).performClick()
onAllNodesWithText(interests).assertCountEquals(2)
}
}
@Test
fun topLevelDestinations_showSettingsIcon() {
composeTestRule.apply {
onNodeWithContentDescription(settings).assertExists()
onNodeWithText(saved).performClick()
onNodeWithContentDescription(settings).assertExists()
onNodeWithText(interests).performClick()
onNodeWithContentDescription(settings).assertExists()
}
}
/* /*
* There should always be at most one instance of a top-level destination at the same time. * There should always be at most one instance of a top-level destination at the same time.
*/ */

@ -87,6 +87,19 @@ class NiaAppStateTest {
assertTrue(state.topLevelDestinations[2].name.contains("interests", true)) assertTrue(state.topLevelDestinations[2].name.contains("interests", true))
} }
@Test
fun niaAppState_showTopBarForTopLevelDestinations() {
composeTestRule.setContent {
val navController = rememberTestNavController()
state = rememberNiaAppState(
windowSizeClass = getCompactWindowClass(),
navController = navController
)
// Do nothing - we should already be
}
}
@Test @Test
fun niaAppState_showBottomBar_compact() { fun niaAppState_showBottomBar_compact() {
composeTestRule.setContent { composeTestRule.setContent {

@ -23,6 +23,7 @@ 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.bookmarks.R as bookmarksR
import com.google.samples.apps.nowinandroid.feature.foryou.R as forYouR 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.interests.R as interestsR
import com.google.samples.apps.nowinandroid.R
/** /**
* Type for the top level destinations in the application. Each of these destinations * Type for the top level destinations in the application. Each of these destinations
@ -32,21 +33,25 @@ import com.google.samples.apps.nowinandroid.feature.interests.R as interestsR
enum class TopLevelDestination( enum class TopLevelDestination(
val selectedIcon: Icon, val selectedIcon: Icon,
val unselectedIcon: Icon, val unselectedIcon: Icon,
val iconTextId: Int val iconTextId: Int,
val titleTextId: Int
) { ) {
FOR_YOU( FOR_YOU(
selectedIcon = DrawableResourceIcon(NiaIcons.Upcoming), selectedIcon = DrawableResourceIcon(NiaIcons.Upcoming),
unselectedIcon = DrawableResourceIcon(NiaIcons.UpcomingBorder), unselectedIcon = DrawableResourceIcon(NiaIcons.UpcomingBorder),
iconTextId = forYouR.string.for_you iconTextId = forYouR.string.for_you,
titleTextId = R.string.app_name
), ),
BOOKMARKS( BOOKMARKS(
selectedIcon = DrawableResourceIcon(NiaIcons.Bookmarks), selectedIcon = DrawableResourceIcon(NiaIcons.Bookmarks),
unselectedIcon = DrawableResourceIcon(NiaIcons.BookmarksBorder), unselectedIcon = DrawableResourceIcon(NiaIcons.BookmarksBorder),
iconTextId = bookmarksR.string.saved iconTextId = bookmarksR.string.saved,
titleTextId = bookmarksR.string.saved
), ),
INTERESTS( INTERESTS(
selectedIcon = ImageVectorIcon(NiaIcons.Grid3x3), selectedIcon = ImageVectorIcon(NiaIcons.Grid3x3),
unselectedIcon = ImageVectorIcon(NiaIcons.Grid3x3), unselectedIcon = ImageVectorIcon(NiaIcons.Grid3x3),
iconTextId = interestsR.string.interests iconTextId = interestsR.string.interests,
titleTextId = interestsR.string.interests
) )
} }

@ -32,6 +32,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
@ -49,8 +50,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavig
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationRail import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationRail
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationRailItem import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationRailItem
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.Icon.DrawableResourceIcon 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.icon.Icon.ImageVectorIcon
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR
import com.google.samples.apps.nowinandroid.navigation.NiaNavHost import com.google.samples.apps.nowinandroid.navigation.NiaNavHost
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
@ -78,6 +82,22 @@ fun NiaApp(
containerColor = Color.Transparent, containerColor = Color.Transparent,
contentColor = MaterialTheme.colorScheme.onBackground, contentColor = MaterialTheme.colorScheme.onBackground,
contentWindowInsets = WindowInsets(0, 0, 0, 0), contentWindowInsets = WindowInsets(0, 0, 0, 0),
topBar = {
val destination = appState.topLevelDestinations[appState.currentDestination?.route]
if (appState.shouldShowTopBar && destination != null) {
NiaTopAppBar(
titleRes = destination.titleTextId,
actionIcon = NiaIcons.Settings,
actionIconContentDescription = stringResource(
id = settingsR.string.top_app_bar_action_icon_description
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent
),
onActionClick = { /*openAccountDialog = true*/ }
)
}
},
bottomBar = { bottomBar = {
if (appState.shouldShowBottomBar) { if (appState.shouldShowBottomBar) {
NiaBottomBar( NiaBottomBar(

@ -59,6 +59,9 @@ class NiaAppState(
@Composable get() = navController @Composable get() = navController
.currentBackStackEntryAsState().value?.destination .currentBackStackEntryAsState().value?.destination
val shouldShowTopBar: Boolean
@Composable get() = (currentDestination?.route in topLevelDestinations)
val shouldShowBottomBar: Boolean val shouldShowBottomBar: Boolean
get() = windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact || get() = windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact ||
windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact
@ -67,7 +70,8 @@ class NiaAppState(
get() = !shouldShowBottomBar get() = !shouldShowBottomBar
/** /**
* Top level destinations to be used in the BottomBar and NavRail * Map of top level destinations to be used in the TopBar, BottomBar and NavRail. The key is the
* route.
*/ */
val topLevelDestinations: List<TopLevelDestination> = TopLevelDestination.values().asList() val topLevelDestinations: List<TopLevelDestination> = TopLevelDestination.values().asList()

@ -31,4 +31,5 @@ plugins {
alias(libs.plugins.kotlin.serialization) apply false alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.hilt) apply false alias(libs.plugins.hilt) apply false
alias(libs.plugins.secrets) apply false alias(libs.plugins.secrets) apply false
id("org.jetbrains.kotlin.android") version "1.7.10" apply false
} }

@ -40,6 +40,7 @@ message UserPreferences {
map<string, bool> followed_topic_ids = 13; map<string, bool> followed_topic_ids = 13;
map<string, bool> followed_author_ids = 14; map<string, bool> followed_author_ids = 14;
map<string, bool> bookmarked_news_resource_ids = 15; map<string, bool> bookmarked_news_resource_ids = 15;
ThemeBrandProto theme_brand = 12;
DarkThemeConfigProto dark_theme_config = 13; ThemeBrandProto theme_brand = 16;
DarkThemeConfigProto dark_theme_config = 17;
} }

@ -32,7 +32,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.google.samples.apps.nowinandroid.core.designsystem.R
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -97,7 +99,7 @@ fun NiaTopAppBar(
} }
}, },
colors = colors, colors = colors,
modifier = modifier modifier = modifier,
) )
} }

@ -32,6 +32,7 @@ import androidx.compose.material.icons.rounded.Grid3x3
import androidx.compose.material.icons.rounded.Person import androidx.compose.material.icons.rounded.Person
import androidx.compose.material.icons.rounded.PlayArrow import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Search
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.ShortText import androidx.compose.material.icons.rounded.ShortText
import androidx.compose.material.icons.rounded.Tag import androidx.compose.material.icons.rounded.Tag
import androidx.compose.material.icons.rounded.ViewDay import androidx.compose.material.icons.rounded.ViewDay
@ -64,6 +65,7 @@ object NiaIcons {
val Person = Icons.Rounded.Person val Person = Icons.Rounded.Person
val PlayArrow = Icons.Rounded.PlayArrow val PlayArrow = Icons.Rounded.PlayArrow
val Search = Icons.Rounded.Search val Search = Icons.Rounded.Search
val Settings = Icons.Rounded.Settings
val ShortText = Icons.Rounded.ShortText val ShortText = Icons.Rounded.ShortText
val Tag = Icons.Rounded.Tag val Tag = Icons.Rounded.Tag
val Upcoming = R.drawable.ic_upcoming val Upcoming = R.drawable.ic_upcoming

@ -18,4 +18,5 @@
<string name="follow">Follow</string> <string name="follow">Follow</string>
<string name="unfollow">Unfollow</string> <string name="unfollow">Unfollow</string>
<string name="browse_topic">Browse topic</string> <string name="browse_topic">Browse topic</string>
<string name="screen_title">Screen title</string>
</resources> </resources>

@ -34,7 +34,6 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -46,8 +45,6 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank
import com.google.samples.apps.nowinandroid.core.ui.newsFeed import com.google.samples.apps.nowinandroid.core.ui.newsFeed
@ -74,18 +71,6 @@ fun BookmarksScreen(
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Scaffold( Scaffold(
topBar = {
NiaTopAppBar(
titleRes = R.string.top_app_bar_title_saved,
actionIcon = NiaIcons.AccountCircle,
actionIconContentDescription = stringResource(
id = R.string.top_app_bar_action_menu
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent
)
)
},
containerColor = Color.Transparent, containerColor = Color.Transparent,
contentWindowInsets = WindowInsets(0, 0, 0, 0) contentWindowInsets = WindowInsets(0, 0, 0, 0)
) { innerPadding -> ) { innerPadding ->

@ -17,7 +17,7 @@
<resources> <resources>
<string name="saved">Saved</string> <string name="saved">Saved</string>
<string name="saved_loading">Loading saved…</string> <string name="saved_loading">Loading saved…</string>
<string name="top_app_bar_title_saved">Saved</string> <string name="top_app_bar_title">Saved</string>
<string name="top_app_bar_action_search">Search</string> <string name="top_app_bar_action_search">Search</string>
<string name="top_app_bar_action_menu">Menu</string> <string name="top_app_bar_action_menu">Menu</string>
</resources> </resources>

@ -63,7 +63,6 @@ import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -93,7 +92,6 @@ import coil.compose.AsyncImage
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilledButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilledButton
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverlayLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverlayLoadingWheel
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaToggleButton
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor
@ -173,19 +171,6 @@ internal fun ForYouScreen(
Scaffold( Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) }, snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = {
NiaTopAppBar(
titleRes = R.string.top_app_bar_title,
actionIcon = NiaIcons.AccountCircle,
actionIconContentDescription = stringResource(
id = R.string.for_you_top_app_bar_action_my_account
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent
),
onActionClick = { openAccountDialog = true }
)
},
containerColor = Color.Transparent, containerColor = Color.Transparent,
contentWindowInsets = WindowInsets(0, 0, 0, 0) contentWindowInsets = WindowInsets(0, 0, 0, 0)
) { innerPadding -> ) { innerPadding ->

@ -22,7 +22,6 @@
<string name="onboarding_guidance_title">What are you interested in?</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="onboarding_guidance_subtitle">Updates from topics you follow will appear here. Follow some things to get started.</string>
<string name="top_app_bar_title">Now in Android</string> <string name="top_app_bar_title">Now in Android</string>
<string name="for_you_top_app_bar_action_my_account">My account</string>
<string name="for_you_top_app_bar_action_search">Search</string> <string name="for_you_top_app_bar_action_search">Search</string>
<string name="for_you_not_connected">⚠️ You arent connected to the internet</string> <string name="for_you_not_connected">⚠️ You arent connected to the internet</string>

@ -19,12 +19,10 @@ package com.google.samples.apps.nowinandroid.feature.interests
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
@ -33,8 +31,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackg
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
@ -90,16 +86,6 @@ internal fun InterestsScreen(
modifier = modifier, modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
NiaTopAppBar(
titleRes = R.string.interests,
actionIcon = NiaIcons.MoreVert,
actionIconContentDescription = stringResource(
id = R.string.interests_top_app_bar_action_menu
),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = Color.Transparent
)
)
when (uiState) { when (uiState) {
InterestsUiState.Loading -> InterestsUiState.Loading ->
NiaLoadingWheel( NiaLoadingWheel(

@ -15,6 +15,7 @@
limitations under the License. limitations under the License.
--> -->
<resources> <resources>
<!-- TODO: Remove the redundant "interests" prefix -->
<string name="interests">Interests</string> <string name="interests">Interests</string>
<string name="interests_topics">Topics</string> <string name="interests_topics">Topics</string>
<string name="interests_people">People</string> <string name="interests_people">People</string>
@ -22,6 +23,7 @@
<string name="interests_empty_header">"No available data"</string> <string name="interests_empty_header">"No available data"</string>
<string name="interests_card_follow_button_content_desc">Follow interest button</string> <string name="interests_card_follow_button_content_desc">Follow interest button</string>
<string name="interests_card_unfollow_button_content_desc">Unfollow interest button</string> <string name="interests_card_unfollow_button_content_desc">Unfollow interest button</string>
<string name="interests_top_app_bar_title">Interests</string>
<string name="interests_top_app_bar_action_menu">Menu</string> <string name="interests_top_app_bar_action_menu">Menu</string>
<string name="interests_top_app_bar_action_seearch">Search</string> <string name="interests_top_app_bar_action_seearch">Search</string>
</resources> </resources>

@ -0,0 +1 @@
/build

@ -0,0 +1,24 @@
/*
* 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.
*/
plugins {
id("nowinandroid.android.feature")
id("nowinandroid.android.library.compose")
id("nowinandroid.android.library.jacoco")
}
android {
namespace = "com.google.samples.apps.nowinandroid.feature.settings"
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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
http://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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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
http://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.
-->
<resources>
<string name="top_app_bar_action_icon_description">Settings</string>
</resources>

@ -51,6 +51,7 @@ include(":feature:foryou")
include(":feature:interests") include(":feature:interests")
include(":feature:bookmarks") include(":feature:bookmarks")
include(":feature:topic") include(":feature:topic")
include(":feature:settings")
include(":lint") include(":lint")
include(":sync:work") include(":sync:work")
include(":sync:sync-test") include(":sync:sync-test")

Loading…
Cancel
Save