Merge branch 'android:main' into loading-progress-for-image

pull/850/head
Qamar A. Safadi 1 year ago committed by GitHub
commit 9f3103c212
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -106,7 +106,6 @@ dependencies {
debugImplementation(libs.androidx.compose.ui.testManifest) debugImplementation(libs.androidx.compose.ui.testManifest)
debugImplementation(project(":ui-test-hilt-manifest")) debugImplementation(project(":ui-test-hilt-manifest"))
implementation(libs.accompanist.systemuicontroller)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(libs.androidx.appcompat) implementation(libs.androidx.appcompat)
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)

@ -27,19 +27,27 @@ import androidx.compose.ui.test.junit4.AndroidComposeTestRule
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.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
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.compose.ui.test.performScrollToNode
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.R
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.model.data.Topic
import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule
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
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import javax.inject.Inject
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
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 FeatureForyouR import com.google.samples.apps.nowinandroid.feature.foryou.R as FeatureForyouR
@ -78,6 +86,9 @@ class NavigationTest {
@get:Rule(order = 3) @get:Rule(order = 3)
val composeTestRule = createAndroidComposeRule<MainActivity>() val composeTestRule = createAndroidComposeRule<MainActivity>()
@Inject
lateinit var topicsRepository: TopicsRepository
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) = private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) } ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
@ -92,6 +103,9 @@ class NavigationTest {
private val brand by composeTestRule.stringResource(SettingsR.string.brand_android) private val brand by composeTestRule.stringResource(SettingsR.string.brand_android)
private val ok by composeTestRule.stringResource(SettingsR.string.dismiss_dialog_button_text) private val ok by composeTestRule.stringResource(SettingsR.string.dismiss_dialog_button_text)
@Before
fun setup() = hiltRule.inject()
@Test @Test
fun firstScreen_isForYou() { fun firstScreen_isForYou() {
composeTestRule.apply { composeTestRule.apply {
@ -251,11 +265,14 @@ class NavigationTest {
} }
@Test @Test
fun navigationBar_multipleBackStackInterests() { fun navigationBar_multipleBackStackInterests() = runTest {
composeTestRule.apply { composeTestRule.apply {
onNodeWithText(interests).performClick() onNodeWithText(interests).performClick()
// TODO: Grab string from fake data
onNodeWithText("Android Studio & Tools").performClick() // Select the last topic
val topic = topicsRepository.getTopics().first().sortedBy(Topic::name).last().name
onNodeWithTag("interests:topics").performScrollToNode(hasText(topic))
onNodeWithText(topic).performClick()
// Switch tab // Switch tab
onNodeWithText(forYou).performClick() onNodeWithText(forYou).performClick()
@ -264,7 +281,7 @@ class NavigationTest {
onNodeWithText(interests).performClick() onNodeWithText(interests).performClick()
// Verify we're not in the list of interests // Verify we're not in the list of interests
onNodeWithText("Android Auto").assertDoesNotExist() // TODO: Grab string from fake data onNodeWithTag("interests:topics").assertDoesNotExist()
} }
} }
} }

@ -19,7 +19,9 @@ package com.google.samples.apps.nowinandroid
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
@ -31,13 +33,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.metrics.performance.JankStats import androidx.metrics.performance.JankStats
import androidx.profileinstaller.ProfileVerifier import androidx.profileinstaller.ProfileVerifier
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.samples.apps.nowinandroid.MainActivityUiState.Loading import com.google.samples.apps.nowinandroid.MainActivityUiState.Loading
import com.google.samples.apps.nowinandroid.MainActivityUiState.Success import com.google.samples.apps.nowinandroid.MainActivityUiState.Success
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
@ -108,16 +108,28 @@ class MainActivity : ComponentActivity() {
} }
// Turn off the decor fitting system windows, which allows us to handle insets, // Turn off the decor fitting system windows, which allows us to handle insets,
// including IME animations // including IME animations, and go edge-to-edge
WindowCompat.setDecorFitsSystemWindows(window, false) // This also sets up the initial system bar style based on the platform theme
enableEdgeToEdge()
setContent { setContent {
val systemUiController = rememberSystemUiController()
val darkTheme = shouldUseDarkTheme(uiState) val darkTheme = shouldUseDarkTheme(uiState)
// Update the dark content of the system bars to match the theme // Update the edge to edge configuration to match the theme
DisposableEffect(systemUiController, darkTheme) { // This is the same parameters as the default enableEdgeToEdge call, but we manually
systemUiController.systemBarsDarkContentEnabled = !darkTheme // resolve whether or not to show dark theme using uiState, since it can be different
// than the configuration's dark theme value based on the user preference.
DisposableEffect(darkTheme) {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.auto(
android.graphics.Color.TRANSPARENT,
android.graphics.Color.TRANSPARENT,
) { darkTheme },
navigationBarStyle = SystemBarStyle.auto(
lightScrim,
darkScrim,
) { darkTheme },
)
onDispose {} onDispose {}
} }
@ -224,3 +236,15 @@ private fun shouldUseDarkTheme(
DarkThemeConfig.DARK -> true DarkThemeConfig.DARK -> true
} }
} }
/**
* The default light scrim, as defined by androidx and the platform:
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=35-38;drc=27e7d52e8604a080133e8b842db10c89b4482598
*/
private val lightScrim = android.graphics.Color.argb(0xe6, 0xFF, 0xFF, 0xFF)
/**
* The default dark scrim, as defined by androidx and the platform:
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:activity/activity/src/main/java/androidx/activity/EdgeToEdge.kt;l=40-44;drc=27e7d52e8604a080133e8b842db10c89b4482598
*/
private val darkScrim = android.graphics.Color.argb(0x80, 0x1b, 0x1b, 0x1b)

@ -16,10 +16,7 @@
--> -->
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<style name="NightAdjusted.Theme.Nia" parent="android:Theme.Material.NoActionBar"> <style name="NightAdjusted.Theme.Nia" parent="android:Theme.Material.NoActionBar" />
<item name="android:windowLightStatusBar" tools:targetApi="23">false</item>
<item name="android:windowLightNavigationBar" tools:targetApi="27">false</item>
</style>
<style name="NightAdjusted.Theme.Splash" parent="Theme.SplashScreen"> <style name="NightAdjusted.Theme.Splash" parent="Theme.SplashScreen">
<item name="android:windowLightStatusBar" tools:targetApi="23">false</item> <item name="android:windowLightStatusBar" tools:targetApi="23">false</item>

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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>
<style name="PlatformAdjusted.Theme.Nia" parent="NightAdjusted.Theme.Nia">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 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>
<style name="PlatformAdjusted.Theme.Nia" parent="NightAdjusted.Theme.Nia">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
</resources>

@ -18,19 +18,10 @@
<!-- Allows us to override night specific attributes in the <!-- Allows us to override night specific attributes in the
values-night folder. --> values-night folder. -->
<style name="NightAdjusted.Theme.Nia" parent="android:Theme.Material.Light.NoActionBar"> <style name="NightAdjusted.Theme.Nia" parent="android:Theme.Material.Light.NoActionBar" />
<item name="android:windowLightStatusBar" tools:targetApi="23">true</item>
<item name="android:windowLightNavigationBar" tools:targetApi="27">true</item>
</style>
<!-- Allows us to override platform level specific attributes in their
respective values-vXX folder. -->
<style name="PlatformAdjusted.Theme.Nia" parent="NightAdjusted.Theme.Nia">
<item name="android:statusBarColor">@color/black30</item>
</style>
<!-- The final theme we use --> <!-- The final theme we use -->
<style name="Theme.Nia" parent="PlatformAdjusted.Theme.Nia" /> <style name="Theme.Nia" parent="NightAdjusted.Theme.Nia" />
<style name="NightAdjusted.Theme.Splash" parent="Theme.SplashScreen"> <style name="NightAdjusted.Theme.Splash" parent="Theme.SplashScreen">
<item name="android:windowLightStatusBar" tools:targetApi="23">true</item> <item name="android:windowLightStatusBar" tools:targetApi="23">true</item>

@ -37,7 +37,7 @@ val followableTopicTestData: List<FollowableTopic> = listOf(
id = "3", id = "3",
name = "UI", name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets", shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on tocpis such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!", longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on topics such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!",
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594", imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "", url = "",
), ),

@ -32,7 +32,7 @@ val topicsTestData: List<Topic> = listOf(
id = "3", id = "3",
name = "UI", name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets", shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on tocpis such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!", longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on topics such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!",
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594", imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "", url = "",
), ),

@ -45,7 +45,7 @@ class FollowableTopicPreviewParameterProvider : PreviewParameterProvider<List<Fo
id = "3", id = "3",
name = "UI", name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets", shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on tocpis such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!", longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on topics such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!",
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594", imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "", url = "",
), ),

@ -66,7 +66,7 @@ object PreviewParameterData {
id = "3", id = "3",
name = "UI", name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets", shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on tocpis such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!", longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on topics such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!",
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594", imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "", url = "",
), ),

@ -18,7 +18,7 @@
<string name="search">Search</string> <string name="search">Search</string>
<string name="clear_search_text_content_desc">Clear search text</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_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="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="try_another_search">Try another search or explorer </string>
<string name="interests">Interests</string> <string name="interests">Interests</string>
<string name="to_browse_topics"> to browse topics</string> <string name="to_browse_topics"> to browse topics</string>

@ -2,7 +2,7 @@
accompanist = "0.28.0" accompanist = "0.28.0"
androidDesugarJdkLibs = "2.0.3" androidDesugarJdkLibs = "2.0.3"
androidGradlePlugin = "8.1.0" androidGradlePlugin = "8.1.0"
androidxActivity = "1.7.0" androidxActivity = "1.8.0-alpha06"
androidxAppCompat = "1.5.1" androidxAppCompat = "1.5.1"
androidxBrowser = "1.4.0" androidxBrowser = "1.4.0"
androidxComposeBom = "2023.06.01" androidxComposeBom = "2023.06.01"
@ -55,7 +55,6 @@ turbine = "0.12.1"
[libraries] [libraries]
accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" }
accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" }
accompanist-testharness = { group = "com.google.accompanist", name = "accompanist-testharness", version.ref = "accompanist" } accompanist-testharness = { group = "com.google.accompanist", name = "accompanist-testharness", version.ref = "accompanist" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }

Loading…
Cancel
Save